From cb1a6851d0815c82fbc48550c49bac4a88cee056 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Wed, 30 May 2012 23:08:06 +0800 Subject: [PATCH] LU-957 scrub: OSD layer cleanup for OI scrub 1) Abstract some common functions in OSD layer. 2) Call lu_object_put() in osd_object_find() under failure case. 3) Do not release buffer_head until all the needed contents have been accessed in osd_oi_index_create_one(). Signed-off-by: Fan Yong Change-Id: I3e6880271ee73ec2c4638b02c7e9c55fc827bdf3 Reviewed-on: http://review.whamcloud.com/2551 Reviewed-by: Andreas Dilger Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_compat.c | 62 +++++------ lustre/osd-ldiskfs/osd_handler.c | 223 ++++++++++++++++++++------------------ lustre/osd-ldiskfs/osd_igif.c | 6 +- lustre/osd-ldiskfs/osd_internal.h | 24 +++- lustre/osd-ldiskfs/osd_io.c | 4 +- lustre/osd-ldiskfs/osd_oi.c | 212 +++++++++++++++++------------------- lustre/osd-ldiskfs/osd_oi.h | 62 +++++++++-- 7 files changed, 319 insertions(+), 274 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_compat.c b/lustre/osd-ldiskfs/osd_compat.c index 69bea5d..1e9b397 100644 --- a/lustre/osd-ldiskfs/osd_compat.c +++ b/lustre/osd-ldiskfs/osd_compat.c @@ -55,6 +55,7 @@ #include #include "osd_internal.h" +#include "osd_oi.h" struct osd_compat_objid_seq { /* protects on-fly initialization */ @@ -344,8 +345,7 @@ int osd_compat_add_entry(struct osd_thread_info *info, struct osd_device *osd, inode = &info->oti_inode; inode->i_sb = osd_sb(osd); - inode->i_ino = id->oii_ino; - inode->i_generation = id->oii_gen; + osd_id_to_inode(inode, id); child = &info->oti_child_dentry; child->d_name.hash = 0; @@ -369,12 +369,12 @@ int osd_compat_objid_lookup(struct osd_thread_info *info, struct dentry *d; struct dentry *d_seq; struct ost_id *ostid = &info->oti_ostid; - int rc = 0; int dirn; char name[32]; struct ldiskfs_dir_entry_2 *de; struct buffer_head *bh; struct inode *dir; + struct inode *inode; ENTRY; /* on the very first lookup we find and open directories */ @@ -405,25 +405,18 @@ int osd_compat_objid_lookup(struct osd_thread_info *info, bh = osd_ldiskfs_find_entry(dir, d_seq, &de, NULL); UNLOCK_INODE_MUTEX(dir); - rc = -ENOENT; - if (bh) { - struct inode *inode; - - id->oii_ino = le32_to_cpu(de->inode); - brelse(bh); + if (bh == NULL) + RETURN(-ENOENT); - id->oii_gen = OSD_OII_NOGEN; - inode = osd_iget(info, dev, id); + osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN); + brelse(bh); - if (IS_ERR(inode)) - GOTO(cleanup, rc = PTR_ERR(inode)); - rc = 0; - id->oii_gen = inode->i_generation; - iput(inode); - } + inode = osd_iget(info, dev, id); + if (IS_ERR(inode)) + RETURN(PTR_ERR(inode)); -cleanup: - RETURN(rc); + iput(inode); + RETURN(0); } int osd_compat_objid_insert(struct osd_thread_info *info, @@ -555,6 +548,7 @@ int osd_compat_spec_lookup(struct osd_thread_info *info, struct osd_inode_id *id) { struct dentry *dentry; + struct inode *inode; char *name; int rc = -ENOENT; ENTRY; @@ -563,20 +557,20 @@ int osd_compat_spec_lookup(struct osd_thread_info *info, if (name == NULL || strlen(name) == 0) RETURN(-ENOENT); - dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); - if (!IS_ERR(dentry)) { - if (dentry->d_inode) { - if (is_bad_inode(dentry->d_inode)) { - rc = -EIO; - } else { - id->oii_ino = dentry->d_inode->i_ino; - id->oii_gen = dentry->d_inode->i_generation; - rc = 0; - } - } - dput(dentry); - } + dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); + if (!IS_ERR(dentry)) { + inode = dentry->d_inode; + if (inode) { + if (is_bad_inode(inode)) { + rc = -EIO; + } else { + osd_id_gen(id, inode->i_ino, + inode->i_generation); + rc = 0; + } + } + dput(dentry); + } - RETURN(rc); + RETURN(rc); } - diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 057e062..b68f7f788 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -243,43 +243,101 @@ static struct lu_object *osd_object_alloc(const struct lu_env *env, } } +static int osd_get_lma(struct inode *inode, struct dentry *dentry, + struct lustre_mdt_attrs *lma) +{ + int rc; + + dentry->d_inode = inode; + rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA, (void *)lma, + sizeof(*lma)); + if (rc > 0) { + /* Check LMA compatibility */ + if (lma->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP)) { + CWARN("%.16s: unsupported incompat LMA feature(s) " + "%lx/%#x\n", + LDISKFS_SB(inode->i_sb)->s_es->s_volume_name, + inode->i_ino, le32_to_cpu(lma->lma_incompat) & + ~LMA_INCOMPAT_SUPP); + rc = -ENOSYS; + } else { + lustre_lma_swab(lma); + rc = 0; + } + } else if (rc == 0) { + rc = -ENODATA; + } + + return rc; +} + /* * retrieve object from backend ext fs. **/ -struct inode *osd_iget(struct osd_thread_info *info, - struct osd_device *dev, - const struct osd_inode_id *id) +struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev, + struct osd_inode_id *id) +{ + struct inode *inode = NULL; + + inode = ldiskfs_iget(osd_sb(dev), id->oii_ino); + if (IS_ERR(inode)) { + CDEBUG(D_INODE, "no inode: ino = %u, rc = %ld\n", + id->oii_ino, PTR_ERR(inode)); + } else if (id->oii_gen != OSD_OII_NOGEN && + inode->i_generation != id->oii_gen) { + CDEBUG(D_INODE, "unmatched inode: ino = %u, gen0 = %u, " + "gen1 = %u\n", + id->oii_ino, id->oii_gen, inode->i_generation); + iput(inode); + inode = ERR_PTR(-ESTALE); + } else if (inode->i_nlink == 0) { + /* due to parallel readdir and unlink, + * we can have dead inode here. */ + CDEBUG(D_INODE, "stale inode: ino = %u\n", id->oii_ino); + make_bad_inode(inode); + iput(inode); + inode = ERR_PTR(-ESTALE); + } else if (is_bad_inode(inode)) { + CWARN("%s: bad inode: ino = %u\n", + dev->od_dt_dev.dd_lu_dev.ld_obd->obd_name, id->oii_ino); + iput(inode); + inode = ERR_PTR(-ENOENT); + } else { + if (id->oii_gen == OSD_OII_NOGEN) + osd_id_gen(id, inode->i_ino, inode->i_generation); + + /* Do not update file c/mtime in ldiskfs. + * NB: we don't have any lock to protect this because we don't + * have reference on osd_object now, but contention with + * another lookup + attr_set can't happen in the tiny window + * between if (...) and set S_NOCMTIME. */ + if (!(inode->i_flags & S_NOCMTIME)) + inode->i_flags |= S_NOCMTIME; + } + return inode; +} + +struct inode *osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev, + struct osd_inode_id *id, struct lu_fid *fid) { - struct inode *inode = NULL; + struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs; + struct inode *inode; + int rc; - inode = ldiskfs_iget(osd_sb(dev), id->oii_ino); - if (IS_ERR(inode)) { - CERROR("Cannot get inode, rc = %li\n", PTR_ERR(inode)); - } else if (id->oii_gen != OSD_OII_NOGEN && - inode->i_generation != id->oii_gen) { - iput(inode); - inode = ERR_PTR(-ESTALE); - } else if (inode->i_nlink == 0) { - /* due to parallel readdir and unlink, - * we can have dead inode here. */ - CWARN("stale inode\n"); - make_bad_inode(inode); - iput(inode); - inode = ERR_PTR(-ESTALE); - } else if (is_bad_inode(inode)) { - CERROR("bad inode %lx\n",inode->i_ino); - iput(inode); - inode = ERR_PTR(-ENOENT); - } else { - /* Do not update file c/mtime in ldiskfs. - * NB: we don't have any lock to protect this because we don't - * have reference on osd_object now, but contention with - * another lookup + attr_set can't happen in the tiny window - * between if (...) and set S_NOCMTIME. */ - if (!(inode->i_flags & S_NOCMTIME)) - inode->i_flags |= S_NOCMTIME; - } - return inode; + inode = osd_iget(info, dev, id); + if (IS_ERR(inode)) + return inode; + + rc = osd_get_lma(inode, &info->oti_obj_dentry, lma); + if (rc == 0) { + *fid = lma->lma_self_fid; + } else if (rc == -ENODATA) { + LU_IGIF_BUILD(fid, inode->i_ino, inode->i_generation); + } else { + iput(inode); + inode = ERR_PTR(rc); + } + return inode; } static int osd_fid_lookup(const struct lu_env *env, @@ -340,18 +398,20 @@ static int osd_fid_lookup(const struct lu_env *env, } if (!S_ISDIR(inode->i_mode) || !ldiskfs_pdo) /* done */ - goto out; + GOTO(out, result = 0); + + LASSERT(obj->oo_hl_head == NULL); + obj->oo_hl_head = ldiskfs_htree_lock_head_alloc(HTREE_HBITS_DEF); + if (obj->oo_hl_head == NULL) { + obj->oo_inode = NULL; + iput(inode); + GOTO(out, result = -ENOMEM); + } + GOTO(out, result = 0); - LASSERT(obj->oo_hl_head == NULL); - obj->oo_hl_head = ldiskfs_htree_lock_head_alloc(HTREE_HBITS_DEF); - if (obj->oo_hl_head == NULL) { - obj->oo_inode = NULL; - iput(inode); - result = -ENOMEM; - } out: - LINVRNT(osd_invariant(obj)); - RETURN(result); + LINVRNT(osd_invariant(obj)); + return result; } /* @@ -870,7 +930,7 @@ static void osd_conf_get(const struct lu_env *env, */ param->ddp_max_name_len = LDISKFS_NAME_LEN; param->ddp_max_nlink = LDISKFS_LINK_MAX; - param->ddp_block_shift = osd_sb(osd_dt_dev(dev))->s_blocksize_bits; + param->ddp_block_shift = sb->s_blocksize_bits; param->ddp_mntopts = 0; if (test_opt(sb, XATTR_USER)) param->ddp_mntopts |= MNTOPT_USERXATTR; @@ -1694,11 +1754,8 @@ static int __osd_oi_insert(const struct lu_env *env, struct osd_object *obj, LASSERT(obj->oo_inode != NULL); LASSERT(uc != NULL); - id->oii_ino = obj->oo_inode->i_ino; - id->oii_gen = obj->oo_inode->i_generation; - - return osd_oi_insert(info, osd, fid, id, th, - uc->mu_cap & CFS_CAP_SYS_RESOURCE_MASK); + osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation); + return osd_oi_insert(info, osd, fid, id, th); } static int osd_declare_object_create(const struct lu_env *env, @@ -1895,15 +1952,6 @@ static int osd_ea_fid_set(const struct lu_env *env, struct dt_object *dt, } /** - * Helper function to form igif - */ -static inline void osd_igif_get(const struct lu_env *env, struct inode *inode, - struct lu_fid *fid) -{ - LU_IGIF_BUILD(fid, inode->i_ino, inode->i_generation); -} - -/** * ldiskfs supports fid in dirent, it is passed in dentry->d_fsdata. * lustre 1.8 also uses d_fsdata for passing other info to ldiskfs. * To have compatilibility with 1.8 ldiskfs driver we need to have @@ -1930,54 +1978,20 @@ void osd_get_ldiskfs_dirent_param(struct ldiskfs_dentry_param *param, * \retval 0 on success */ static int osd_ea_fid_get(const struct lu_env *env, struct osd_object *obj, - __u32 ino, struct lu_fid *fid) + __u32 ino, struct lu_fid *fid) { - struct osd_thread_info *info = osd_oti_get(env); - struct lustre_mdt_attrs *mdt_attrs = &info->oti_mdt_attrs; - struct lu_device *ldev = obj->oo_dt.do_lu.lo_dev; - struct dentry *dentry = &info->oti_child_dentry; - struct osd_inode_id *id = &info->oti_id; - struct osd_device *dev; - struct inode *inode; - int rc; - - ENTRY; - dev = osd_dev(ldev); - - id->oii_ino = ino; - id->oii_gen = OSD_OII_NOGEN; - - inode = osd_iget(info, dev, id); - if (IS_ERR(inode)) { - rc = PTR_ERR(inode); - GOTO(out,rc); - } - dentry->d_inode = inode; + struct osd_thread_info *info = osd_oti_get(env); + struct osd_inode_id *id = &info->oti_id; + struct inode *inode; + ENTRY; - LASSERT(inode->i_op != NULL && inode->i_op->getxattr != NULL); - rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA, (void *)mdt_attrs, - sizeof *mdt_attrs); - - /* Check LMA compatibility */ - if (rc > 0 && - (mdt_attrs->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP))) { - CWARN("Inode %lx: Unsupported incompat LMA feature(s) %#x\n", - inode->i_ino, le32_to_cpu(mdt_attrs->lma_incompat) & - ~LMA_INCOMPAT_SUPP); - return -ENOSYS; - } + osd_id_gen(id, ino, OSD_OII_NOGEN); + inode = osd_iget_fid(info, osd_obj2dev(obj), id, fid); + if (IS_ERR(inode)) + RETURN(PTR_ERR(inode)); - if (rc > 0) { - lustre_lma_swab(mdt_attrs); - memcpy(fid, &mdt_attrs->lma_self_fid, sizeof(*fid)); - rc = 0; - } else if (rc == -ENODATA) { - osd_igif_get(env, inode, fid); - rc = 0; - } - iput(inode); -out: - RETURN(rc); + iput(inode); + RETURN(0); } /** @@ -2911,7 +2925,7 @@ static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt, LASSERT(th != NULL); if (osd_object_auth(env, dt, capa, CAPA_OPC_INDEX_INSERT)) - return -EACCES; + RETURN(-EACCES); OSD_EXEC_OP(th, insert); @@ -3173,7 +3187,7 @@ struct osd_object *osd_object_find(const struct lu_env *env, else LU_OBJECT_DEBUG(D_ERROR, env, luch, "lu_object can't be located" - ""DFID"\n", PFID(fid)); + DFID"\n", PFID(fid)); if (child == NULL) { lu_object_put(env, luch); @@ -3184,6 +3198,7 @@ struct osd_object *osd_object_find(const struct lu_env *env, LU_OBJECT_DEBUG(D_ERROR, env, luch, "lu_object does not exists "DFID"\n", PFID(fid)); + lu_object_put(env, luch); child = ERR_PTR(-ENOENT); } } else diff --git a/lustre/osd-ldiskfs/osd_igif.c b/lustre/osd-ldiskfs/osd_igif.c index 8df57ab..fa7b0af 100644 --- a/lustre/osd-ldiskfs/osd_igif.c +++ b/lustre/osd-ldiskfs/osd_igif.c @@ -55,8 +55,6 @@ void lu_igif_to_id(const struct lu_fid *fid, struct osd_inode_id *id) { - LASSERT(fid_is_igif(fid)); - id->oii_ino = lu_igif_ino(fid); - id->oii_gen = lu_igif_gen(fid); + LASSERT(fid_is_igif(fid)); + osd_id_gen(id, lu_igif_ino(fid), lu_igif_gen(fid)); } - diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index dcd29aac..f6858e1 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -78,7 +78,6 @@ struct inode; -#define OSD_OII_NOGEN (0) #define OSD_COUNTERS (0) /** Enable thandle usage statistics */ @@ -441,7 +440,9 @@ struct osd_thread_info { struct htree_lock *oti_hlock; struct lu_fid oti_fid; - struct osd_inode_id oti_id; + struct lu_fid oti_fid2; + struct osd_inode_id oti_id; + struct osd_inode_id oti_id2; struct ost_id oti_ostid; /* @@ -535,9 +536,10 @@ int osd_object_auth(const struct lu_env *env, struct dt_object *dt, struct lustre_capa *capa, __u64 opc); void osd_declare_qid(struct dt_object *dt, struct osd_thandle *oh, int type, uid_t id, struct inode *inode); -struct inode *osd_iget(struct osd_thread_info *info, - struct osd_device *dev, - const struct osd_inode_id *id); +struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev, + struct osd_inode_id *id); +struct inode *osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev, + struct osd_inode_id *id, struct lu_fid *fid); int osd_compat_init(struct osd_device *dev); void osd_compat_fini(struct osd_device *dev); @@ -585,6 +587,14 @@ static inline int osd_invariant(const struct osd_object *obj) #define osd_invariant(obj) (1) #endif +extern const struct dt_index_operations osd_otable_ops; + +static inline int osd_oi_fid2idx(struct osd_device *dev, + const struct lu_fid *fid) +{ + return fid->f_seq & (dev->od_oi_count - 1); +} + static inline struct osd_oi *osd_fid2oi(struct osd_device *osd, const struct lu_fid *fid) { @@ -593,7 +603,7 @@ static inline struct osd_oi *osd_fid2oi(struct osd_device *osd, LASSERT(osd->od_oi_table != NULL && osd->od_oi_count >= 1); /* It can work even od_oi_count equals to 1 although it's unexpected, * the only reason we set it to 1 is for performance measurement */ - return osd->od_oi_table[fid->f_seq & (osd->od_oi_count - 1)]; + return osd->od_oi_table[osd_oi_fid2idx(osd, fid)]; } extern const struct lu_device_operations osd_lu_ops; @@ -688,6 +698,8 @@ static inline void osd_ipd_put(const struct lu_env *env, } int osd_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs); +int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize, + loff_t *offs, handle_t *handle); static inline struct dentry *osd_child_dentry_by_inode(const struct lu_env *env, diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index c913d11..9adc20f 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -969,8 +969,8 @@ static int osd_ldiskfs_writelink(struct inode *inode, char *buffer, int buflen) return 0; } -static int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize, - loff_t *offs, handle_t *handle) +int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize, + loff_t *offs, handle_t *handle) { struct buffer_head *bh = NULL; loff_t offset = *offs; diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index d5f7a31..d13a0fa 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -64,15 +64,12 @@ /* fid_cpu_to_be() */ #include +#include #include "osd_oi.h" /* osd_lookup(), struct osd_thread_info */ #include "osd_internal.h" #include "osd_igif.h" -#include "dt_object.h" - -#define OSD_OI_FID_NR (1UL << OSD_OI_FID_OID_BITS) -#define OSD_OI_FID_NR_MAX (1UL << OSD_OI_FID_OID_BITS_MAX) static unsigned int osd_oi_count = OSD_OI_FID_NR; CFS_MODULE_PARM(osd_oi_count, "i", int, 0444, @@ -111,62 +108,56 @@ static void osd_oi_table_put(struct osd_thread_info *info, } static int osd_oi_index_create_one(struct osd_thread_info *info, - struct osd_device *osd, const char *name, - struct dt_index_features *feat) + struct osd_device *osd, const char *name, + struct dt_index_features *feat) { - const struct lu_env *env = info->oti_env; - struct osd_inode_id *id = &info->oti_id; - struct buffer_head *bh; - struct inode *inode; - struct ldiskfs_dir_entry_2 *de; - struct dentry *dentry; - struct inode *dir; - handle_t *jh; - int rc; - - dentry = osd_child_dentry_by_inode(env, osd_sb(osd)->s_root->d_inode, - name, strlen(name)); - dir = osd_sb(osd)->s_root->d_inode; - bh = osd_ldiskfs_find_entry(dir, dentry, &de, NULL); - if (bh) { - brelse(bh); - - id->oii_ino = le32_to_cpu(de->inode); - id->oii_gen = OSD_OII_NOGEN; - - inode = osd_iget(info, osd, id); - if (!IS_ERR(inode)) { - iput(inode); - RETURN(-EEXIST); - } - RETURN(PTR_ERR(inode)); - } - - jh = ldiskfs_journal_start_sb(osd_sb(osd), 100); - LASSERT(!IS_ERR(jh)); - - inode = ldiskfs_create_inode(jh, osd_sb(osd)->s_root->d_inode, - (S_IFREG | S_IRUGO | S_IWUSR)); - LASSERT(!IS_ERR(inode)); - - if (feat->dif_flags & DT_IND_VARKEY) - rc = iam_lvar_create(inode, feat->dif_keysize_max, - feat->dif_ptrsize, feat->dif_recsize_max, - jh); - else - rc = iam_lfix_create(inode, feat->dif_keysize_max, - feat->dif_ptrsize, feat->dif_recsize_max, - jh); - - dentry = osd_child_dentry_by_inode(env, osd_sb(osd)->s_root->d_inode, - name, strlen(name)); - rc = osd_ldiskfs_add_entry(jh, dentry, inode, NULL); - LASSERT(rc == 0); - - ldiskfs_journal_stop(jh); - iput(inode); - - return rc; + const struct lu_env *env = info->oti_env; + struct osd_inode_id *id = &info->oti_id; + struct buffer_head *bh; + struct inode *inode; + struct ldiskfs_dir_entry_2 *de; + struct dentry *dentry; + struct super_block *sb = osd_sb(osd); + struct inode *dir = sb->s_root->d_inode; + handle_t *jh; + int rc; + + dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name)); + bh = osd_ldiskfs_find_entry(dir, dentry, &de, NULL); + if (bh) { + osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN); + brelse(bh); + inode = osd_iget(info, osd, id); + if (!IS_ERR(inode)) { + iput(inode); + inode = ERR_PTR(-EEXIST); + } + return PTR_ERR(inode); + } + + jh = ldiskfs_journal_start_sb(sb, 100); + if (IS_ERR(jh)) + return PTR_ERR(jh); + + inode = ldiskfs_create_inode(jh, dir, (S_IFREG | S_IRUGO | S_IWUSR)); + if (IS_ERR(inode)) { + ldiskfs_journal_stop(jh); + return PTR_ERR(inode); + } + + if (feat->dif_flags & DT_IND_VARKEY) + rc = iam_lvar_create(inode, feat->dif_keysize_max, + feat->dif_ptrsize, feat->dif_recsize_max, + jh); + else + rc = iam_lfix_create(inode, feat->dif_keysize_max, + feat->dif_ptrsize, feat->dif_recsize_max, + jh); + dentry = osd_child_dentry_by_inode(env, dir, name, strlen(name)); + rc = osd_ldiskfs_add_entry(jh, dentry, inode, NULL); + ldiskfs_journal_stop(jh); + iput(inode); + return rc; } static struct inode *osd_oi_index_open(struct osd_thread_info *info, @@ -199,7 +190,7 @@ static struct inode *osd_oi_index_open(struct osd_thread_info *info, rc = osd_oi_index_create_one(info, osd, name, f); if (rc) - RETURN(ERR_PTR(rc)); + return ERR_PTR(rc); dentry = ll_lookup_one_len(name, osd_sb(osd)->s_root, strlen(name)); if (IS_ERR(dentry)) @@ -434,11 +425,27 @@ static int osd_oi_iam_lookup(struct osd_thread_info *oti, RETURN(rc); } +int __osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, + const struct lu_fid *fid, struct osd_inode_id *id) +{ + struct lu_fid *oi_fid = &info->oti_fid2; + int rc; + + fid_cpu_to_be(oi_fid, fid); + rc = osd_oi_iam_lookup(info, osd_fid2oi(osd, fid), (struct dt_rec *)id, + (const struct dt_key *)oi_fid); + if (rc > 0) { + osd_id_unpack(id, id); + rc = 0; + } else if (rc == 0) { + rc = -ENOENT; + } + return rc; +} + int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, struct osd_inode_id *id) { - struct lu_fid *oi_fid = &info->oti_fid; - const struct dt_key *key; int rc = 0; if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG) { @@ -446,36 +453,21 @@ int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, rc = osd_compat_objid_lookup(info, osd, fid, id); } else if (fid_is_igif(fid)) { lu_igif_to_id(fid, id); - rc = 0; } else if (fid_is_fs_root(fid)) { - struct inode *inode = osd_sb(osd)->s_root->d_inode; - - id->oii_ino = inode->i_ino; - id->oii_gen = inode->i_generation; - } else { + osd_id_gen(id, osd_sb(osd)->s_root->d_inode->i_ino, + osd_sb(osd)->s_root->d_inode->i_generation); + } else { if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) return osd_compat_spec_lookup(info, osd, fid, id); - fid_cpu_to_be(oi_fid, fid); - key = (struct dt_key *)oi_fid; - - rc = osd_oi_iam_lookup(info, osd_fid2oi(osd, fid), - (struct dt_rec *)id, key); - - if (rc > 0) { - id->oii_ino = be32_to_cpu(id->oii_ino); - id->oii_gen = be32_to_cpu(id->oii_gen); - rc = 0; - } else if (rc == 0) { - rc = -ENOENT; - } + rc = __osd_oi_lookup(info, osd, fid, id); } return rc; } static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi, - const struct dt_rec *rec, const struct dt_key *key, - struct thandle *th, int ignore_quota) + const struct dt_rec *rec, const struct dt_key *key, + struct thandle *th) { struct iam_container *bag; struct iam_rec *iam_rec = (struct iam_rec *)oti->oti_ldp; @@ -499,10 +491,7 @@ static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi, LASSERT(oh->ot_handle != NULL); LASSERT(oh->ot_handle->h_transaction != NULL); #ifdef HAVE_QUOTA_SUPPORT - if (ignore_quota) - cfs_cap_raise(CFS_CAP_SYS_RESOURCE); - else - cfs_cap_lower(CFS_CAP_SYS_RESOURCE); + cfs_cap_raise(CFS_CAP_SYS_RESOURCE); #endif if (S_ISDIR(oi->oi_inode->i_mode)) osd_fid_pack((struct osd_fid_pack *)iam_rec, rec, @@ -520,32 +509,27 @@ static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi, } int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, - const struct lu_fid *fid, const struct osd_inode_id *id0, - struct thandle *th, int ignore_quota) + const struct lu_fid *fid, const struct osd_inode_id *id, + struct thandle *th) { - struct lu_fid *oi_fid = &info->oti_fid; - struct osd_inode_id *id; - const struct dt_key *key; + struct lu_fid *oi_fid = &info->oti_fid2; + struct osd_inode_id *oi_id = &info->oti_id2; if (fid_is_igif(fid) || unlikely(fid_seq(fid) == FID_SEQ_DOT_LUSTRE)) return 0; if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG) - return osd_compat_objid_insert(info, osd, fid, id0, th); + return osd_compat_objid_insert(info, osd, fid, id, th); /* Server mount should not depends on OI files */ if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) - return osd_compat_spec_insert(info, osd, fid, id0, th); - - fid_cpu_to_be(oi_fid, fid); - key = (struct dt_key *)oi_fid; + return osd_compat_spec_insert(info, osd, fid, id, th); - id = &info->oti_id; - id->oii_ino = cpu_to_be32(id0->oii_ino); - id->oii_gen = cpu_to_be32(id0->oii_gen); - - return osd_oi_iam_insert(info, osd_fid2oi(osd, fid), - (struct dt_rec *)id, key, th, ignore_quota); + fid_cpu_to_be(oi_fid, fid); + osd_id_pack(oi_id, id); + return osd_oi_iam_insert(info, osd_fid2oi(osd, fid), + (const struct dt_rec *)oi_id, + (const struct dt_key *)oi_fid, th); } static int osd_oi_iam_delete(struct osd_thread_info *oti, struct osd_oi *oi, @@ -575,24 +559,22 @@ static int osd_oi_iam_delete(struct osd_thread_info *oti, struct osd_oi *oi, } int osd_oi_delete(struct osd_thread_info *info, - struct osd_device *osd, const struct lu_fid *fid, - struct thandle *th) + struct osd_device *osd, const struct lu_fid *fid, + struct thandle *th) { - struct lu_fid *oi_fid = &info->oti_fid; - const struct dt_key *key; - - LASSERT(fid_seq(fid) != FID_SEQ_LOCAL_FILE); + struct lu_fid *oi_fid = &info->oti_fid2; - if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG) - return osd_compat_objid_delete(info, osd, fid, th); + LASSERT(fid_seq(fid) != FID_SEQ_LOCAL_FILE); - fid_cpu_to_be(oi_fid, fid); - key = (struct dt_key *)oi_fid; + if (fid_is_idif(fid) || fid_seq(fid) == FID_SEQ_LLOG) + return osd_compat_objid_delete(info, osd, fid, th); - return osd_oi_iam_delete(info, osd_fid2oi(osd, fid), key, th); + fid_cpu_to_be(oi_fid, fid); + return osd_oi_iam_delete(info, osd_fid2oi(osd, fid), + (const struct dt_key *)oi_fid, th); } -int osd_oi_mod_init() +int osd_oi_mod_init(void) { if (osd_oi_count == 0 || osd_oi_count > OSD_OI_FID_NR_MAX) osd_oi_count = OSD_OI_FID_NR; diff --git a/lustre/osd-ldiskfs/osd_oi.h b/lustre/osd-ldiskfs/osd_oi.h index 287ede3..bae99ed 100644 --- a/lustre/osd-ldiskfs/osd_oi.h +++ b/lustre/osd-ldiskfs/osd_oi.h @@ -57,6 +57,11 @@ #include #include +#define OSD_OI_FID_NR (1UL << OSD_OI_FID_OID_BITS) +#define OSD_OI_FID_NR_MAX (1UL << OSD_OI_FID_OID_BITS_MAX) + +#define OSD_OII_NOGEN (0) + struct lu_fid; struct osd_thread_info; struct lu_site; @@ -70,25 +75,64 @@ struct osd_oi; * Storage cookie. Datum uniquely identifying inode on the underlying file * system. * - * XXX Currently this is ext2/ext3/ldiskfs specific thing. In the future this - * should be generalized to work with other local file systems. + * osd_inode_id is the internal ldiskfs identifier for an object. It should + * not be visible outside of the osd-ldiskfs. Other OSDs may have different + * identifiers, so this cannot form any part of the OSD API. */ struct osd_inode_id { - __u32 oii_ino; /* inode number */ - __u32 oii_gen; /* inode generation */ + __u32 oii_ino; /* inode number */ + __u32 oii_gen; /* inode generation */ }; +static inline void osd_id_pack(struct osd_inode_id *tgt, + const struct osd_inode_id *src) +{ + tgt->oii_ino = cpu_to_be32(src->oii_ino); + tgt->oii_gen = cpu_to_be32(src->oii_gen); +} + +static inline void osd_id_unpack(struct osd_inode_id *tgt, + struct osd_inode_id *src) +{ + tgt->oii_ino = be32_to_cpu(src->oii_ino); + tgt->oii_gen = be32_to_cpu(src->oii_gen); +} + +static inline void osd_id_gen(struct osd_inode_id *id, __u32 ino, __u32 gen) +{ + id->oii_ino = ino; + id->oii_gen = gen; +} + +static inline void osd_id_to_inode(struct inode *inode, + const struct osd_inode_id *id) +{ + inode->i_ino = id->oii_ino; + inode->i_generation = id->oii_gen; +} + +static inline int osd_id_eq(const struct osd_inode_id *id0, + const struct osd_inode_id *id1) +{ + return (id0->oii_ino == id1->oii_ino) && + (id0->oii_gen == id1->oii_gen || + id0->oii_gen == OSD_OII_NOGEN || + id1->oii_gen == OSD_OII_NOGEN); +} + int osd_oi_mod_init(void); int osd_oi_init(struct osd_thread_info *info, struct osd_device *osd); void osd_oi_fini(struct osd_thread_info *info, struct osd_device *osd); +int __osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, + const struct lu_fid *fid, struct osd_inode_id *id); int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, - const struct lu_fid *fid, struct osd_inode_id *id); + const struct lu_fid *fid, struct osd_inode_id *id); int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, - const struct lu_fid *fid, const struct osd_inode_id *id, - struct thandle *th, int ingore_quota); + const struct lu_fid *fid, const struct osd_inode_id *id, + struct thandle *th); int osd_oi_delete(struct osd_thread_info *info, - struct osd_device *osd, const struct lu_fid *fid, - struct thandle *th); + struct osd_device *osd, const struct lu_fid *fid, + struct thandle *th); #endif /* __KERNEL__ */ #endif /* _OSD_OI_H */ -- 1.8.3.1