X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fllite_lib.c;h=e7443908d24f7ea7a07e839ff27d2a0afffe0a2f;hp=1aec027611d309616f39a1dea0be3782a4f5f5cc;hb=1601e8591c1334ee7879bb6daac09342caa4a542;hpb=69b34f1a015ee0ffabf4c6477f9d681608aa5af6 diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 1aec027..e744390 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1041,10 +1041,8 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) cfg->cfg_callback = class_config_llog_handler; /* set up client obds */ err = lustre_process_log(sb, profilenm, cfg); - if (err < 0) { - CERROR("Unable to process log: %d\n", err); - GOTO(out_free, err); - } + if (err < 0) + GOTO(out_free, err); /* Profile set with LCFG_MOUNTOPT so we can find our mdc and osc obds */ lprof = class_get_profile(profilenm); @@ -1216,6 +1214,212 @@ struct inode *ll_inode_from_lock(struct ldlm_lock *lock) return inode; } +static void ll_dir_clear_lsm_md(struct inode *inode) +{ + struct ll_inode_info *lli = ll_i2info(inode); + + LASSERT(S_ISDIR(inode->i_mode)); + + if (lli->lli_lsm_md != NULL) { + lmv_free_memmd(lli->lli_lsm_md); + lli->lli_lsm_md = NULL; + } +} + +static struct inode *ll_iget_anon_dir(struct super_block *sb, + const struct lu_fid *fid, + struct lustre_md *md) +{ + struct ll_sb_info *sbi = ll_s2sbi(sb); + struct mdt_body *body = md->body; + struct inode *inode; + ino_t ino; + ENTRY; + + ino = cl_fid_build_ino(fid, sbi->ll_flags & LL_SBI_32BIT_API); + inode = iget_locked(sb, ino); + if (inode == NULL) { + CERROR("%s: failed get simple inode "DFID": rc = -ENOENT\n", + ll_get_fsname(sb, NULL, 0), PFID(fid)); + RETURN(ERR_PTR(-ENOENT)); + } + + if (inode->i_state & I_NEW) { + struct ll_inode_info *lli = ll_i2info(inode); + struct lmv_stripe_md *lsm = md->lmv; + + inode->i_mode = (inode->i_mode & ~S_IFMT) | + (body->mode & S_IFMT); + LASSERTF(S_ISDIR(inode->i_mode), "Not slave inode "DFID"\n", + PFID(fid)); + + LTIME_S(inode->i_mtime) = 0; + LTIME_S(inode->i_atime) = 0; + LTIME_S(inode->i_ctime) = 0; + inode->i_rdev = 0; + + /* initializing backing dev info. */ + inode->i_mapping->backing_dev_info = + &s2lsi(inode->i_sb)->lsi_bdi; + inode->i_op = &ll_dir_inode_operations; + inode->i_fop = &ll_dir_operations; + lli->lli_fid = *fid; + ll_lli_init(lli); + + LASSERT(lsm != NULL); + /* master stripe FID */ + lli->lli_pfid = lsm->lsm_md_oinfo[0].lmo_fid; + CDEBUG(D_INODE, "lli %p master "DFID" slave "DFID"\n", + lli, PFID(fid), PFID(&lli->lli_pfid)); + unlock_new_inode(inode); + } + + RETURN(inode); +} + +static int ll_init_lsm_md(struct inode *inode, struct lustre_md *md) +{ + struct lu_fid *fid; + struct lmv_stripe_md *lsm = md->lmv; + int i; + + LASSERT(lsm != NULL); + /* XXX sigh, this lsm_root initialization should be in + * LMV layer, but it needs ll_iget right now, so we + * put this here right now. */ + for (i = 0; i < lsm->lsm_md_stripe_count; i++) { + fid = &lsm->lsm_md_oinfo[i].lmo_fid; + LASSERT(lsm->lsm_md_oinfo[i].lmo_root == NULL); + if (i == 0) { + lsm->lsm_md_oinfo[i].lmo_root = inode; + } else { + /* Unfortunately ll_iget will call ll_update_inode, + * where the initialization of slave inode is slightly + * different, so it reset lsm_md to NULL to avoid + * initializing lsm for slave inode. */ + lsm->lsm_md_oinfo[i].lmo_root = + ll_iget_anon_dir(inode->i_sb, fid, md); + if (IS_ERR(lsm->lsm_md_oinfo[i].lmo_root)) { + int rc = PTR_ERR(lsm->lsm_md_oinfo[i].lmo_root); + + lsm->lsm_md_oinfo[i].lmo_root = NULL; + return rc; + } + } + } + + /* Here is where the lsm is being initialized(fill lmo_info) after + * client retrieve MD stripe information from MDT. */ + return md_update_lsm_md(ll_i2mdexp(inode), lsm, md->body, + ll_md_blocking_ast); +} + +static inline int lli_lsm_md_eq(const struct lmv_stripe_md *lsm_md1, + const struct lmv_stripe_md *lsm_md2) +{ + return lsm_md1->lsm_md_magic == lsm_md2->lsm_md_magic && + lsm_md1->lsm_md_stripe_count == lsm_md2->lsm_md_stripe_count && + lsm_md1->lsm_md_master_mdt_index == + lsm_md2->lsm_md_master_mdt_index && + lsm_md1->lsm_md_hash_type == lsm_md2->lsm_md_hash_type && + lsm_md1->lsm_md_layout_version == + lsm_md2->lsm_md_layout_version && + strcmp(lsm_md1->lsm_md_pool_name, + lsm_md2->lsm_md_pool_name) == 0; +} + +static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md) +{ + struct ll_inode_info *lli = ll_i2info(inode); + struct lmv_stripe_md *lsm = md->lmv; + int idx; + ENTRY; + + LASSERT(S_ISDIR(inode->i_mode)); + CDEBUG(D_INODE, "update lsm %p of "DFID"\n", lli->lli_lsm_md, + PFID(ll_inode2fid(inode))); + + /* no striped information from request. */ + if (lsm == NULL) { + if (lli->lli_lsm_md == NULL) { + RETURN_EXIT; + } else if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_MIGRATE) { + /* migration is done, the temporay MIGRATE layout has + * been removed */ + CDEBUG(D_INODE, DFID" finish migration.\n", + PFID(ll_inode2fid(inode))); + lmv_free_memmd(lli->lli_lsm_md); + lli->lli_lsm_md = NULL; + RETURN_EXIT; + } else { + /* The lustre_md from req does not include stripeEA, + * see ll_md_setattr */ + RETURN_EXIT; + } + } + + /* set the directory layout */ + if (lli->lli_lsm_md == NULL) { + int rc; + + rc = ll_init_lsm_md(inode, md); + if (rc != 0) { + CERROR("%s: init "DFID" failed: rc = %d\n", + ll_get_fsname(inode->i_sb, NULL, 0), + PFID(&lli->lli_fid), rc); + return; + } + lli->lli_lsm_md = lsm; + /* set lsm_md to NULL, so the following free lustre_md + * will not free this lsm */ + md->lmv = NULL; + CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm, + lsm->lsm_md_magic, PFID(ll_inode2fid(inode))); + RETURN_EXIT; + } + + /* Compare the old and new stripe information */ + if (!lli_lsm_md_eq(lli->lli_lsm_md, lsm)) { + CERROR("inode %p %lu mismatch\n" + " new(%p) vs lli_lsm_md(%p):\n" + " magic: %x %x\n" + " count: %x %x\n" + " master: %x %x\n" + " hash_type: %x %x\n" + " layout: %x %x\n" + " pool: %s %s\n", + inode, inode->i_ino, lsm, lli->lli_lsm_md, + lsm->lsm_md_magic, lli->lli_lsm_md->lsm_md_magic, + lsm->lsm_md_stripe_count, + lli->lli_lsm_md->lsm_md_stripe_count, + lsm->lsm_md_master_mdt_index, + lli->lli_lsm_md->lsm_md_master_mdt_index, + lsm->lsm_md_hash_type, lli->lli_lsm_md->lsm_md_hash_type, + lsm->lsm_md_layout_version, + lli->lli_lsm_md->lsm_md_layout_version, + lsm->lsm_md_pool_name, + lli->lli_lsm_md->lsm_md_pool_name); + return; + } + + for (idx = 0; idx < lli->lli_lsm_md->lsm_md_stripe_count; idx++) { + if (!lu_fid_eq(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid, + &lsm->lsm_md_oinfo[idx].lmo_fid)) { + CERROR("%s: FID in lsm mismatch idx %d, old: "DFID + "new:"DFID"\n", + ll_get_fsname(inode->i_sb, NULL, 0), idx, + PFID(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid), + PFID(&lsm->lsm_md_oinfo[idx].lmo_fid)); + return; + } + } + + md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md, + md->body, ll_md_blocking_ast); + + RETURN_EXIT; +} + void ll_clear_inode(struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); @@ -1273,15 +1477,17 @@ void ll_clear_inode(struct inode *inode) #endif lli->lli_inode_magic = LLI_INODE_DEAD; - ll_clear_inode_capas(inode); - if (!S_ISDIR(inode->i_mode)) - LASSERT(cfs_list_empty(&lli->lli_agl_list)); + ll_clear_inode_capas(inode); + if (S_ISDIR(inode->i_mode)) + ll_dir_clear_lsm_md(inode); + else + LASSERT(list_empty(&lli->lli_agl_list)); - /* - * XXX This has to be done before lsm is freed below, because - * cl_object still uses inode lsm. - */ - cl_inode_fini(inode); + /* + * XXX This has to be done before lsm is freed below, because + * cl_object still uses inode lsm. + */ + cl_inode_fini(inode); lli->lli_has_smd = false; EXIT; @@ -1489,7 +1695,6 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) if (attr->ia_valid & ATTR_SIZE) inode_dio_write_done(inode); mutex_unlock(&inode->i_mutex); - down_write(&lli->lli_trunc_sem); } /* truncate on a released file must failed with -ENODATA, @@ -1557,7 +1762,11 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) * excessive to send mtime/atime updates to OSTs when not * setting times to past, but it is necessary due to possible * time de-synchronization between MDT inode and OST objects */ + if (attr->ia_valid & ATTR_SIZE) + down_write(&lli->lli_trunc_sem); rc = ll_setattr_ost(inode, attr); + if (attr->ia_valid & ATTR_SIZE) + up_write(&lli->lli_trunc_sem); } EXIT; out: @@ -1570,7 +1779,6 @@ out: ll_finish_md_op_data(op_data); } if (!S_ISDIR(inode->i_mode)) { - up_write(&lli->lli_trunc_sem); mutex_lock(&inode->i_mutex); if ((attr->ia_valid & ATTR_SIZE) && !hsm_import) inode_dio_wait(inode); @@ -1741,7 +1949,10 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) lli->lli_maxbytes = MAX_LFS_FILESIZE; } - if (sbi->ll_flags & LL_SBI_RMT_CLIENT) { + if (S_ISDIR(inode->i_mode)) + ll_update_lsm_md(inode, md); + + if (sbi->ll_flags & LL_SBI_RMT_CLIENT) { if (body->valid & OBD_MD_FLRMTPERM) ll_update_remote_perm(inode, md->remote_perm); } @@ -1756,7 +1967,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) #endif inode->i_ino = cl_fid_build_ino(&body->fid1, sbi->ll_flags & LL_SBI_32BIT_API); - inode->i_generation = cl_fid_build_gen(&body->fid1); + inode->i_generation = cl_fid_build_gen(&body->fid1); if (body->valid & OBD_MD_FLATIME) { if (body->atime > LTIME_S(inode->i_atime)) @@ -1798,17 +2009,18 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->valid & OBD_MD_FLRDEV) inode->i_rdev = old_decode_dev(body->rdev); - if (body->valid & OBD_MD_FLID) { - /* FID shouldn't be changed! */ - if (fid_is_sane(&lli->lli_fid)) { - LASSERTF(lu_fid_eq(&lli->lli_fid, &body->fid1), - "Trying to change FID "DFID + if (body->valid & OBD_MD_FLID) { + /* FID shouldn't be changed! */ + if (fid_is_sane(&lli->lli_fid)) { + LASSERTF(lu_fid_eq(&lli->lli_fid, &body->fid1), + "Trying to change FID "DFID " to the "DFID", inode "DFID"(%p)\n", PFID(&lli->lli_fid), PFID(&body->fid1), PFID(ll_inode2fid(inode)), inode); - } else - lli->lli_fid = body->fid1; - } + } else { + lli->lli_fid = body->fid1; + } + } LASSERT(fid_seq(&lli->lli_fid) != 0); @@ -2154,9 +2366,9 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req, struct super_block *sb, struct lookup_intent *it) { struct ll_sb_info *sbi = NULL; - struct lustre_md md; - int rc; - ENTRY; + struct lustre_md md = { 0 }; + int rc; + ENTRY; LASSERT(*inode || sb); sbi = sb ? ll_s2sbi(sb) : ll_i2sbi(*inode); @@ -2276,31 +2488,28 @@ out_statfs: int ll_process_config(struct lustre_cfg *lcfg) { - char *ptr; - void *sb; - struct lprocfs_static_vars lvars; - unsigned long x; - int rc = 0; + struct super_block *sb; + unsigned long x; + int rc = 0; + char *ptr; - lprocfs_llite_init_vars(&lvars); - - /* The instance name contains the sb: lustre-client-aacfe000 */ - ptr = strrchr(lustre_cfg_string(lcfg, 0), '-'); - if (!ptr || !*(++ptr)) - return -EINVAL; - if (sscanf(ptr, "%lx", &x) != 1) - return -EINVAL; - sb = (void *)x; - /* This better be a real Lustre superblock! */ - LASSERT(s2lsi((struct super_block *)sb)->lsi_lmd->lmd_magic == LMD_MAGIC); - - /* Note we have not called client_common_fill_super yet, so - proc fns must be able to handle that! */ - rc = class_process_proc_param(PARAM_LLITE, lvars.obd_vars, - lcfg, sb); - if (rc > 0) - rc = 0; - return(rc); + /* The instance name contains the sb: lustre-client-aacfe000 */ + ptr = strrchr(lustre_cfg_string(lcfg, 0), '-'); + if (!ptr || !*(++ptr)) + return -EINVAL; + if (sscanf(ptr, "%lx", &x) != 1) + return -EINVAL; + sb = (struct super_block *)x; + /* This better be a real Lustre superblock! */ + LASSERT(s2lsi(sb)->lsi_lmd->lmd_magic == LMD_MAGIC); + + /* Note we have not called client_common_fill_super yet, so + proc fns must be able to handle that! */ + rc = class_process_proc_seq_param(PARAM_LLITE, lprocfs_llite_obd_vars, + lcfg, sb); + if (rc > 0) + rc = 0; + return rc; } /* this function prepares md_op_data hint for passing ot down to MD stack. */ @@ -2320,17 +2529,27 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data, if (op_data == NULL) return ERR_PTR(-ENOMEM); - ll_i2gids(op_data->op_suppgids, i1, i2); - op_data->op_fid1 = *ll_inode2fid(i1); - op_data->op_capa1 = ll_mdscapa_get(i1); + ll_i2gids(op_data->op_suppgids, i1, i2); + op_data->op_fid1 = *ll_inode2fid(i1); + op_data->op_capa1 = ll_mdscapa_get(i1); + if (S_ISDIR(i1->i_mode)) + op_data->op_mea1 = ll_i2info(i1)->lli_lsm_md; + + if (i2) { + op_data->op_fid2 = *ll_inode2fid(i2); + op_data->op_capa2 = ll_mdscapa_get(i2); + if (S_ISDIR(i2->i_mode)) + op_data->op_mea2 = ll_i2info(i2)->lli_lsm_md; + } else { + fid_zero(&op_data->op_fid2); + op_data->op_capa2 = NULL; + } - if (i2) { - op_data->op_fid2 = *ll_inode2fid(i2); - op_data->op_capa2 = ll_mdscapa_get(i2); - } else { - fid_zero(&op_data->op_fid2); - op_data->op_capa2 = NULL; - } + if (ll_i2sbi(i1)->ll_flags & LL_SBI_64BIT_HASH) + op_data->op_cli_flags |= CLI_HASH64; + + if (ll_need_32bit_api(ll_i2sbi(i1))) + op_data->op_cli_flags |= CLI_API32; op_data->op_name = name; op_data->op_namelen = namelen; @@ -2344,7 +2563,6 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data, if ((opc == LUSTRE_OPC_CREATE) && (name != NULL) && filename_is_volatile(name, namelen, NULL)) op_data->op_bias |= MDS_CREATE_VOLATILE; - op_data->op_opc = opc; op_data->op_mds = 0; op_data->op_data = data;