exportfs: Add a function to return the raw output from fh_to_dentry()

In order to allow nfsd to accept return values that are not
acceptable to overlayfs and others, add a new function.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Trond Myklebust 2020-11-30 17:03:17 -05:00 committed by Chuck Lever
parent 7f84b488f9
commit d045465fc6
2 changed files with 29 additions and 8 deletions

View File

@ -417,9 +417,11 @@ int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
} }
EXPORT_SYMBOL_GPL(exportfs_encode_fh); EXPORT_SYMBOL_GPL(exportfs_encode_fh);
struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid, struct dentry *
int fh_len, int fileid_type, exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len,
int (*acceptable)(void *, struct dentry *), void *context) int fileid_type,
int (*acceptable)(void *, struct dentry *),
void *context)
{ {
const struct export_operations *nop = mnt->mnt_sb->s_export_op; const struct export_operations *nop = mnt->mnt_sb->s_export_op;
struct dentry *result, *alias; struct dentry *result, *alias;
@ -432,10 +434,8 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
if (!nop || !nop->fh_to_dentry) if (!nop || !nop->fh_to_dentry)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type); result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
if (PTR_ERR(result) == -ENOMEM)
return ERR_CAST(result);
if (IS_ERR_OR_NULL(result)) if (IS_ERR_OR_NULL(result))
return ERR_PTR(-ESTALE); return result;
/* /*
* If no acceptance criteria was specified by caller, a disconnected * If no acceptance criteria was specified by caller, a disconnected
@ -561,10 +561,26 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
err_result: err_result:
dput(result); dput(result);
if (err != -ENOMEM)
err = -ESTALE;
return ERR_PTR(err); return ERR_PTR(err);
} }
EXPORT_SYMBOL_GPL(exportfs_decode_fh_raw);
struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
int fh_len, int fileid_type,
int (*acceptable)(void *, struct dentry *),
void *context)
{
struct dentry *ret;
ret = exportfs_decode_fh_raw(mnt, fid, fh_len, fileid_type,
acceptable, context);
if (IS_ERR_OR_NULL(ret)) {
if (ret == ERR_PTR(-ENOMEM))
return ret;
return ERR_PTR(-ESTALE);
}
return ret;
}
EXPORT_SYMBOL_GPL(exportfs_decode_fh); EXPORT_SYMBOL_GPL(exportfs_decode_fh);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -223,6 +223,11 @@ extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
int *max_len, struct inode *parent); int *max_len, struct inode *parent);
extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
int *max_len, int connectable); int *max_len, int connectable);
extern struct dentry *exportfs_decode_fh_raw(struct vfsmount *mnt,
struct fid *fid, int fh_len,
int fileid_type,
int (*acceptable)(void *, struct dentry *),
void *context);
extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid, extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *), int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
void *context); void *context);