Whamcloud - gitweb
LU-12137 osd-ldiskfs: have scrub code handle NULL dentry inode 80/35580/5
authorJames Simmons <jsimmons@infradead.org>
Sat, 3 Aug 2019 13:46:31 +0000 (09:46 -0400)
committerOleg Drokin <green@whamcloud.com>
Thu, 15 Aug 2019 07:54:37 +0000 (07:54 +0000)
With the goal of making what is currently osd_ios_lookup_one_len()
used outside of the scrub code move the special handling of the
inode of the dentry being NULL out of the function. This leads to
making the scrub code more clear.

Most calls to osd_ios_lookup_one_len() are followed by a call to
osd_ios_scan_one() passing child->d_inode as the 4th arg.
To handle those cases, osd_ios_scan_one() is changed to
return -ENOENT when the fourth arg is NULL.  The remaining
cases require
    child->d_inode==NULL
to be handled explicitly.

Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Signed-off-by: Mr NeilBrown <neilb@suse.com>
Change-Id: Ib52d7e5ee9b1e88af830cd85f8c8841b2e7ac16f
Reviewed-on: https://review.whamcloud.com/35580
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/osd-ldiskfs/osd_compat.c
lustre/osd-ldiskfs/osd_scrub.c

index b8fcc59..cab030a 100644 (file)
@@ -75,8 +75,6 @@ static void osd_push_ctxt(const struct osd_device *dev,
  *
  * This should be called without the parent
  * i_mutex held, and will take the i_mutex itself.
  *
  * This should be called without the parent
  * i_mutex held, and will take the i_mutex itself.
- *
- * Unlike osd_lookup_one_len dentry with NULL d_inode is valid
  */
 struct dentry *osd_lookup_one_len_unlocked(const char *name,
                                           struct dentry *base, int len)
  */
 struct dentry *osd_lookup_one_len_unlocked(const char *name,
                                           struct dentry *base, int len)
@@ -106,9 +104,6 @@ struct dentry *osd_lookup_one_len_unlocked(const char *name,
  * @name:      pathname component to lookup
  * @base:      base directory to lookup from
  * @len:       maximum length @len should be interpreted to
  * @name:      pathname component to lookup
  * @base:      base directory to lookup from
  * @len:       maximum length @len should be interpreted to
- *
- * Treat found dentry with NULL d_inode as an -ENOENT error so LFSCK
- * can repair the file.
  */
 struct dentry *osd_ios_lookup_one_len(const char *name, struct dentry *base,
                                      int len)
  */
 struct dentry *osd_ios_lookup_one_len(const char *name, struct dentry *base,
                                      int len)
@@ -128,11 +123,6 @@ struct dentry *osd_ios_lookup_one_len(const char *name, struct dentry *base,
                return dentry;
        }
 
                return dentry;
        }
 
-       if (dentry->d_inode == NULL) {
-               dput(dentry);
-               return ERR_PTR(-ENOENT);
-       }
-
        return dentry;
 }
 
        return dentry;
 }
 
index 48f652a..9ac3fca 100644 (file)
@@ -1896,6 +1896,12 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev,
        int                      rc;
        ENTRY;
 
        int                      rc;
        ENTRY;
 
+       if (!inode) {
+               CDEBUG(D_INODE, "%s: child '%.*s' lacks inode: rc = -2\n",
+                      osd_name(dev), namelen, name);
+               RETURN(-ENOENT);
+       }
+
        rc = osd_get_lma(info, inode, &info->oti_obj_dentry,
                         &info->oti_ost_attrs);
        if (rc != 0 && rc != -ENODATA) {
        rc = osd_get_lma(info, inode, &info->oti_obj_dentry,
                         &info->oti_ost_attrs);
        if (rc != 0 && rc != -ENODATA) {
@@ -2021,6 +2027,11 @@ static int osd_ios_lf_fill(void *buf,
                CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n",
                      osd_name(dev), namelen, name, (int)PTR_ERR(child));
                RETURN(0);
                CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n",
                      osd_name(dev), namelen, name, (int)PTR_ERR(child));
                RETURN(0);
+       } else if (!child->d_inode) {
+               dput(child);
+               CDEBUG(D_INODE, "%s: child '%.*s' lacks inode\n",
+                      osd_name(dev), namelen, name);
+               RETURN(0);
        }
 
        inode = child->d_inode;
        }
 
        inode = child->d_inode;
