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

Commit 55554f31 authored by John L. Hammond's avatar John L. Hammond Committed by Greg Kroah-Hartman
Browse files

staging: lustre: lov: add cl_object_layout_get()



Add cl_object_layout_get() to return the layout and generation of an
object. Replace some direct accesses to object LSM with calls to this
function.

In ll_getxattr() factor out the LOV xattr specific handling into a new
function ll_getxattr_lov() which calls cl_object_layout_get(). In
ll_listxattr() call ll_getxattr_lov() to determine if a lustre.lov
xattr should be emitted.  Add lov_lsm_pack() to generate LOV xattrs
from a LSM.

Remove the unused functions ccc_inode_lsm_{get,put}() and
lov_lsm_get().

Signed-off-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Signed-off-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5814
Reviewed-on: http://review.whamcloud.com/13680


Reviewed-by: default avatarBobi Jam <bobijam@hotmail.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 f0cf21ab
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -301,6 +301,26 @@ enum {
	OBJECT_CONF_WAIT = 2
};

enum {
	CL_LAYOUT_GEN_NONE	= (u32)-2,	/* layout lock was cancelled */
	CL_LAYOUT_GEN_EMPTY	= (u32)-1,	/* for empty layout */
};

struct cl_layout {
	/** the buffer to return the layout in lov_mds_md format. */
	struct lu_buf	cl_buf;
	/** size of layout in lov_mds_md format. */
	size_t		cl_size;
	/** Layout generation. */
	u32		cl_layout_gen;
	/**
	 * True if this is a released file.
	 * Temporarily added for released file truncate in ll_setattr_raw().
	 * It will be removed later. -Jinshan
	 */
	bool		cl_is_released;
};

/**
 * Operations implemented for each cl object layer.
 *
@@ -406,6 +426,11 @@ struct cl_object_operations {
	int (*coo_fiemap)(const struct lu_env *env, struct cl_object *obj,
			  struct ll_fiemap_info_key *fmkey,
			  struct fiemap *fiemap, size_t *buflen);
	/**
	 * Get layout and generation of the object.
	 */
	int (*coo_layout_get)(const struct lu_env *env, struct cl_object *obj,
			      struct cl_layout *layout);
};

/**
@@ -2200,6 +2225,8 @@ int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
		     struct ll_fiemap_info_key *fmkey, struct fiemap *fiemap,
		     size_t *buflen);
int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
			 struct cl_layout *cl);

/**
 * Returns true, iff \a o0 and \a o1 are slices of the same object.
+3 −0
Original line number Diff line number Diff line
@@ -346,6 +346,9 @@ enum ll_lease_type {
#define LOV_ALL_STRIPES       0xffff /* only valid for directories */
#define LOV_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */

#define XATTR_LUSTRE_PREFIX	"lustre."
#define XATTR_LUSTRE_LOV	"lustre.lov"

#define lov_user_ost_data lov_user_ost_data_v1
struct lov_user_ost_data_v1 {     /* per-stripe data structure */
	struct ost_id l_ost_oi;	  /* OST object ID */
+84 −65
Original line number Diff line number Diff line
@@ -3145,35 +3145,51 @@ ll_iocontrol_call(struct inode *inode, struct file *file,
int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct cl_object *obj = lli->lli_clob;
	struct cl_env_nest nest;
	struct lu_env *env;
	int result;
	int rc;

	if (!lli->lli_clob)
	if (!obj)
		return 0;

	env = cl_env_nested_get(&nest);
	if (IS_ERR(env))
		return PTR_ERR(env);

	result = cl_conf_set(env, lli->lli_clob, conf);
	cl_env_nested_put(&nest, env);
	rc = cl_conf_set(env, obj, conf);
	if (rc < 0)
		goto out;

	if (conf->coc_opc == OBJECT_CONF_SET) {
		struct ldlm_lock *lock = conf->coc_lock;
		struct cl_layout cl = {
			.cl_layout_gen = 0,
		};

		LASSERT(lock);
		LASSERT(ldlm_has_layout(lock));
		if (result == 0) {

		/* it can only be allowed to match after layout is
		 * applied to inode otherwise false layout would be
		 * seen. Applying layout should happen before dropping
		 * the intent lock.
		 */
		ldlm_lock_allow_match(lock);

		rc = cl_object_layout_get(env, obj, &cl);
		if (rc < 0)
			goto out;

		CDEBUG(D_VFSTRACE, DFID ": layout version change: %u -> %u\n",
		       PFID(&lli->lli_fid), ll_layout_version_get(lli),
		       cl.cl_layout_gen);
		ll_layout_version_set(lli, cl.cl_layout_gen);
		lli->lli_has_smd = lsm_has_objects(conf->u.coc_md->lsm);
	}
	}
	return result;
out:
	cl_env_nested_put(&nest, env);
	return rc;
}

/* Fetch layout from MDT with getxattr request, if it's not ready yet */
@@ -3252,7 +3268,7 @@ static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
 * in this function.
 */
static int ll_layout_lock_set(struct lustre_handle *lockh, enum ldlm_mode mode,
			      struct inode *inode, __u32 *gen, bool reconf)
			      struct inode *inode)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct ll_sb_info    *sbi = ll_i2sbi(inode);
