Skip to content

Commit 96b2b07

Browse files
amir73iljankara
authored andcommitted
exportfs: allow exporting non-decodeable file handles to userspace
Some userspace programs use st_ino as a unique object identifier, even though inode numbers may be recycable. This issue has been addressed for NFS export long ago using the exportfs file handle API and the unique file handle identifiers are also exported to userspace via name_to_handle_at(2). fanotify also uses file handles to identify objects in events, but only for filesystems that support NFS export. Relax the requirement for NFS export support and allow more filesystems to export a unique object identifier via name_to_handle_at(2) with the flag AT_HANDLE_FID. A file handle requested with the AT_HANDLE_FID flag, may or may not be usable as an argument to open_by_handle_at(2). To allow filesystems to opt-in to supporting AT_HANDLE_FID, a struct export_operations is required, but even an empty struct is sufficient for encoding FIDs. Acked-by: Jeff Layton <[email protected]> Acked-by: Chuck Lever <[email protected]> Signed-off-by: Amir Goldstein <[email protected]> Acked-by: Christian Brauner <[email protected]> Signed-off-by: Jan Kara <[email protected]> Message-Id: <[email protected]>
1 parent 304e9c8 commit 96b2b07

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

fs/fhandle.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,22 @@
1616

1717
static long do_sys_name_to_handle(const struct path *path,
1818
struct file_handle __user *ufh,
19-
int __user *mnt_id)
19+
int __user *mnt_id, int fh_flags)
2020
{
2121
long retval;
2222
struct file_handle f_handle;
2323
int handle_dwords, handle_bytes;
2424
struct file_handle *handle = NULL;
2525

2626
/*
27-
* We need to make sure whether the file system
28-
* support decoding of the file handle
27+
* We need to make sure whether the file system support decoding of
28+
* the file handle if decodeable file handle was requested.
29+
* Otherwise, even empty export_operations are sufficient to opt-in
30+
* to encoding FIDs.
2931
*/
3032
if (!path->dentry->d_sb->s_export_op ||
31-
!path->dentry->d_sb->s_export_op->fh_to_dentry)
33+
(!(fh_flags & EXPORT_FH_FID) &&
34+
!path->dentry->d_sb->s_export_op->fh_to_dentry))
3235
return -EOPNOTSUPP;
3336

3437
if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle)))
@@ -45,10 +48,10 @@ static long do_sys_name_to_handle(const struct path *path,
4548
/* convert handle size to multiple of sizeof(u32) */
4649
handle_dwords = f_handle.handle_bytes >> 2;
4750

48-
/* we ask for a non connected handle */
51+
/* we ask for a non connectable maybe decodeable file handle */
4952
retval = exportfs_encode_fh(path->dentry,
5053
(struct fid *)handle->f_handle,
51-
&handle_dwords, 0);
54+
&handle_dwords, fh_flags);
5255
handle->handle_type = retval;
5356
/* convert handle size to bytes */
5457
handle_bytes = handle_dwords * sizeof(u32);
@@ -84,6 +87,7 @@ static long do_sys_name_to_handle(const struct path *path,
8487
* @handle: resulting file handle
8588
* @mnt_id: mount id of the file system containing the file
8689
* @flag: flag value to indicate whether to follow symlink or not
90+
* and whether a decodable file handle is required.
8791
*
8892
* @handle->handle_size indicate the space available to store the
8993
* variable part of the file handle in bytes. If there is not
@@ -96,17 +100,19 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
96100
{
97101
struct path path;
98102
int lookup_flags;
103+
int fh_flags;
99104
int err;
100105

101-
if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
106+
if (flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH | AT_HANDLE_FID))
102107
return -EINVAL;
103108

104109
lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
110+
fh_flags = (flag & AT_HANDLE_FID) ? EXPORT_FH_FID : 0;
105111
if (flag & AT_EMPTY_PATH)
106112
lookup_flags |= LOOKUP_EMPTY;
107113
err = user_path_at(dfd, name, lookup_flags, &path);
108114
if (!err) {
109-
err = do_sys_name_to_handle(&path, handle, mnt_id);
115+
err = do_sys_name_to_handle(&path, handle, mnt_id, fh_flags);
110116
path_put(&path);
111117
}
112118
return err;

include/uapi/linux/fcntl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,9 @@
112112

113113
#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */
114114

115+
/* Flags for name_to_handle_at(2). We reuse AT_ flag space to save bits... */
116+
#define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to
117+
compare object identity and may not
118+
be usable to open_by_handle_at(2) */
119+
115120
#endif /* _UAPI_LINUX_FCNTL_H */

0 commit comments

Comments
 (0)