Whamcloud - gitweb
LU-12137 osd-ldiskfs: create locked and unlocked versions of osd lookup code 94/35594/3
authorJames Simmons <jsimmons@infradead.org>
Mon, 19 Aug 2019 13:17:29 +0000 (09:17 -0400)
committerOleg Drokin <green@whamcloud.com>
Mon, 16 Sep 2019 23:03:56 +0000 (23:03 +0000)
The inode_lock is expected to be taken when lookup_one_len() is
called. Rename osd_ios_lookup_one_len() to osd_lookup_one_len()
since it now doesn't take the inode_lock manually. Instead it
expects the called to have already called inode_lock(). The
osd_lookup_one_len_unlocked() function will always take the
inode_lock itself. Currently osd-ldiskfs always uses
osd_lookup_one_len_unlocked().

Change-Id: Ie406db5e24f983e52ea8a89bca66546ab9d25148
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/35594
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Neil Brown <neilb@suse.de>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/osd-ldiskfs/osd_compat.c
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_oi.h
lustre/osd-ldiskfs/osd_scrub.c

index 298ce2f..15c395f 100644 (file)
@@ -66,27 +66,32 @@ static void osd_push_ctxt(const struct osd_device *dev,
        push_ctxt(save, newctxt);
 }
 
        push_ctxt(save, newctxt);
 }
 
