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; }
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; }