Source
x
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2004-2005 Silicon Graphics, Inc.
* All Rights Reserved.
*/
/*
* Note that we only accept fileids which are long enough rather than allow
* the parent generation number to default to zero. XFS considers zero a
* valid generation number not an invalid/wildcard value.
*/
static int xfs_fileid_length(int fileid_type)
{
switch (fileid_type) {
case FILEID_INO32_GEN:
return 2;
case FILEID_INO32_GEN_PARENT:
return 4;
case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
return 3;
case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
return 6;
}
return FILEID_INVALID;
}
STATIC int
xfs_fs_encode_fh(
struct inode *inode,
__u32 *fh,
int *max_len,
struct inode *parent)
{
struct fid *fid = (struct fid *)fh;
struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh;
int fileid_type;
int len;
/* Directories don't need their parent encoded, they have ".." */
if (!parent)
fileid_type = FILEID_INO32_GEN;
else
fileid_type = FILEID_INO32_GEN_PARENT;
/*
* If the the filesystem may contain 64bit inode numbers, we need
* to use larger file handles that can represent them.
*
* While we only allocate inodes that do not fit into 32 bits any
* large enough filesystem may contain them, thus the slightly
* confusing looking conditional below.
*/
if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS) ||
(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_32BITINODES))
fileid_type |= XFS_FILEID_TYPE_64FLAG;
/*
* Only encode if there is enough space given. In practice
* this means we can't export a filesystem with 64bit inodes
* over NFSv2 with the subtree_check export option; the other
* seven combinations work. The real answer is "don't use v2".
*/
len = xfs_fileid_length(fileid_type);
if (*max_len < len) {
*max_len = len;
return FILEID_INVALID;
}
*max_len = len;
switch (fileid_type) {
case FILEID_INO32_GEN_PARENT:
fid->i32.parent_ino = XFS_I(parent)->i_ino;
fid->i32.parent_gen = parent->i_generation;
/*FALLTHRU*/
case FILEID_INO32_GEN:
fid->i32.ino = XFS_I(inode)->i_ino;