Skip to content

Commit 6434311

Browse files
amir73ilbrauner
authored andcommitted
exportfs: support encoding non-decodeable file handles by default
AT_HANDLE_FID was added as an API for name_to_handle_at() that request the encoding of a file id, which is not intended to be decoded. This file id is used by fanotify to describe objects in events. So far, overlayfs is the only filesystem that supports encoding non-decodeable file ids, by providing export_operations with an ->encode_fh() method and without a ->decode_fh() method. Add support for encoding non-decodeable file ids to all the filesystems that do not provide export_operations, by encoding a file id of type FILEID_INO64_GEN from { i_ino, i_generation }. A filesystem may that does not support NFS export, can opt-out of encoding non-decodeable file ids for fanotify by defining an empty export_operations struct (i.e. with a NULL ->encode_fh() method). This allows the use of fanotify events with file ids on filesystems like 9p which do not support NFS export to bring fanotify in feature parity with inotify on those filesystems. Note that fanotify also requires that the filesystems report a non-null fsid. Currently, many simple filesystems that have support for inotify (e.g. debugfs, tracefs, sysfs) report a null fsid, so can still not be used with fanotify in file id reporting mode. Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Amir Goldstein <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 41d1ddd commit 6434311

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

fs/exportfs/expfs.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,32 @@ int generic_encode_ino32_fh(struct inode *inode, __u32 *fh, int *max_len,
383383
}
384384
EXPORT_SYMBOL_GPL(generic_encode_ino32_fh);
385385

386+
#define FILEID_INO64_GEN_LEN 3
387+
388+
/**
389+
* exportfs_encode_ino64_fid - encode non-decodeable 64bit ino file id
390+
* @inode: the object to encode
391+
* @fid: where to store the file handle fragment
392+
* @max_len: maximum length to store there (in 4 byte units)
393+
*
394+
* This generic function is used to encode a non-decodeable file id for
395+
* fanotify for filesystems that do not support NFS export.
396+
*/
397+
static int exportfs_encode_ino64_fid(struct inode *inode, struct fid *fid,
398+
int *max_len)
399+
{
400+
if (*max_len < FILEID_INO64_GEN_LEN) {
401+
*max_len = FILEID_INO64_GEN_LEN;
402+
return FILEID_INVALID;
403+
}
404+
405+
fid->i64.ino = inode->i_ino;
406+
fid->i64.gen = inode->i_generation;
407+
*max_len = FILEID_INO64_GEN_LEN;
408+
409+
return FILEID_INO64_GEN;
410+
}
411+
386412
/**
387413
* exportfs_encode_inode_fh - encode a file handle from inode
388414
* @inode: the object to encode
@@ -401,10 +427,10 @@ int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
401427
if (!exportfs_can_encode_fh(nop, flags))
402428
return -EOPNOTSUPP;
403429

404-
if (nop && nop->encode_fh)
405-
return nop->encode_fh(inode, fid->raw, max_len, parent);
430+
if (!nop && (flags & EXPORT_FH_FID))
431+
return exportfs_encode_ino64_fid(inode, fid, max_len);
406432

407-
return -EOPNOTSUPP;
433+
return nop->encode_fh(inode, fid->raw, max_len, parent);
408434
}
409435
EXPORT_SYMBOL_GPL(exportfs_encode_inode_fh);
410436

include/linux/exportfs.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,11 @@ struct fid {
134134
u32 parent_ino;
135135
u32 parent_gen;
136136
} i32;
137-
struct {
137+
struct {
138+
u64 ino;
139+
u32 gen;
140+
} __packed i64;
141+
struct {
138142
u32 block;
139143
u16 partref;
140144
u16 parent_partref;
@@ -246,7 +250,7 @@ extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
246250

247251
static inline bool exportfs_can_encode_fid(const struct export_operations *nop)
248252
{
249-
return nop && nop->encode_fh;
253+
return !nop || nop->encode_fh;
250254
}
251255

252256
static inline bool exportfs_can_decode_fh(const struct export_operations *nop)
@@ -259,7 +263,7 @@ static inline bool exportfs_can_encode_fh(const struct export_operations *nop,
259263
{
260264
/*
261265
* If a non-decodeable file handle was requested, we only need to make
262-
* sure that filesystem can encode file handles.
266+
* sure that filesystem did not opt-out of encoding fid.
263267
*/
264268
if (fh_flags & EXPORT_FH_FID)
265269
return exportfs_can_encode_fid(nop);

0 commit comments

Comments
 (0)