Whamcloud - gitweb
LU-957 scrub: OSD layer cleanup for OI scrub
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_handler.c
index 057e062..b68f7f7 100644 (file)
@@ -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