@@ -3269,8 +3285,8 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, enum ldlm_mode mode,
	LASSERT(lock);
	LASSERT(ldlm_has_layout(lock));

	LDLM_DEBUG(lock, "File "DFID"(%p) being reconfigured: %d",
		   PFID(&lli->lli_fid), inode, reconf);
	LDLM_DEBUG(lock, "File " DFID "(%p) being reconfigured",
		   PFID(&lli->lli_fid), inode);

	/* in case this is a caching lock and reinstate with new inode */
	md_set_lock_data(sbi->ll_md_exp, lockh, inode, NULL);
@@ -3281,15 +3297,8 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, enum ldlm_mode mode,
	/* checking lvb_ready is racy but this is okay. The worst case is
	 * that multi processes may configure the file on the same time.
	 */
	if (lvb_ready || !reconf) {
		rc = -ENODATA;
	if (lvb_ready) {
			/* layout_gen must be valid if layout lock is not
			 * cancelled and stripe has already set
			 */
			*gen = ll_layout_version_get(lli);
		rc = 0;
		}
		goto out;
	}

@@ -3305,19 +3314,17 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, enum ldlm_mode mode,
	if (lock->l_lvb_data) {
		rc = obd_unpackmd(sbi->ll_dt_exp, &md.lsm,
				  lock->l_lvb_data, lock->l_lvb_len);
		if (rc >= 0) {
			*gen = LL_LAYOUT_GEN_EMPTY;
			if (md.lsm)
				*gen = md.lsm->lsm_layout_gen;
			rc = 0;
		} else {
		if (rc < 0) {
			CERROR("%s: file " DFID " unpackmd error: %d\n",
			       ll_get_fsname(inode->i_sb, NULL, 0),
			       PFID(&lli->lli_fid), rc);
			goto out;
		}

		LASSERTF(md.lsm, "lvb_data = %p, lvb_len = %u\n",
			 lock->l_lvb_data, lock->l_lvb_len);
		rc = 0;
	}
	if (rc < 0)
		goto out;

	/* set layout to file. Unlikely this will fail as old layout was
	 * surely eliminated
@@ -3359,20 +3366,7 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, enum ldlm_mode mode,
	return rc;
}

/**
 * This function checks if there exists a LAYOUT lock on the client side,
 * or enqueues it if it doesn't have one in cache.
 *
 * This function will not hold layout lock so it may be revoked any time after
 * this function returns. Any operations depend on layout should be redone
 * in that case.
 *
 * This function should be called before lov_io_init() to get an uptodate
 * layout version, the caller should save the version number and after IO
 * is finished, this function should be called again to verify that layout
 * is not changed during IO time.
 */
int ll_layout_refresh(struct inode *inode, __u32 *gen)
static int ll_layout_refresh_locked(struct inode *inode)
{
	struct ll_inode_info  *lli = ll_i2info(inode);
	struct ll_sb_info     *sbi = ll_i2sbi(inode);
@@ -3388,17 +3382,6 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen)
	};
	int rc;

	*gen = ll_layout_version_get(lli);
	if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK) || *gen != LL_LAYOUT_GEN_NONE)
		return 0;

	/* sanity checks */
	LASSERT(fid_is_sane(ll_inode2fid(inode)));
	LASSERT(S_ISREG(inode->i_mode));

	/* take layout lock mutex to enqueue layout lock exclusively. */
	mutex_lock(&lli->lli_layout_mutex);

