Skip to content

Commit 304e9c8

Browse files
amir73iljankara
authored andcommitted
exportfs: add explicit flag to request non-decodeable file handles
So far, all callers of exportfs_encode_inode_fh(), except for fsnotify's show_mark_fhandle(), check that filesystem can decode file handles, but we would like to add more callers that do not require a file handle that can be decoded. Introduce a flag to explicitly request a file handle that may not to be decoded later and a wrapper exportfs_encode_fid() that sets this flag and convert show_mark_fhandle() to use the new wrapper. This will be used to allow adding fanotify support to filesystems that do not support NFS export. Acked-by: Jeff Layton <[email protected]> Acked-by: Chuck Lever <[email protected]> Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]> Message-Id: <[email protected]>
1 parent b528782 commit 304e9c8

File tree

5 files changed

+34
-8
lines changed

5 files changed

+34
-8
lines changed

Documentation/filesystems/nfs/exporting.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ are exportable by setting the s_export_op field in the struct
122122
super_block. This field must point to a "struct export_operations"
123123
struct which has the following members:
124124

125-
encode_fh (optional)
126-
Takes a dentry and creates a filehandle fragment which can later be used
125+
encode_fh (optional)
126+
Takes a dentry and creates a filehandle fragment which may later be used
127127
to find or create a dentry for the same object. The default
128128
implementation creates a filehandle fragment that encodes a 32bit inode
129129
and generation number for the inode encoded, and if necessary the

fs/exportfs/expfs.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,27 @@ static int export_encode_fh(struct inode *inode, struct fid *fid,
381381
return type;
382382
}
383383

384+
/**
385+
* exportfs_encode_inode_fh - encode a file handle from inode
386+
* @inode: the object to encode
387+
* @fid: where to store the file handle fragment
388+
* @max_len: maximum length to store there
389+
* @flags: properties of the requested file handle
390+
*
391+
* Returns an enum fid_type or a negative errno.
392+
*/
384393
int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
385-
int *max_len, struct inode *parent)
394+
int *max_len, struct inode *parent, int flags)
386395
{
387396
const struct export_operations *nop = inode->i_sb->s_export_op;
388397

398+
/*
399+
* If a decodeable file handle was requested, we need to make sure that
400+
* filesystem can decode file handles.
401+
*/
402+
if (nop && !(flags & EXPORT_FH_FID) && !nop->fh_to_dentry)
403+
return -EOPNOTSUPP;
404+
389405
if (nop && nop->encode_fh)
390406
return nop->encode_fh(inode, fid->raw, max_len, parent);
391407

@@ -418,7 +434,7 @@ int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
418434
parent = p->d_inode;
419435
}
420436

421-
error = exportfs_encode_inode_fh(inode, fid, max_len, parent);
437+
error = exportfs_encode_inode_fh(inode, fid, max_len, parent, flags);
422438
dput(p);
423439

424440
return error;

fs/notify/fanotify/fanotify.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static int fanotify_encode_fh_len(struct inode *inode)
380380
if (!inode)
381381
return 0;
382382

383-
exportfs_encode_inode_fh(inode, NULL, &dwords, NULL);
383+
exportfs_encode_inode_fh(inode, NULL, &dwords, NULL, 0);
384384
fh_len = dwords << 2;
385385

386386
/*
@@ -443,7 +443,7 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode,
443443
}
444444

445445
dwords = fh_len >> 2;
446-
type = exportfs_encode_inode_fh(inode, buf, &dwords, NULL);
446+
type = exportfs_encode_inode_fh(inode, buf, &dwords, NULL, 0);
447447
err = -EINVAL;
448448
if (!type || type == FILEID_INVALID || fh_len != dwords << 2)
449449
goto out_err;

fs/notify/fdinfo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static void show_mark_fhandle(struct seq_file *m, struct inode *inode)
5050
f.handle.handle_bytes = sizeof(f.pad);
5151
size = f.handle.handle_bytes >> 2;
5252

53-
ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, NULL);
53+
ret = exportfs_encode_fid(inode, (struct fid *)f.handle.f_handle, &size);
5454
if ((ret == FILEID_INVALID) || (ret < 0)) {
5555
WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret);
5656
return;

include/linux/exportfs.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ struct fid {
136136
};
137137

138138
#define EXPORT_FH_CONNECTABLE 0x1 /* Encode file handle with parent */
139+
#define EXPORT_FH_FID 0x2 /* File handle may be non-decodeable */
139140

140141
/**
141142
* struct export_operations - for nfsd to communicate with file systems
@@ -227,9 +228,18 @@ struct export_operations {
227228
};
228229

229230
extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
230-
int *max_len, struct inode *parent);
231+
int *max_len, struct inode *parent,
232+
int flags);
231233
extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
232234
int *max_len, int flags);
235+
236+
static inline int exportfs_encode_fid(struct inode *inode, struct fid *fid,
237+
int *max_len)
238+
{
239+
return exportfs_encode_inode_fh(inode, fid, max_len, NULL,
240+
EXPORT_FH_FID);
241+
}
242+
233243
extern struct dentry *exportfs_decode_fh_raw(struct vfsmount *mnt,
234244
struct fid *fid, int fh_len,
235245
int fileid_type,

0 commit comments

Comments
 (0)