mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
vfs-6.7.fsid
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZUpEaAAKCRCRxhvAZXjc ounBAQCAoS66gnOZ+k4kOWwB2zZ1Ueh3dPFC7IcEZ+pwFS8hpAEAxUQxV0TSWf5l W/1oKRtAJyuSYvehHeMUSJmHVBiM8w4= =bNm0 -----END PGP SIGNATURE----- Merge tag 'vfs-6.7.fsid' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs fanotify fsid updates from Christian Brauner: "This work is part of the plan to enable fanotify to serve as a drop-in replacement for inotify. While inotify is availabe on all filesystems, fanotify currently isn't. In order to support fanotify on all filesystems two things are needed: (1) all filesystems need to support AT_HANDLE_FID (2) all filesystems need to report a non-zero f_fsid This contains (1) and allows filesystems to encode non-decodable file handlers for fanotify without implementing any exportfs operations by encoding a file id of type FILEID_INO64_GEN from i_ino and i_generation. Filesystems that want to opt out of encoding non-decodable file ids for fanotify that don't support NFS export can do so by providing an empty export_operations struct. This also partially addresses (2) by generating f_fsid for simple filesystems as well as freevxfs. Remaining filesystems will be dealt with by separate patches. Finally, this contains the patch from the current exportfs maintainers which moves exportfs under vfs with Chuck, Jeff, and Amir as maintainers and vfs.git as tree" * tag 'vfs-6.7.fsid' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: MAINTAINERS: create an entry for exportfs fs: fix build error with CONFIG_EXPORTFS=m or not defined freevxfs: derive f_fsid from bdev->bd_dev fs: report f_fsid from s_dev for "simple" filesystems exportfs: support encoding non-decodeable file handles by default exportfs: define FILEID_INO64_GEN* file handle types exportfs: make ->encode_fh() a mandatory method for NFS export exportfs: add helpers to check if filesystem can encode/decode file handles
This commit is contained in:
commit
13d88ac54d
@ -122,12 +122,9 @@ are exportable by setting the s_export_op field in the struct
|
||||
super_block. This field must point to a "struct export_operations"
|
||||
struct which has the following members:
|
||||
|
||||
encode_fh (optional)
|
||||
encode_fh (mandatory)
|
||||
Takes a dentry and creates a filehandle fragment which may later be used
|
||||
to find or create a dentry for the same object. The default
|
||||
implementation creates a filehandle fragment that encodes a 32bit inode
|
||||
and generation number for the inode encoded, and if necessary the
|
||||
same information for the parent.
|
||||
to find or create a dentry for the same object.
|
||||
|
||||
fh_to_dentry (mandatory)
|
||||
Given a filehandle fragment, this should find the implied object and
|
||||
|
@ -1052,3 +1052,12 @@ kill_anon_super(), or kill_block_super() helpers.
|
||||
|
||||
Lock ordering has been changed so that s_umount ranks above open_mutex again.
|
||||
All places where s_umount was taken under open_mutex have been fixed up.
|
||||
|
||||
---
|
||||
|
||||
**mandatory**
|
||||
|
||||
export_operations ->encode_fh() no longer has a default implementation to
|
||||
encode FILEID_INO32_GEN* file handles.
|
||||
Filesystems that used the default implementation may use the generic helper
|
||||
generic_encode_ino32_fh() explicitly.
|
||||
|
13
MAINTAINERS
13
MAINTAINERS
@ -8156,6 +8156,18 @@ F: include/linux/fs_types.h
|
||||
F: include/uapi/linux/fs.h
|
||||
F: include/uapi/linux/openat2.h
|
||||
|
||||
FILESYSTEMS [EXPORTFS]
|
||||
M: Chuck Lever <chuck.lever@oracle.com>
|
||||
M: Jeff Layton <jlayton@kernel.org>
|
||||
R: Amir Goldstein <amir73il@gmail.com>
|
||||
L: linux-fsdevel@vger.kernel.org
|
||||
L: linux-nfs@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/filesystems/nfs/exporting.rst
|
||||
F: fs/exportfs/
|
||||
F: fs/fhandle.c
|
||||
F: include/linux/exportfs.h
|
||||
|
||||
FILESYSTEMS [IOMAP]
|
||||
M: Christian Brauner <brauner@kernel.org>
|
||||
R: Darrick J. Wong <djwong@kernel.org>
|
||||
@ -11548,7 +11560,6 @@ S: Supported
|
||||
W: http://nfs.sourceforge.net/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
|
||||
F: Documentation/filesystems/nfs/
|
||||
F: fs/exportfs/
|
||||
F: fs/lockd/
|
||||
F: fs/nfs_common/
|
||||
F: fs/nfsd/
|
||||
|
@ -568,6 +568,7 @@ static struct dentry *affs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
}
|
||||
|
||||
const struct export_operations affs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = affs_fh_to_dentry,
|
||||
.fh_to_parent = affs_fh_to_parent,
|
||||
.get_parent = affs_get_parent,
|
||||
|
@ -96,6 +96,7 @@ static const struct address_space_operations befs_symlink_aops = {
|
||||
};
|
||||
|
||||
static const struct export_operations befs_export_operations = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = befs_fh_to_dentry,
|
||||
.fh_to_parent = befs_fh_to_parent,
|
||||
.get_parent = befs_get_parent,
|
||||
|
@ -46,6 +46,7 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
u64 storage_space, remaining_space, max_variable_size;
|
||||
u64 id = huge_encode_dev(dentry->d_sb->s_dev);
|
||||
efi_status_t status;
|
||||
|
||||
/* Some UEFI firmware does not implement QueryVariableInfo() */
|
||||
@ -69,6 +70,7 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
buf->f_blocks = storage_space;
|
||||
buf->f_bfree = remaining_space;
|
||||
buf->f_type = dentry->d_sb->s_magic;
|
||||
buf->f_fsid = u64_to_fsid(id);
|
||||
|
||||
/*
|
||||
* In f_bavail we declare the free space that the kernel will allow writing
|
||||
|
@ -123,6 +123,7 @@ static const struct super_operations efs_superblock_operations = {
|
||||
};
|
||||
|
||||
static const struct export_operations efs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = efs_fh_to_dentry,
|
||||
.fh_to_parent = efs_fh_to_parent,
|
||||
.get_parent = efs_get_parent,
|
||||
|
@ -567,6 +567,7 @@ static struct dentry *erofs_get_parent(struct dentry *child)
|
||||
}
|
||||
|
||||
static const struct export_operations erofs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = erofs_fh_to_dentry,
|
||||
.fh_to_parent = erofs_fh_to_parent,
|
||||
.get_parent = erofs_get_parent,
|
||||
|
@ -342,43 +342,30 @@ static int get_name(const struct path *path, char *name, struct dentry *child)
|
||||
return error;
|
||||
}
|
||||
|
||||
#define FILEID_INO64_GEN_LEN 3
|
||||
|
||||
/**
|
||||
* export_encode_fh - default export_operations->encode_fh function
|
||||
* exportfs_encode_ino64_fid - encode non-decodeable 64bit ino file id
|
||||
* @inode: the object to encode
|
||||
* @fid: where to store the file handle fragment
|
||||
* @max_len: maximum length to store there
|
||||
* @parent: parent directory inode, if wanted
|
||||
* @max_len: maximum length to store there (in 4 byte units)
|
||||
*
|
||||
* This default encode_fh function assumes that the 32 inode number
|
||||
* is suitable for locating an inode, and that the generation number
|
||||
* can be used to check that it is still valid. It places them in the
|
||||
* filehandle fragment where export_decode_fh expects to find them.
|
||||
* This generic function is used to encode a non-decodeable file id for
|
||||
* fanotify for filesystems that do not support NFS export.
|
||||
*/
|
||||
static int export_encode_fh(struct inode *inode, struct fid *fid,
|
||||
int *max_len, struct inode *parent)
|
||||
static int exportfs_encode_ino64_fid(struct inode *inode, struct fid *fid,
|
||||
int *max_len)
|
||||
{
|
||||
int len = *max_len;
|
||||
int type = FILEID_INO32_GEN;
|
||||
|
||||
if (parent && (len < 4)) {
|
||||
*max_len = 4;
|
||||
return FILEID_INVALID;
|
||||
} else if (len < 2) {
|
||||
*max_len = 2;
|
||||
if (*max_len < FILEID_INO64_GEN_LEN) {
|
||||
*max_len = FILEID_INO64_GEN_LEN;
|
||||
return FILEID_INVALID;
|
||||
}
|
||||
|
||||
len = 2;
|
||||
fid->i32.ino = inode->i_ino;
|
||||
fid->i32.gen = inode->i_generation;
|
||||
if (parent) {
|
||||
fid->i32.parent_ino = parent->i_ino;
|
||||
fid->i32.parent_gen = parent->i_generation;
|
||||
len = 4;
|
||||
type = FILEID_INO32_GEN_PARENT;
|
||||
}
|
||||
*max_len = len;
|
||||
return type;
|
||||
fid->i64.ino = inode->i_ino;
|
||||
fid->i64.gen = inode->i_generation;
|
||||
*max_len = FILEID_INO64_GEN_LEN;
|
||||
|
||||
return FILEID_INO64_GEN;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -396,17 +383,13 @@ int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
|
||||
{
|
||||
const struct export_operations *nop = inode->i_sb->s_export_op;
|
||||
|
||||
/*
|
||||
* If a decodeable file handle was requested, we need to make sure that
|
||||
* filesystem can decode file handles.
|
||||
*/
|
||||
if (nop && !(flags & EXPORT_FH_FID) && !nop->fh_to_dentry)
|
||||
if (!exportfs_can_encode_fh(nop, flags))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (nop && nop->encode_fh)
|
||||
return nop->encode_fh(inode, fid->raw, max_len, parent);
|
||||
if (!nop && (flags & EXPORT_FH_FID))
|
||||
return exportfs_encode_ino64_fid(inode, fid, max_len);
|
||||
|
||||
return export_encode_fh(inode, fid, max_len, parent);
|
||||
return nop->encode_fh(inode, fid->raw, max_len, parent);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(exportfs_encode_inode_fh);
|
||||
|
||||
@ -456,7 +439,7 @@ exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len,
|
||||
/*
|
||||
* Try to get any dentry for the given file handle from the filesystem.
|
||||
*/
|
||||
if (!nop || !nop->fh_to_dentry)
|
||||
if (!exportfs_can_decode_fh(nop))
|
||||
return ERR_PTR(-ESTALE);
|
||||
result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
|
||||
if (IS_ERR_OR_NULL(result))
|
||||
|
@ -397,6 +397,7 @@ static struct dentry *ext2_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
}
|
||||
|
||||
static const struct export_operations ext2_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = ext2_fh_to_dentry,
|
||||
.fh_to_parent = ext2_fh_to_parent,
|
||||
.get_parent = ext2_get_parent,
|
||||
|
@ -1654,6 +1654,7 @@ static const struct super_operations ext4_sops = {
|
||||
};
|
||||
|
||||
static const struct export_operations ext4_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = ext4_fh_to_dentry,
|
||||
.fh_to_parent = ext4_fh_to_parent,
|
||||
.get_parent = ext4_get_parent,
|
||||
|
@ -3330,6 +3330,7 @@ static struct dentry *f2fs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
}
|
||||
|
||||
static const struct export_operations f2fs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = f2fs_fh_to_dentry,
|
||||
.fh_to_parent = f2fs_fh_to_parent,
|
||||
.get_parent = f2fs_get_parent,
|
||||
|
@ -279,6 +279,7 @@ static struct dentry *fat_get_parent(struct dentry *child_dir)
|
||||
}
|
||||
|
||||
const struct export_operations fat_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = fat_fh_to_dentry,
|
||||
.fh_to_parent = fat_fh_to_parent,
|
||||
.get_parent = fat_get_parent,
|
||||
|
@ -26,12 +26,8 @@ static long do_sys_name_to_handle(const struct path *path,
|
||||
/*
|
||||
* We need to make sure whether the file system support decoding of
|
||||
* the file handle if decodeable file handle was requested.
|
||||
* Otherwise, even empty export_operations are sufficient to opt-in
|
||||
* to encoding FIDs.
|
||||
*/
|
||||
if (!path->dentry->d_sb->s_export_op ||
|
||||
(!(fh_flags & EXPORT_FH_FID) &&
|
||||
!path->dentry->d_sb->s_export_op->fh_to_dentry))
|
||||
if (!exportfs_can_encode_fh(path->dentry->d_sb->s_export_op, fh_flags))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle)))
|
||||
|
@ -76,6 +76,7 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
|
||||
{
|
||||
struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb);
|
||||
struct vxfs_sb *raw_sb = infp->vsi_raw;
|
||||
u64 id = huge_encode_dev(dentry->d_sb->s_bdev->bd_dev);
|
||||
|
||||
bufp->f_type = VXFS_SUPER_MAGIC;
|
||||
bufp->f_bsize = dentry->d_sb->s_blocksize;
|
||||
@ -84,6 +85,7 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
|
||||
bufp->f_bavail = 0;
|
||||
bufp->f_files = 0;
|
||||
bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree);
|
||||
bufp->f_fsid = u64_to_fsid(id);
|
||||
bufp->f_namelen = VXFS_NAMELEN;
|
||||
|
||||
return 0;
|
||||
|
@ -999,7 +999,7 @@ static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len,
|
||||
}
|
||||
|
||||
*max_len = len;
|
||||
return parent ? 0x82 : 0x81;
|
||||
return parent ? FILEID_INO64_GEN_PARENT : FILEID_INO64_GEN;
|
||||
}
|
||||
|
||||
static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
|
||||
@ -1007,7 +1007,8 @@ static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
|
||||
{
|
||||
struct fuse_inode_handle handle;
|
||||
|
||||
if ((fh_type != 0x81 && fh_type != 0x82) || fh_len < 3)
|
||||
if ((fh_type != FILEID_INO64_GEN &&
|
||||
fh_type != FILEID_INO64_GEN_PARENT) || fh_len < 3)
|
||||
return NULL;
|
||||
|
||||
handle.nodeid = (u64) fid->raw[0] << 32;
|
||||
@ -1021,7 +1022,7 @@ static struct dentry *fuse_fh_to_parent(struct super_block *sb,
|
||||
{
|
||||
struct fuse_inode_handle parent;
|
||||
|
||||
if (fh_type != 0x82 || fh_len < 6)
|
||||
if (fh_type != FILEID_INO64_GEN_PARENT || fh_len < 6)
|
||||
return NULL;
|
||||
|
||||
parent.nodeid = (u64) fid->raw[3] << 32;
|
||||
|
@ -1179,7 +1179,9 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
{
|
||||
struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
|
||||
struct hstate *h = hstate_inode(d_inode(dentry));
|
||||
u64 id = huge_encode_dev(dentry->d_sb->s_dev);
|
||||
|
||||
buf->f_fsid = u64_to_fsid(id);
|
||||
buf->f_type = HUGETLBFS_MAGIC;
|
||||
buf->f_bsize = huge_page_size(h);
|
||||
if (sbinfo) {
|
||||
|
@ -150,6 +150,7 @@ static struct dentry *jffs2_get_parent(struct dentry *child)
|
||||
}
|
||||
|
||||
static const struct export_operations jffs2_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.get_parent = jffs2_get_parent,
|
||||
.fh_to_dentry = jffs2_fh_to_dentry,
|
||||
.fh_to_parent = jffs2_fh_to_parent,
|
||||
|
@ -896,6 +896,7 @@ static const struct super_operations jfs_super_operations = {
|
||||
};
|
||||
|
||||
static const struct export_operations jfs_export_operations = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = jfs_fh_to_dentry,
|
||||
.fh_to_parent = jfs_fh_to_parent,
|
||||
.get_parent = jfs_get_parent,
|
||||
|
44
fs/libfs.c
44
fs/libfs.c
@ -41,6 +41,9 @@ EXPORT_SYMBOL(simple_getattr);
|
||||
|
||||
int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
{
|
||||
u64 id = huge_encode_dev(dentry->d_sb->s_dev);
|
||||
|
||||
buf->f_fsid = u64_to_fsid(id);
|
||||
buf->f_type = dentry->d_sb->s_magic;
|
||||
buf->f_bsize = PAGE_SIZE;
|
||||
buf->f_namelen = NAME_MAX;
|
||||
@ -1309,6 +1312,47 @@ ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simple_attr_write_signed);
|
||||
|
||||
/**
|
||||
* generic_encode_ino32_fh - generic export_operations->encode_fh function
|
||||
* @inode: the object to encode
|
||||
* @fh: where to store the file handle fragment
|
||||
* @max_len: maximum length to store there (in 4 byte units)
|
||||
* @parent: parent directory inode, if wanted
|
||||
*
|
||||
* This generic encode_fh function assumes that the 32 inode number
|
||||
* is suitable for locating an inode, and that the generation number
|
||||
* can be used to check that it is still valid. It places them in the
|
||||
* filehandle fragment where export_decode_fh expects to find them.
|
||||
*/
|
||||
int generic_encode_ino32_fh(struct inode *inode, __u32 *fh, int *max_len,
|
||||
struct inode *parent)
|
||||
{
|
||||
struct fid *fid = (void *)fh;
|
||||
int len = *max_len;
|
||||
int type = FILEID_INO32_GEN;
|
||||
|
||||
if (parent && (len < 4)) {
|
||||
*max_len = 4;
|
||||
return FILEID_INVALID;
|
||||
} else if (len < 2) {
|
||||
*max_len = 2;
|
||||
return FILEID_INVALID;
|
||||
}
|
||||
|
||||
len = 2;
|
||||
fid->i32.ino = inode->i_ino;
|
||||
fid->i32.gen = inode->i_generation;
|
||||
if (parent) {
|
||||
fid->i32.parent_ino = parent->i_ino;
|
||||
fid->i32.parent_gen = parent->i_generation;
|
||||
len = 4;
|
||||
type = FILEID_INO32_GEN_PARENT;
|
||||
}
|
||||
*max_len = len;
|
||||
return type;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(generic_encode_ino32_fh);
|
||||
|
||||
/**
|
||||
* generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
|
||||
* @sb: filesystem to do the file handle conversion on
|
||||
|
@ -426,8 +426,7 @@ static int check_export(struct path *path, int *flags, unsigned char *uuid)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!inode->i_sb->s_export_op ||
|
||||
!inode->i_sb->s_export_op->fh_to_dentry) {
|
||||
if (!exportfs_can_decode_fh(inode->i_sb->s_export_op)) {
|
||||
dprintk("exp_export: export of invalid fs type.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1595,7 +1595,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags)
|
||||
* file handles so user can use name_to_handle_at() to compare fids
|
||||
* reported with events to the file handle of watched objects.
|
||||
*/
|
||||
if (!nop)
|
||||
if (!exportfs_can_encode_fid(nop))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
@ -1603,7 +1603,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags)
|
||||
* supports decoding file handles, so user has a way to map back the
|
||||
* reported fids to filesystem objects.
|
||||
*/
|
||||
if (mark_type != FAN_MARK_INODE && !nop->fh_to_dentry)
|
||||
if (mark_type != FAN_MARK_INODE && !exportfs_can_decode_fh(nop))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 0;
|
||||
|
@ -384,6 +384,7 @@ static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
* and due to using iget() whereas NTFS needs ntfs_iget().
|
||||
*/
|
||||
const struct export_operations ntfs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.get_parent = ntfs_get_parent, /* Find the parent of a given
|
||||
directory. */
|
||||
.fh_to_dentry = ntfs_fh_to_dentry,
|
||||
|
@ -811,6 +811,7 @@ static int ntfs_nfs_commit_metadata(struct inode *inode)
|
||||
}
|
||||
|
||||
static const struct export_operations ntfs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = ntfs_fh_to_dentry,
|
||||
.fh_to_parent = ntfs_fh_to_parent,
|
||||
.get_parent = ntfs3_get_parent,
|
||||
|
@ -81,7 +81,7 @@ int ovl_can_decode_fh(struct super_block *sb)
|
||||
if (!capable(CAP_DAC_READ_SEARCH))
|
||||
return 0;
|
||||
|
||||
if (!sb->s_export_op || !sb->s_export_op->fh_to_dentry)
|
||||
if (!exportfs_can_decode_fh(sb->s_export_op))
|
||||
return 0;
|
||||
|
||||
return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN;
|
||||
|
@ -41,13 +41,12 @@ static struct dentry *cifs_get_parent(struct dentry *dentry)
|
||||
}
|
||||
|
||||
const struct export_operations cifs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.get_parent = cifs_get_parent,
|
||||
/* Following five export operations are unneeded so far and can default:
|
||||
.get_dentry =
|
||||
.get_name =
|
||||
.find_exported_dentry =
|
||||
.decode_fh =
|
||||
.encode_fs = */
|
||||
/*
|
||||
* Following export operations are mandatory for NFS export support:
|
||||
* .fh_to_dentry =
|
||||
*/
|
||||
};
|
||||
|
||||
#endif /* CONFIG_CIFS_NFSD_EXPORT */
|
||||
|
@ -173,6 +173,7 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb,
|
||||
|
||||
|
||||
const struct export_operations squashfs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = squashfs_fh_to_dentry,
|
||||
.fh_to_parent = squashfs_fh_to_parent,
|
||||
.get_parent = squashfs_get_parent
|
||||
|
@ -137,6 +137,7 @@ static struct dentry *ufs_get_parent(struct dentry *child)
|
||||
}
|
||||
|
||||
static const struct export_operations ufs_export_ops = {
|
||||
.encode_fh = generic_encode_ino32_fh,
|
||||
.fh_to_dentry = ufs_fh_to_dentry,
|
||||
.fh_to_parent = ufs_fh_to_parent,
|
||||
.get_parent = ufs_get_parent,
|
||||
|
@ -98,6 +98,17 @@ enum fid_type {
|
||||
*/
|
||||
FILEID_FAT_WITH_PARENT = 0x72,
|
||||
|
||||
/*
|
||||
* 64 bit inode number, 32 bit generation number.
|
||||
*/
|
||||
FILEID_INO64_GEN = 0x81,
|
||||
|
||||
/*
|
||||
* 64 bit inode number, 32 bit generation number,
|
||||
* 64 bit parent inode number, 32 bit parent generation.
|
||||
*/
|
||||
FILEID_INO64_GEN_PARENT = 0x82,
|
||||
|
||||
/*
|
||||
* 128 bit child FID (struct lu_fid)
|
||||
* 128 bit parent FID (struct lu_fid)
|
||||
@ -129,7 +140,11 @@ struct fid {
|
||||
u32 parent_ino;
|
||||
u32 parent_gen;
|
||||
} i32;
|
||||
struct {
|
||||
struct {
|
||||
u64 ino;
|
||||
u32 gen;
|
||||
} __packed i64;
|
||||
struct {
|
||||
u32 block;
|
||||
u16 partref;
|
||||
u16 parent_partref;
|
||||
@ -253,6 +268,33 @@ extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
|
||||
extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
|
||||
int *max_len, int flags);
|
||||
|
||||
static inline bool exportfs_can_encode_fid(const struct export_operations *nop)
|
||||
{
|
||||
return !nop || nop->encode_fh;
|
||||
}
|
||||
|
||||
static inline bool exportfs_can_decode_fh(const struct export_operations *nop)
|
||||
{
|
||||
return nop && nop->fh_to_dentry;
|
||||
}
|
||||
|
||||
static inline bool exportfs_can_encode_fh(const struct export_operations *nop,
|
||||
int fh_flags)
|
||||
{
|
||||
/*
|
||||
* If a non-decodeable file handle was requested, we only need to make
|
||||
* sure that filesystem did not opt-out of encoding fid.
|
||||
*/
|
||||
if (fh_flags & EXPORT_FH_FID)
|
||||
return exportfs_can_encode_fid(nop);
|
||||
|
||||
/*
|
||||
* If a decodeable file handle was requested, we need to make sure that
|
||||
* filesystem can also decode file handles.
|
||||
*/
|
||||
return exportfs_can_decode_fh(nop);
|
||||
}
|
||||
|
||||
static inline int exportfs_encode_fid(struct inode *inode, struct fid *fid,
|
||||
int *max_len)
|
||||
{
|
||||
@ -272,10 +314,12 @@ extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
|
||||
/*
|
||||
* Generic helpers for filesystems.
|
||||
*/
|
||||
extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
|
||||
int generic_encode_ino32_fh(struct inode *inode, __u32 *fh, int *max_len,
|
||||
struct inode *parent);
|
||||
struct dentry *generic_fh_to_dentry(struct super_block *sb,
|
||||
struct fid *fid, int fh_len, int fh_type,
|
||||
struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
|
||||
extern struct dentry *generic_fh_to_parent(struct super_block *sb,
|
||||
struct dentry *generic_fh_to_parent(struct super_block *sb,
|
||||
struct fid *fid, int fh_len, int fh_type,
|
||||
struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user