From cb77659272af51e80099c93b0e65abbf43bdaad5 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin Date: Sun, 14 Feb 2016 19:13:52 -0500 Subject: [PATCH] staging/lustre: proper support of NFS anonymous dentries NFS can ask to encode dentries that are not connected to the root. The fix check for parent is NULL and encode a file handle accordingly. Reviewed-on: http://review.whamcloud.com/8347 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4231 Reviewed-by: Fan Yong Reviewed-by: James Simmons Reviewed-by: Jian Yu Signed-off-by: Dmitry Eremin Signed-off-by: Oleg Drokin Acked-by: Jeff Layton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_nfs.c | 30 ++++++++++++++----------- include/linux/exportfs.h | 6 +++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c index 2484412..74a8868 100644 --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c @@ -142,10 +142,11 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren struct inode *inode; struct dentry *result; - CDEBUG(D_INFO, "Get dentry for fid: "DFID"\n", PFID(fid)); if (!fid_is_sane(fid)) return ERR_PTR(-ESTALE); + CDEBUG(D_INFO, "Get dentry for fid: " DFID "\n", PFID(fid)); + inode = search_inode_for_lustre(sb, fid); if (IS_ERR(inode)) return ERR_CAST(inode); @@ -161,7 +162,7 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren * We have to find the parent to tell MDS how to init lov objects. */ if (S_ISREG(inode->i_mode) && !ll_i2info(inode)->lli_has_smd && - parent != NULL) { + parent && !fid_is_zero(parent)) { struct ll_inode_info *lli = ll_i2info(inode); spin_lock(&lli->lli_lock); @@ -175,8 +176,6 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren return result; } -#define LUSTRE_NFS_FID 0x97 - /** * \a connectable - is nfsd will connect himself or this should be done * at lustre @@ -189,20 +188,25 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren static int ll_encode_fh(struct inode *inode, __u32 *fh, int *plen, struct inode *parent) { + int fileid_len = sizeof(struct lustre_nfs_fid) / 4; struct lustre_nfs_fid *nfs_fid = (void *)fh; CDEBUG(D_INFO, "encoding for (%lu,"DFID") maxlen=%d minlen=%d\n", - inode->i_ino, PFID(ll_inode2fid(inode)), *plen, - (int)sizeof(struct lustre_nfs_fid)); + inode->i_ino, PFID(ll_inode2fid(inode)), *plen, fileid_len); - if (*plen < sizeof(struct lustre_nfs_fid) / 4) - return 255; + if (*plen < fileid_len) { + *plen = fileid_len; + return FILEID_INVALID; + } nfs_fid->lnf_child = *ll_inode2fid(inode); - nfs_fid->lnf_parent = *ll_inode2fid(parent); - *plen = sizeof(struct lustre_nfs_fid) / 4; + if (parent) + nfs_fid->lnf_parent = *ll_inode2fid(parent); + else + fid_zero(&nfs_fid->lnf_parent); + *plen = fileid_len; - return LUSTRE_NFS_FID; + return FILEID_LUSTRE; } static int ll_nfs_get_name_filldir(struct dir_context *ctx, const char *name, @@ -261,7 +265,7 @@ static struct dentry *ll_fh_to_dentry(struct super_block *sb, struct fid *fid, { struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid; - if (fh_type != LUSTRE_NFS_FID) + if (fh_type != FILEID_LUSTRE) return ERR_PTR(-EPROTO); return ll_iget_for_nfs(sb, &nfs_fid->lnf_child, &nfs_fid->lnf_parent); @@ -272,7 +276,7 @@ static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid, { struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid; - if (fh_type != LUSTRE_NFS_FID) + if (fh_type != FILEID_LUSTRE) return ERR_PTR(-EPROTO); return ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL); diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index fa05e04..d841450 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -97,6 +97,12 @@ enum fid_type { FILEID_FAT_WITH_PARENT = 0x72, /* + * 128 bit child FID (struct lu_fid) + * 128 bit parent FID (struct lu_fid) + */ + FILEID_LUSTRE = 0x97, + + /* * Filesystems must not use 0xff file ID. */ FILEID_INVALID = 0xff, -- 2.7.4