@@ -2219,6 +2230,8 @@ static int osd_ios_root_fill(void *buf,
        child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
        child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
+       else if (!child->d_inode)
+               GOTO(out_put, rc = -ENOENT);
 
        if (!(map->olm_flags & OLF_NO_OI))
                rc = osd_ios_scan_one(fill_buf->oifb_info, dev,
 
        if (!(map->olm_flags & OLF_NO_OI))
                rc = osd_ios_scan_one(fill_buf->oifb_info, dev,
@@ -2227,6 +2240,7 @@ static int osd_ios_root_fill(void *buf,
        if (rc == 0 && map->olm_flags & OLF_SCAN_SUBITEMS)
                rc = osd_ios_new_item(dev, child, map->olm_scandir,
                                      map->olm_filldir);
        if (rc == 0 && map->olm_flags & OLF_SCAN_SUBITEMS)
                rc = osd_ios_new_item(dev, child, map->olm_scandir,
                                      map->olm_filldir);
+out_put:
        dput(child);
 
        RETURN(rc);
        dput(child);
 
        RETURN(rc);
@@ -2305,19 +2319,20 @@ osd_ios_ROOT_scan(struct osd_thread_info *info, struct osd_device *dev,
        scrub->os_convert_igif = 1;
        child = osd_ios_lookup_one_len(dot_lustre_name, dentry,
                                       strlen(dot_lustre_name));
        scrub->os_convert_igif = 1;
        child = osd_ios_lookup_one_len(dot_lustre_name, dentry,
                                       strlen(dot_lustre_name));
-       if (IS_ERR(child)) {
+       if (IS_ERR(child) && PTR_ERR(child) != -ENOENT) {
                rc = PTR_ERR(child);
                rc = PTR_ERR(child);
-               if (rc == -ENOENT) {
-                       /* It is 1.8 MDT device. */
-                       if (!(sf->sf_flags & SF_UPGRADE)) {
-                               scrub_file_reset(scrub, dev->od_uuid,
-                                                SF_UPGRADE);
-                               sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID;
-                               rc = scrub_file_store(info->oti_env, scrub);
-                       } else {
-                               rc = 0;
-                       }
+       } else if (IS_ERR(child) || !child->d_inode) {
+               /* It is 1.8 MDT device. */
+               if (!(sf->sf_flags & SF_UPGRADE)) {
+                       scrub_file_reset(scrub, dev->od_uuid,
+                                        SF_UPGRADE);
+                       sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID;
+                       rc = scrub_file_store(info->oti_env, scrub);
+               } else {
+                       rc = 0;
                }
                }
+               if (!IS_ERR(child))
+                       dput(child);
        } else {
                /* For lustre-2.x (x <= 3), the ".lustre" has NO FID-in-LMA,
                 * so the client will get IGIF for the ".lustre" object when
        } else {
                /* For lustre-2.x (x <= 3), the ".lustre" has NO FID-in-LMA,
                 * so the client will get IGIF for the ".lustre" object when
@@ -2448,12 +2463,13 @@ static void osd_initial_OI_scrub(struct osd_thread_info *info,
                child = osd_ios_lookup_one_len(map->olm_name,
                                               osd_sb(dev)->s_root,
                                               map->olm_namelen);
                child = osd_ios_lookup_one_len(map->olm_name,
                                               osd_sb(dev)->s_root,
                                               map->olm_namelen);
-               if (!IS_ERR(child))
-                       dput(child);
-               else if (PTR_ERR(child) == -ENOENT)
+               if (PTR_ERR(child) == -ENOENT ||
+                   (!IS_ERR(child) && !child->d_inode))
                        osd_scrub_refresh_mapping(info, dev, &map->olm_fid,
                                                  NULL, DTO_INDEX_DELETE,
                                                  true, 0, NULL);
                        osd_scrub_refresh_mapping(info, dev, &map->olm_fid,
                                                  NULL, DTO_INDEX_DELETE,
                                                  true, 0, NULL);
+               if (!IS_ERR(child))
+                       dput(child);
                map++;
        }
 
                map++;
        }