Example #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;
}
Example #2
0
int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock,
		     struct ll_grouplock *lg)
{
        struct lu_env          *env;
        struct cl_io           *io;
        struct cl_lock         *lock;
        struct cl_lock_descr   *descr;
        __u32                   enqflags;
	__u16                   refcheck;
        int                     rc;

        env = cl_env_get(&refcheck);
        if (IS_ERR(env))
                return PTR_ERR(env);

	io = vvp_env_thread_io(env);
        io->ci_obj = obj;

	rc = cl_io_init(env, io, CIT_MISC, io->ci_obj);
	if (rc != 0) {
		cl_io_fini(env, io);
		cl_env_put(env, &refcheck);
		/* Does not make sense to take GL for released layout */
		if (rc > 0)
			rc = -ENOTSUPP;
		return rc;
	}

	lock = vvp_env_lock(env);
	descr = &lock->cll_descr;
        descr->cld_obj = obj;
        descr->cld_start = 0;
        descr->cld_end = CL_PAGE_EOF;
        descr->cld_gid = gid;
        descr->cld_mode = CLM_GROUP;

	enqflags = CEF_MUST | (nonblock ? CEF_NONBLOCK : 0);
	descr->cld_enq_flags = enqflags;

	rc = cl_lock_request(env, io, lock);
	if (rc < 0) {
		cl_io_fini(env, io);
		cl_env_put(env, &refcheck);
		return rc;
	}

	lg->lg_env = env;
	lg->lg_io = io;
	lg->lg_lock = lock;
	lg->lg_gid = gid;

	return 0;
}