-/**
- * osd_lookup_one_len_unlocked
- *
- * @dev:       obd device we are searching
- * @name:      pathname component to lookup
- * @base:      base directory to lookup from
- * @len:       maximum length @len should be interpreted to
- *
- * This should be called without the parent
- * i_mutex held, and will take the i_mutex itself.
- */
-struct dentry *osd_lookup_one_len_unlocked(struct osd_device *dev,
-                                          const char *name,
-                                          struct dentry *base, int len)
+struct dentry *osd_lookup_one_len_common(struct osd_device *dev,
+                                        const char *name,
+                                        struct dentry *base, int len,
+                                        enum oi_check_flags flags)
 {
        struct dentry *dchild;
 
 {
        struct dentry *dchild;
 
-       inode_lock(base->d_inode);
-       dchild = lookup_one_len(name, base, len);
-       inode_unlock(base->d_inode);
-
+       /*
+        * We can't use inode_is_locked() directly since we can't know
+        * if the current thread context took the lock earlier or if
+        * another thread context took the lock. OI_LOCKED tells us
+        * if the current thread context has already taken the lock.
+        */
+       if (!(flags & OI_LOCKED)) {
+               /* If another thread took this lock already we will
+                * just have to wait until the other thread is done.
+                */
+               inode_lock(base->d_inode);
+               dchild = lookup_one_len(name, base, len);
+               inode_unlock(base->d_inode);
+       } else {
+               /* This thread context already has taken the lock.
+                * Other threads will have to wait until we are done.
+                */
+               dchild = lookup_one_len(name, base, len);
+       }
        if (IS_ERR(dchild))
                return dchild;
 
        if (IS_ERR(dchild))
                return dchild;
 
@@ -102,17 +107,37 @@ struct dentry *osd_lookup_one_len_unlocked(struct osd_device *dev,
 }
 
 /**
 }
 
 /**
- * osd_ios_lookup_one_len - lookup single pathname component
+ * osd_lookup_one_len_unlocked
+ *
+ * @dev:       obd device we are searching
+ * @name:      pathname component to lookup
+ * @base:      base directory to lookup from
+ * @len:       maximum length @len should be interpreted to
+ *
+ * Unlike osd_lookup_one_len, this should be called without the parent
+ * i_mutex held, and will take the i_mutex itself.
+ */
+struct dentry *osd_lookup_one_len_unlocked(struct osd_device *dev,
+                                          const char *name,
+                                          struct dentry *base, int len)
+{
+       return osd_lookup_one_len_common(dev, name, base, len, ~OI_LOCKED);
+}
+
+/**
+ * osd_lookup_one_len - lookup single pathname component
  *
  * @dev:       obd device we are searching
  * @name:      pathname component to lookup
  * @base:      base directory to lookup from
  * @len:       maximum length @len should be interpreted to
  *
  * @dev:       obd device we are searching
  * @name:      pathname component to lookup
  * @base:      base directory to lookup from
  * @len:       maximum length @len should be interpreted to
+ *
+ * The caller must hold inode lock
  */
  */
-struct dentry *osd_ios_lookup_one_len(struct osd_device *dev, const char *name,
-                                     struct dentry *base, int len)
+struct dentry *osd_lookup_one_len(struct osd_device *dev, const char *name,
+                                 struct dentry *base, int len)
 {
 {
-       return osd_lookup_one_len_unlocked(dev, name, base, len);
+       return osd_lookup_one_len_common(dev, name, base, len, OI_LOCKED);
 }
 
 /* utility to make a directory */
 }
 
 /* utility to make a directory */
index c76b2a0..fc9ab44 100644 (file)
@@ -800,9 +800,8 @@ void osd_scrub_dump(struct seq_file *m, struct osd_device *dev);
 struct dentry *osd_lookup_one_len_unlocked(struct osd_device *dev,
                                           const char *name,
                                           struct dentry *base, int len);
 struct dentry *osd_lookup_one_len_unlocked(struct osd_device *dev,
                                           const char *name,
                                           struct dentry *base, int len);
-struct dentry *osd_ios_lookup_one_len(struct osd_device *dev,
-                                     const char *name,
-                                     struct dentry *base, int len);
+struct dentry *osd_lookup_one_len(struct osd_device *dev, const char *name,
+                                 struct dentry *base, int len);
 
 int osd_fld_lookup(const struct lu_env *env, struct osd_device *osd,
                   u64 seq, struct lu_seq_range *range);
 
 int osd_fld_lookup(const struct lu_env *env, struct osd_device *osd,
                   u64 seq, struct lu_seq_range *range);
index 697b81b..7e0c377 100644 (file)
@@ -131,6 +131,7 @@ static inline int osd_id_eq_strict(const struct osd_inode_id *id0,
 enum oi_check_flags {
        OI_CHECK_FLD    = 0x00000001,
        OI_KNOWN_ON_OST = 0x00000002,
 enum oi_check_flags {
        OI_CHECK_FLD    = 0x00000001,
        OI_KNOWN_ON_OST = 0x00000002,
+       OI_LOCKED       = 0x00000004,
 };
 
 extern unsigned int osd_oi_count;
 };
 
 extern unsigned int osd_oi_count;
index adabfd3..31b01fa 100644 (file)
@@ -2022,7 +2022,7 @@ static int osd_ios_lf_fill(void *buf,
                RETURN(0);
 
        scrub->os_lf_scanned++;
                RETURN(0);
 
        scrub->os_lf_scanned++;
-       child = osd_ios_lookup_one_len(dev, name, parent, namelen);
+       child = osd_lookup_one_len_unlocked(dev, name, parent, namelen);
        if (IS_ERR(child)) {
                CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n",
                      osd_name(dev), namelen, name, (int)PTR_ERR(child));
        if (IS_ERR(child)) {
                CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n",
                      osd_name(dev), namelen, name, (int)PTR_ERR(child));
@@ -2096,8 +2096,8 @@ static int osd_ios_varfid_fill(void *buf,
        if (name[0] == '.')
                RETURN(0);
 
        if (name[0] == '.')
                RETURN(0);
 
-       child = osd_ios_lookup_one_len(dev, name, fill_buf->oifb_dentry,
-                                      namelen);
+       child = osd_lookup_one_len_unlocked(dev, name, fill_buf->oifb_dentry,
+                                           namelen);
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
@@ -2145,8 +2145,8 @@ static int osd_ios_dl_fill(void *buf,
        if (map->olm_name == NULL)
                RETURN(0);
 
        if (map->olm_name == NULL)
                RETURN(0);
 
-       child = osd_ios_lookup_one_len(dev, name, fill_buf->oifb_dentry,
-                                      namelen);
+       child = osd_lookup_one_len_unlocked(dev, name, fill_buf->oifb_dentry,
+                                           namelen);
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
@@ -2180,8 +2180,8 @@ static int osd_ios_uld_fill(void *buf,
        if (name[0] != '[')
                RETURN(0);
 
        if (name[0] != '[')
                RETURN(0);
 
-       child = osd_ios_lookup_one_len(dev, name, fill_buf->oifb_dentry,
-                                      namelen);
+       child = osd_lookup_one_len_unlocked(dev, name, fill_buf->oifb_dentry,
+                                           namelen);
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
@@ -2231,8 +2231,8 @@ static int osd_ios_root_fill(void *buf,
        if (map->olm_name == NULL)
                RETURN(0);
 
        if (map->olm_name == NULL)
                RETURN(0);
 
-       child = osd_ios_lookup_one_len(dev, name, fill_buf->oifb_dentry,
-                                      namelen);
+       child = osd_lookup_one_len_unlocked(dev, name, fill_buf->oifb_dentry,
+                                           namelen);
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
        else if (!child->d_inode)
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
        else if (!child->d_inode)
@@ -2322,8 +2322,8 @@ osd_ios_ROOT_scan(struct osd_thread_info *info, struct osd_device *dev,
         *      OI mapping crashed or lost also, then we have to give up under
         *      double failure cases. */
        scrub->os_convert_igif = 1;
         *      OI mapping crashed or lost also, then we have to give up under
         *      double failure cases. */
        scrub->os_convert_igif = 1;
-       child = osd_ios_lookup_one_len(dev, dot_lustre_name, dentry,
-                                      strlen(dot_lustre_name));
+       child = osd_lookup_one_len_unlocked(dev, dot_lustre_name, dentry,
+                                           strlen(dot_lustre_name));
        if (IS_ERR(child)) {
                if (PTR_ERR(child) != -ENOENT)
                        RETURN(PTR_ERR(child));
        if (IS_ERR(child)) {
                if (PTR_ERR(child) != -ENOENT)
                        RETURN(PTR_ERR(child));
@@ -2395,8 +2395,8 @@ osd_ios_OBJECTS_scan(struct osd_thread_info *info, struct osd_device *dev,
                        RETURN(rc);
        }
 
                        RETURN(rc);
        }
 
-       child = osd_ios_lookup_one_len(dev, ADMIN_USR, dentry,
-                                      strlen(ADMIN_USR));
+       child = osd_lookup_one_len_unlocked(dev, ADMIN_USR, dentry,
+                                           strlen(ADMIN_USR));
        if (IS_ERR(child)) {
                rc = PTR_ERR(child);
        } else {
        if (IS_ERR(child)) {
                rc = PTR_ERR(child);
        } else {
@@ -2409,8 +2409,8 @@ osd_ios_OBJECTS_scan(struct osd_thread_info *info, struct osd_device *dev,
        if (rc != 0 && rc != -ENOENT)
                GOTO(out, rc);
 
        if (rc != 0 && rc != -ENOENT)
                GOTO(out, rc);
 
-       child = osd_ios_lookup_one_len(dev, ADMIN_GRP, dentry,
-                                      strlen(ADMIN_GRP));
+       child = osd_lookup_one_len_unlocked(dev, ADMIN_GRP, dentry,
+                                           strlen(ADMIN_GRP));
        if (IS_ERR(child))
                GOTO(out, rc = PTR_ERR(child));
 
        if (IS_ERR(child))
                GOTO(out, rc = PTR_ERR(child));
 
@@ -2466,9 +2466,9 @@ static void osd_initial_OI_scrub(struct osd_thread_info *info,
                        continue;
                }
 
                        continue;
                }
 
-               child = osd_ios_lookup_one_len(dev, map->olm_name,
-                                              osd_sb(dev)->s_root,
-                                              map->olm_namelen);
+               child = osd_lookup_one_len_unlocked(dev, map->olm_name,
+                                                   osd_sb(dev)->s_root,
+                                                   map->olm_namelen);
                if (PTR_ERR(child) == -ENOENT ||
                    (!IS_ERR(child) && !child->d_inode))
                        osd_scrub_refresh_mapping(info, dev, &map->olm_fid,
                if (PTR_ERR(child) == -ENOENT ||
                    (!IS_ERR(child) && !child->d_inode))
                        osd_scrub_refresh_mapping(info, dev, &map->olm_fid,