Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb776592 authored by Dmitry Eremin's avatar Dmitry Eremin Committed by Greg Kroah-Hartman
Browse files

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: default avatarFan Yong <fan.yong@intel.com>
Reviewed-by: default avatarJames Simmons <uja.ornl@gmail.com>
Reviewed-by: default avatarJian Yu <jian.yu@intel.com>
Signed-off-by: default avatarDmitry Eremin <dmitry.eremin@intel.com>
Signed-off-by: default avatarOleg Drokin <green@linuxhacker.ru>
Acked-by: default avatarJeff Layton <jlayton@poochiereds.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 020ecc6f
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -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);
	if (parent)
		nfs_fid->lnf_parent = *ll_inode2fid(parent);
	*plen = sizeof(struct lustre_nfs_fid) / 4;
	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);
+6 −0
Original line number Diff line number Diff line
@@ -96,6 +96,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.
	 */