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

Commit ef21b1fb authored by wang di's avatar wang di Committed by Greg Kroah-Hartman
Browse files

staging: lustre: llite: a few fixes about readdir of striped dir.



Normally we know the value of op_mea1 when ll_readdir is called.
In the case of '.' or '..' op_mea1 is unknown so for that case
fetch the real parents FID.

Signed-off-by: default avatarwang di <di.wang@intel.com>
Signed-off-by: default avatarLi Xi <lixi@ddn.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4603
Reviewed-on: http://review.whamcloud.com/9191


Reviewed-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarFan Yong <fan.yong@intel.com>
Reviewed-by: default avatarLi Xi <pkuelelixi@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 00c0a6ae
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -622,6 +622,33 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx)
		goto out;
	}

	if (unlikely(op_data->op_mea1)) {
		/*
		 * This is only needed for striped dir to fill ..,
		 * see lmv_read_page
		 */
		if (file_dentry(filp)->d_parent &&
		    file_dentry(filp)->d_parent->d_inode) {
			__u64 ibits = MDS_INODELOCK_UPDATE;
			struct inode *parent;

			parent = file_dentry(filp)->d_parent->d_inode;
			if (ll_have_md_lock(parent, &ibits, LCK_MINMODE))
				op_data->op_fid3 = *ll_inode2fid(parent);
		}

		/*
		 * If it can not find in cache, do lookup .. on the master
		 * object
		 */
		if (fid_is_zero(&op_data->op_fid3)) {
			rc = ll_dir_get_parent_fid(inode, &op_data->op_fid3);
			if (rc) {
				ll_finish_md_op_data(op_data);
				return rc;
			}
		}
	}
	ctx->pos = pos;
	rc = ll_dir_read(inode, &pos, op_data, ctx);
	pos = ctx->pos;
+1 −0
Original line number Diff line number Diff line
@@ -812,6 +812,7 @@ __u32 get_uuid2int(const char *name, int len);
void get_uuid2fsid(const char *name, int len, __kernel_fsid_t *fsid);
struct inode *search_inode_for_lustre(struct super_block *sb,
				      const struct lu_fid *fid);
int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid);

/* llite/symlink.c */
extern const struct inode_operations ll_fast_symlink_inode_operations;
+22 −9
Original line number Diff line number Diff line
@@ -302,14 +302,12 @@ static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
	return ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL);
}

static struct dentry *ll_get_parent(struct dentry *dchild)
int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid)
{
	struct ptlrpc_request *req = NULL;
	struct inode	  *dir = d_inode(dchild);
	struct ll_sb_info     *sbi;
	struct dentry	 *result = NULL;
	struct mdt_body       *body;
	static char	   dotdot[] = "..";
	static const char dotdot[] = "..";
	struct md_op_data     *op_data;
	int		   rc;
	int		      lmmsize;
@@ -324,13 +322,13 @@ static struct dentry *ll_get_parent(struct dentry *dchild)

	rc = ll_get_default_mdsize(sbi, &lmmsize);
	if (rc != 0)
		return ERR_PTR(rc);
		return rc;

	op_data = ll_prep_md_op_data(NULL, dir, NULL, dotdot,
				     strlen(dotdot), lmmsize,
				     LUSTRE_OPC_ANY, NULL);
	if (IS_ERR(op_data))
		return (void *)op_data;
		return PTR_ERR(op_data);

	rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
	ll_finish_md_op_data(op_data);
@@ -338,7 +336,7 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
		CERROR("%s: failure inode "DFID" get parent: rc = %d\n",
		       ll_get_fsname(dir->i_sb, NULL, 0),
		       PFID(ll_inode2fid(dir)), rc);
		return ERR_PTR(rc);
		return rc;
	}
	body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
	/*
@@ -348,11 +346,26 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
	if (body->valid & OBD_MD_FLID) {
		CDEBUG(D_INFO, "parent for " DFID " is " DFID "\n",
		       PFID(ll_inode2fid(dir)), PFID(&body->fid1));
		*parent_fid = body->fid1;
	}
	result = ll_iget_for_nfs(dir->i_sb, &body->fid1, NULL);

	ptlrpc_req_finished(req);
	return result;
	return 0;
}

static struct dentry *ll_get_parent(struct dentry *dchild)
{
	struct lu_fid parent_fid = { 0 };
	struct dentry *dentry;
	int rc;

	rc = ll_dir_get_parent_fid(dchild->d_inode, &parent_fid);
	if (rc)
		return ERR_PTR(rc);

	dentry = ll_iget_for_nfs(dchild->d_inode->i_sb, &parent_fid, NULL);

	return dentry;
}

const struct export_operations lustre_export_operations = {