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