again:
	/* mostly layout lock is caching on the local side, so try to match
	 * it before grabbing layout lock mutex.
@@ -3406,20 +3389,16 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen)
	mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
			       LCK_CR | LCK_CW | LCK_PR | LCK_PW);
	if (mode != 0) { /* hit cached lock */
		rc = ll_layout_lock_set(&lockh, mode, inode, gen, true);
		rc = ll_layout_lock_set(&lockh, mode, inode);
		if (rc == -EAGAIN)
			goto again;

		mutex_unlock(&lli->lli_layout_mutex);
		return rc;
	}

	op_data = ll_prep_md_op_data(NULL, inode, inode, NULL,
				     0, 0, LUSTRE_OPC_ANY, NULL);
	if (IS_ERR(op_data)) {
		mutex_unlock(&lli->lli_layout_mutex);
	if (IS_ERR(op_data))
		return PTR_ERR(op_data);
	}

	/* have to enqueue one */
	memset(&it, 0, sizeof(it));
@@ -3443,10 +3422,50 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen)
	if (rc == 0) {
		/* set lock data in case this is a new lock */
		ll_set_lock_data(sbi->ll_md_exp, inode, &it, NULL);
		rc = ll_layout_lock_set(&lockh, mode, inode, gen, true);
		rc = ll_layout_lock_set(&lockh, mode, inode);
		if (rc == -EAGAIN)
			goto again;
	}

	return rc;
}

/**
 * This function checks if there exists a LAYOUT lock on the client side,
 * or enqueues it if it doesn't have one in cache.
 *
 * This function will not hold layout lock so it may be revoked any time after
 * this function returns. Any operations depend on layout should be redone
 * in that case.
 *
 * This function should be called before lov_io_init() to get an uptodate
 * layout version, the caller should save the version number and after IO
 * is finished, this function should be called again to verify that layout
 * is not changed during IO time.
 */
int ll_layout_refresh(struct inode *inode, __u32 *gen)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct ll_sb_info *sbi = ll_i2sbi(inode);
	int rc;

	*gen = ll_layout_version_get(lli);
	if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK) || *gen != CL_LAYOUT_GEN_NONE)
		return 0;

	/* sanity checks */
	LASSERT(fid_is_sane(ll_inode2fid(inode)));
	LASSERT(S_ISREG(inode->i_mode));

	/* take layout lock mutex to enqueue layout lock exclusively. */
	mutex_lock(&lli->lli_layout_mutex);

	rc = ll_layout_refresh_locked(inode);
	if (rc < 0)
		goto out;

	*gen = ll_layout_version_get(lli);
out:
	mutex_unlock(&lli->lli_layout_mutex);

	return rc;
+0 −19
Original line number Diff line number Diff line
@@ -304,22 +304,3 @@ __u32 cl_fid_build_gen(const struct lu_fid *fid)
	gen = fid_flatten(fid) >> 32;
	return gen;
}

/* lsm is unreliable after hsm implementation as layout can be changed at
 * any time. This is only to support old, non-clio-ized interfaces. It will
 * cause deadlock if clio operations are called with this extra layout refcount
 * because in case the layout changed during the IO, ll_layout_refresh() will
 * have to wait for the refcount to become zero to destroy the older layout.
 *
 * Notice that the lsm returned by this function may not be valid unless called
 * inside layout lock - MDS_INODELOCK_LAYOUT.
 */
struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode)
{
	return lov_lsm_get(ll_i2info(inode)->lli_clob);
}

inline void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm)
{
	lov_lsm_put(ll_i2info(inode)->lli_clob, lsm);
}
+0 −5
Original line number Diff line number Diff line
@@ -1316,11 +1316,6 @@ static inline void d_lustre_revalidate(struct dentry *dentry)
	spin_unlock(&dentry->d_lock);
}

enum {
	LL_LAYOUT_GEN_NONE  = ((__u32)-2),	/* layout lock was cancelled */
	LL_LAYOUT_GEN_EMPTY = ((__u32)-1)	/* for empty layout */
};

int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf);
int ll_layout_refresh(struct inode *inode, __u32 *gen);
int ll_layout_restore(struct inode *inode, loff_t start, __u64 length);
Loading