Whamcloud - gitweb
LU-9857 lmv: stripe dir page may be released mistakenly 48/28548/2
authorLai Siyao <lai.siyao@intel.com>
Tue, 15 Aug 2017 03:13:30 +0000 (11:13 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 28 Aug 2017 06:27:13 +0000 (06:27 +0000)
stripe_dirent_next() may put_stripe_dirent() while its dirent
is still in use, e.g. lmv_dirent_next() popped stripe last
dirent, when it can't point sd_ent to next, but it shouldn't
release stripe dir page.

stripe_dirent->sd_ent should be set NULL when its dir page
is released, which can avoid misuse.

Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Change-Id: I6d0e119d598e468d6a080b2072514a6bf1d4f786
Reviewed-on: https://review.whamcloud.com/28548
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Tested-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lmv/lmv_obd.c

index 904a7e0..19bbe64 100644 (file)
@@ -2082,6 +2082,7 @@ static inline void put_stripe_dirent(struct stripe_dirent *stripe)
                kunmap(stripe->sd_page);
                put_page(stripe->sd_page);
                stripe->sd_page = NULL;
+               stripe->sd_ent = NULL;
        }
 }
 
@@ -2105,20 +2106,23 @@ static struct lu_dirent *stripe_dirent_next(struct lmv_dir_ctxt *ctxt,
 
        LASSERT(stripe == &ctxt->ldc_stripes[stripe_index]);
 
+       if (stripe->sd_eof)
+               RETURN(NULL);
+
        if (ent) {
                ent = lu_dirent_next(ent);
                if (!ent) {
 check_eof:
                        end = le64_to_cpu(stripe->sd_dp->ldp_hash_end);
-
-                       put_stripe_dirent(stripe);
-
+                       LASSERTF(hash <= end, "hash %llx end %llx\n",
+                                hash, end);
                        if (end == MDS_DIR_END_OFF) {
                                stripe->sd_ent = NULL;
                                stripe->sd_eof = true;
                                RETURN(NULL);
                        }
-                       LASSERT(hash <= end);
+
+                       put_stripe_dirent(stripe);
                        hash = end;
                }
        }
@@ -2170,10 +2174,8 @@ check_eof:
                             le16_to_cpu(ent->lde_namelen)) == 0))
                        continue;
 
-               if (le64_to_cpu(ent->lde_hash) < hash)
-                       continue;
-
-               break;
+               if (le64_to_cpu(ent->lde_hash) >= hash)
+                       break;
        }
 
        if (!ent)