📄 llite_lib.c
字号:
OBD_ALLOC(osc, strlen(lprof->lp_osc) + strlen(ll_instance) + 2); if (!osc) GOTO(out_free, err = -ENOMEM); sprintf(osc, "%s-%s", lprof->lp_osc, ll_instance); OBD_ALLOC(mdc, strlen(lprof->lp_mdc) + strlen(ll_instance) + 2); if (!mdc) GOTO(out_free, err = -ENOMEM); sprintf(mdc, "%s-%s", lprof->lp_mdc, ll_instance); /* connections, registrations, sb setup */ err = client_common_fill_super(sb, mdc, osc);out_free: if (mdc) OBD_FREE(mdc, strlen(mdc) + 1); if (osc) OBD_FREE(osc, strlen(osc) + 1); if (err) ll_put_super(sb); else LCONSOLE_WARN("Client %s has started\n", profilenm); RETURN(err);} /* ll_fill_super */void ll_put_super(struct super_block *sb){ struct config_llog_instance cfg; char ll_instance[sizeof(sb) * 2 + 1]; struct obd_device *obd; struct lustre_sb_info *lsi = s2lsi(sb); struct ll_sb_info *sbi = ll_s2sbi(sb); char *profilenm = get_profile_name(sb); int force = 1, next; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm); sprintf(ll_instance, "%p", sb); cfg.cfg_instance = ll_instance; lustre_end_log(sb, NULL, &cfg); if (sbi->ll_mdc_exp) { obd = class_exp2obd(sbi->ll_mdc_exp); if (obd) force = obd->obd_force; } /* We need to set force before the lov_disconnect in lustre_common_put_super, since l_d cleans up osc's as well. */ if (force) { next = 0; while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) != NULL) { obd->obd_force = force; } } if (sbi->ll_lcq) { /* Only if client_common_fill_super succeeded */ client_common_put_super(sb); } next = 0; while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) !=NULL) { class_manual_cleanup(obd); } if (profilenm) class_del_profile(profilenm); ll_free_sbi(sb); lsi->lsi_llsbi = NULL; lustre_common_put_super(sb); LCONSOLE_WARN("client %s umount complete\n", ll_instance); cfs_module_put(); EXIT;} /* client_put_super */#ifdef HAVE_REGISTER_CACHE#include <linux/cache_def.h>#ifdef HAVE_CACHE_RETURN_INTstatic int#elsestatic void#endifll_shrink_cache(int priority, unsigned int gfp_mask){ struct ll_sb_info *sbi; int count = 0; list_for_each_entry(sbi, &ll_super_blocks, ll_list) count += llap_shrink_cache(sbi, priority);#ifdef HAVE_CACHE_RETURN_INT return count;#endif}struct cache_definition ll_cache_definition = { .name = "llap_cache", .shrink = ll_shrink_cache};#endif /* HAVE_REGISTER_CACHE */struct inode *ll_inode_from_lock(struct ldlm_lock *lock){ struct inode *inode = NULL; /* NOTE: we depend on atomic igrab() -bzzz */ lock_res_and_lock(lock); if (lock->l_ast_data) { struct ll_inode_info *lli = ll_i2info(lock->l_ast_data); if (lli->lli_inode_magic == LLI_INODE_MAGIC) { inode = igrab(lock->l_ast_data); } else { inode = lock->l_ast_data; ldlm_lock_debug(NULL, inode->i_state & I_FREEING ? D_INFO : D_WARNING, lock, __FILE__, __func__, __LINE__, "l_ast_data %p is bogus: magic %08x", lock->l_ast_data, lli->lli_inode_magic); inode = NULL; } } unlock_res_and_lock(lock); return inode;}static int null_if_equal(struct ldlm_lock *lock, void *data){ if (data == lock->l_ast_data) { lock->l_ast_data = NULL; if (lock->l_req_mode != lock->l_granted_mode) LDLM_ERROR(lock,"clearing inode with ungranted lock"); } return LDLM_ITER_CONTINUE;}void ll_clear_inode(struct inode *inode){ struct ll_fid fid; struct ll_inode_info *lli = ll_i2info(inode); struct ll_sb_info *sbi = ll_i2sbi(inode); ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino, inode->i_generation, inode); if (S_ISDIR(inode->i_mode)) { /* these should have been cleared in ll_file_release */ LASSERT(lli->lli_sai == NULL); LASSERT(lli->lli_opendir_key == NULL); LASSERT(lli->lli_opendir_pid == 0); } ll_inode2fid(&fid, inode); clear_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags); mdc_change_cbdata(sbi->ll_mdc_exp, &fid, null_if_equal, inode); LASSERT(!lli->lli_open_fd_write_count); LASSERT(!lli->lli_open_fd_read_count); LASSERT(!lli->lli_open_fd_exec_count); if (lli->lli_mds_write_och) ll_mdc_real_close(inode, FMODE_WRITE); if (lli->lli_mds_exec_och) { if (!FMODE_EXEC) CERROR("No FMODE exec, bug exec och is present for " "inode %ld\n", inode->i_ino); ll_mdc_real_close(inode, FMODE_EXEC); } if (lli->lli_mds_read_och) ll_mdc_real_close(inode, FMODE_READ); if (lli->lli_smd) { obd_change_cbdata(sbi->ll_osc_exp, lli->lli_smd, null_if_equal, inode); obd_free_memmd(sbi->ll_osc_exp, &lli->lli_smd); lli->lli_smd = NULL; } if (lli->lli_symlink_name) { OBD_FREE(lli->lli_symlink_name, strlen(lli->lli_symlink_name) + 1); lli->lli_symlink_name = NULL; }#ifdef CONFIG_FS_POSIX_ACL if (lli->lli_posix_acl) { LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; }#endif lli->lli_inode_magic = LLI_INODE_DEAD;#ifdef HAVE_EXPORT___IGET spin_lock(&sbi->ll_deathrow_lock); list_del_init(&lli->lli_dead_list); spin_unlock(&sbi->ll_deathrow_lock);#endif EXIT;}static int ll_setattr_do_truncate(struct inode *inode, loff_t new_size){ struct ll_sb_info *sbi = ll_i2sbi(inode); struct ll_inode_info *lli = ll_i2info(inode); struct lov_stripe_md *lsm = lli->lli_smd; int rc; ldlm_policy_data_t policy = { .l_extent = {new_size, OBD_OBJECT_EOF } }; struct lustre_handle lockh = { 0 }; int local_lock = 0; /* 0 - no local lock; * 1 - lock taken by lock_extent; * 2 - by obd_match*/ int ast_flags; int err; ENTRY; UNLOCK_INODE_MUTEX(inode); UP_WRITE_I_ALLOC_SEM(inode); if (sbi->ll_lco.lco_flags & OBD_CONNECT_TRUNCLOCK) { ast_flags = LDLM_FL_BLOCK_GRANTED; rc = obd_match(sbi->ll_osc_exp, lsm, LDLM_EXTENT, &policy, LCK_PW, &ast_flags, inode, &lockh); if (rc > 0) { local_lock = 2; rc = 0; } else if (rc == 0) { rc = ll_file_punch(inode, new_size, 1); } } else { /* XXX when we fix the AST intents to pass the discard-range * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA * XXX here. */ ast_flags = (new_size == 0) ? LDLM_AST_DISCARD_DATA : 0; rc = ll_extent_lock(NULL, inode, lsm, LCK_PW, &policy, &lockh, ast_flags); if (likely(rc == 0)) local_lock = 1; }#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) DOWN_WRITE_I_ALLOC_SEM(inode); LOCK_INODE_MUTEX(inode);#else LOCK_INODE_MUTEX(inode); DOWN_WRITE_I_ALLOC_SEM(inode);#endif if (likely(rc == 0)) { /* Only ll_inode_size_lock is taken at this level. * lov_stripe_lock() is grabbed by ll_truncate() only over * call to obd_adjust_kms(). If vmtruncate returns 0, then * ll_truncate dropped ll_inode_size_lock() */ ll_inode_size_lock(inode, 0); if (!local_lock) set_bit(LLI_F_SRVLOCK, &lli->lli_flags); rc = vmtruncate(inode, new_size); clear_bit(LLI_F_SRVLOCK, &lli->lli_flags); if (rc != 0) { LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); ll_inode_size_unlock(inode, 0); } } if (local_lock) { if (local_lock == 2) err = obd_cancel(sbi->ll_osc_exp, lsm, LCK_PW, &lockh); else err = ll_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh); if (unlikely(err != 0)){ CERROR("extent unlock failed: err=%d," " unlock method =%d\n", err, local_lock); if (rc == 0) rc = err; } } RETURN(rc);}/* If this inode has objects allocated to it (lsm != NULL), then the OST * object(s) determine the file size and mtime. Otherwise, the MDS will * keep these values until such a time that objects are allocated for it. * We do the MDS operations first, as it is checking permissions for us. * We don't to the MDS RPC if there is nothing that we want to store there, * otherwise there is no harm in updating mtime/atime on the MDS if we are * going to do an RPC anyways. * * If we are doing a truncate, we will send the mtime and ctime updates * to the OST with the punch RPC, otherwise we do an explicit setattr RPC. * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE * at the same time. */int ll_setattr_raw(struct inode *inode, struct iattr *attr){ struct ll_inode_info *lli = ll_i2info(inode); struct lov_stripe_md *lsm = lli->lli_smd; struct ll_sb_info *sbi = ll_i2sbi(inode); struct ptlrpc_request *request = NULL; struct mdc_op_data op_data; struct lustre_md md; int ia_valid = attr->ia_valid; int rc = 0; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu valid %x\n", inode->i_ino, attr->ia_valid); ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETATTR, 1); if (ia_valid & ATTR_SIZE) { if (attr->ia_size > ll_file_maxbytes(inode)) { CDEBUG(D_INODE, "file too large %llu > "LPU64"\n", attr->ia_size, ll_file_maxbytes(inode)); RETURN(-EFBIG); } attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; } /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) RETURN(-EPERM); } /* We mark all of the fields "set" so MDS/OST does not re-set them */ if (attr->ia_valid & ATTR_CTIME) { attr->ia_ctime = CURRENT_TIME; attr->ia_valid |= ATTR_CTIME_SET; } if (!(ia_valid & ATTR_ATIME_SET) && (attr->ia_valid & ATTR_ATIME)) { attr->ia_atime = CURRENT_TIME; attr->ia_valid |= ATTR_ATIME_SET; } if (!(ia_valid & ATTR_MTIME_SET) && (attr->ia_valid & ATTR_MTIME)) { attr->ia_mtime = CURRENT_TIME; attr->ia_valid |= ATTR_MTIME_SET; } if ((attr->ia_valid & ATTR_CTIME) && !(attr->ia_valid & ATTR_MTIME)) { /* To avoid stale mtime on mds, obtain it from ost and send to mds. */ rc = ll_glimpse_size(inode, 0); if (rc) RETURN(rc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -