Esempio n. 1
0
int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
		    struct inode *inode, struct cl_object *clob, int agl)
{
	const struct lu_fid  *fid   = lu_object_fid(&clob->co_lu);
	struct cl_lock *lock = vvp_env_lock(env);
	struct cl_lock_descr *descr = &lock->cll_descr;
	int result = 0;

	CDEBUG(D_DLMTRACE, "Glimpsing inode " DFID "\n", PFID(fid));

	/* NOTE: this looks like DLM lock request, but it may
	 *       not be one. Due to CEF_ASYNC flag (translated
	 *       to LDLM_FL_HAS_INTENT by osc), this is
	 *       glimpse request, that won't revoke any
	 *       conflicting DLM locks held. Instead,
	 *       ll_glimpse_callback() will be called on each
	 *       client holding a DLM lock against this file,
	 *       and resulting size will be returned for each
	 *       stripe. DLM lock on [0, EOF] is acquired only
	 *       if there were no conflicting locks. If there
	 *       were conflicting locks, enqueuing or waiting
	 *       fails with -ENAVAIL, but valid inode
	 *       attributes are returned anyway.
	 */
	*descr = whole_file;
	descr->cld_obj = clob;
	descr->cld_mode = CLM_READ;
	descr->cld_enq_flags = CEF_ASYNC | CEF_MUST;
	if (agl)
		descr->cld_enq_flags |= CEF_AGL;
	/*
	 * CEF_ASYNC is used because glimpse sub-locks cannot
	 * deadlock (because they never conflict with other
	 * locks) and, hence, can be enqueued out-of-order.
	 *
	 * CEF_MUST protects glimpse lock from conversion into
	 * a lockless mode.
	 */
	result = cl_lock_request(env, io, lock);
	if (result < 0)
		return result;

	if (!agl) {
		ll_merge_attr(env, inode);
		if (i_size_read(inode) > 0 && !inode->i_blocks) {
			/*
			 * LU-417: Add dirty pages block count
			 * lest i_blocks reports 0, some "cp" or
			 * "tar" may think it's a completely
			 * sparse file and skip it.
			 */
			inode->i_blocks = dirty_cnt(inode);
		}
	}

	cl_lock_release(env, lock);

	return result;
}
Esempio n. 2
0
void cl_put_grouplock(struct ll_grouplock *lg)
{
	struct lu_env  *env  = lg->lg_env;
	struct cl_io   *io   = lg->lg_io;
	struct cl_lock *lock = lg->lg_lock;

	LASSERT(lg->lg_env != NULL);
	LASSERT(lg->lg_gid != 0);

	cl_lock_release(env, lock);
	cl_io_fini(env, io);
	cl_env_put(env, NULL);
}
Esempio n. 3
0
void cl_put_grouplock(struct ccc_grouplock *cg)
{
        struct lu_env          *env = cg->cg_env;
        struct cl_lock         *lock = cg->cg_lock;
        int                     refcheck;

        LASSERT(cg->cg_env);
        LASSERT(cg->cg_gid);

        cl_env_implant(env, &refcheck);
        cl_env_put(env, &refcheck);

        cl_unuse(env, lock);
        cl_lock_release(env, lock, GROUPLOCK_SCOPE, cfs_current());
        cl_io_fini(env, &ccc_env_info(env)->cti_io);
        cl_env_put(env, NULL);
}
Esempio n. 4
0
int cl_local_size(struct inode *inode)
{
	struct lu_env	   *env = NULL;
	struct cl_io	    *io  = NULL;
	struct ccc_thread_info  *cti;
	struct cl_object	*clob;
	struct cl_lock_descr    *descr;
	struct cl_lock	  *lock;
	int		      result;
	int		      refcheck;

	ENTRY;

	if (!cl_i2info(inode)->lli_has_smd)
		RETURN(0);

	result = cl_io_get(inode, &env, &io, &refcheck);
	if (result <= 0)
		RETURN(result);

	clob = io->ci_obj;
	result = cl_io_init(env, io, CIT_MISC, clob);
	if (result > 0)
		result = io->ci_result;
	else if (result == 0) {
		cti = ccc_env_info(env);
		descr = &cti->cti_descr;

		*descr = whole_file;
		descr->cld_obj = clob;
		lock = cl_lock_peek(env, io, descr, "localsize", current);
		if (lock != NULL) {
			cl_merge_lvb(env, inode);
			cl_unuse(env, lock);
			cl_lock_release(env, lock, "localsize", current);
			result = 0;
		} else
			result = -ENODATA;
	}
	cl_io_fini(env, io);
	cl_env_put(env, &refcheck);
	RETURN(result);
}
Esempio n. 5
0
int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
		    struct inode *inode, struct cl_object *clob, int agl)
{
	struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr;
	struct cl_inode_info *lli   = cl_i2info(inode);
	const struct lu_fid  *fid   = lu_object_fid(&clob->co_lu);
	struct ccc_io	*cio   = ccc_env_io(env);
	struct cl_lock       *lock;
	int result;

	ENTRY;
	result = 0;
	if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) {
		CDEBUG(D_DLMTRACE, "Glimpsing inode "DFID"\n", PFID(fid));
		if (lli->lli_has_smd) {
			/* NOTE: this looks like DLM lock request, but it may
			 *       not be one. Due to CEF_ASYNC flag (translated
			 *       to LDLM_FL_HAS_INTENT by osc), this is
			 *       glimpse request, that won't revoke any
			 *       conflicting DLM locks held. Instead,
			 *       ll_glimpse_callback() will be called on each
			 *       client holding a DLM lock against this file,
			 *       and resulting size will be returned for each
			 *       stripe. DLM lock on [0, EOF] is acquired only
			 *       if there were no conflicting locks. If there
			 *       were conflicting locks, enqueuing or waiting
			 *       fails with -ENAVAIL, but valid inode
			 *       attributes are returned anyway. */
			*descr = whole_file;
			descr->cld_obj   = clob;
			descr->cld_mode  = CLM_PHANTOM;
			descr->cld_enq_flags = CEF_ASYNC | CEF_MUST;
			if (agl)
				descr->cld_enq_flags |= CEF_AGL;
			cio->cui_glimpse = 1;
			/*
			 * CEF_ASYNC is used because glimpse sub-locks cannot
			 * deadlock (because they never conflict with other
			 * locks) and, hence, can be enqueued out-of-order.
			 *
			 * CEF_MUST protects glimpse lock from conversion into
			 * a lockless mode.
			 */
			lock = cl_lock_request(env, io, descr, "glimpse",
					       current);
			cio->cui_glimpse = 0;

			if (lock == NULL)
				RETURN(0);

			if (IS_ERR(lock))
				RETURN(PTR_ERR(lock));

			LASSERT(agl == 0);
			result = cl_wait(env, lock);
			if (result == 0) {
				cl_merge_lvb(env, inode);
				if (cl_isize_read(inode) > 0 &&
				    inode->i_blocks == 0) {
					/*
					 * LU-417: Add dirty pages block count
					 * lest i_blocks reports 0, some "cp" or
					 * "tar" may think it's a completely
					 * sparse file and skip it.
					 */
					inode->i_blocks = dirty_cnt(inode);
				}
				cl_unuse(env, lock);
			}
			cl_lock_release(env, lock, "glimpse", current);
		} else {
			CDEBUG(D_DLMTRACE, "No objects for inode\n");
			cl_merge_lvb(env, inode);
		}
	}

	RETURN(result);
}