Whamcloud - gitweb
LU-3864 lov: return minimal FIEMAP for released files 84/7584/12
authorBruno Faccini <bruno.faccini@intel.com>
Sun, 29 Sep 2013 07:27:32 +0000 (09:27 +0200)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 2 Oct 2013 20:16:12 +0000 (20:16 +0000)
Since st_blocks = NULL is returned for released files, FIEMAP
should at least return a minimal mapping to make users aware
that file contains data but it is not immediately available.
This will make coreutils and tools such tar happy and have
them presume file is sparse.

Also, add a new test_228 in sanity-hsm to verify it works
for "[cp,tar] --sparse" commands.

Also fix a LBUG ("lov_fiemap()) ASSERTION( fm_local ) failed")
likely to occur when no-object/ENOMEM conditions and also now
when released.

Signed-off-by: Bruno Faccini <bruno.faccini@intel.com>
Change-Id: Idc59f755d407fd34e7095898c68b4aceb5bf9c28
Reviewed-on: http://review.whamcloud.com/7584
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Aurelien Degremont <aurelien.degremont@cea.fr>
lustre/lov/lov_obd.c
lustre/tests/sanity-hsm.sh

index 20b14e5..8aed982 100644 (file)
@@ -2276,8 +2276,29 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key,
         int cur_stripe = 0, cur_stripe_wrap = 0, stripe_count;
         unsigned int buffer_size = FIEMAP_BUFFER_SIZE;
 
         int cur_stripe = 0, cur_stripe_wrap = 0, stripe_count;
         unsigned int buffer_size = FIEMAP_BUFFER_SIZE;
 
-       if (!lsm_has_objects(lsm))
-                GOTO(out, rc = 0);
+       if (!lsm_has_objects(lsm)) {
+               if (lsm && lsm_is_released(lsm) && (fm_key->fiemap.fm_start <
+                   fm_key->oa.o_size)) {
+                       /* released file, return a minimal FIEMAP if
+                        * request fits in file-size.
+                        */
+                       fiemap->fm_mapped_extents = 1;
+                       fiemap->fm_extents[0].fe_logical =
+                                               fm_key->fiemap.fm_start;
+                       if (fm_key->fiemap.fm_start + fm_key->fiemap.fm_length <
+                           fm_key->oa.o_size)
+                               fiemap->fm_extents[0].fe_length =
+                                               fm_key->fiemap.fm_length;
+                       else
+                               fiemap->fm_extents[0].fe_length =
+                                               fm_key->oa.o_size -
+                                               fm_key->fiemap.fm_start;
+                       fiemap->fm_extents[0].fe_flags |=
+                                               (FIEMAP_EXTENT_UNKNOWN |
+                                                FIEMAP_EXTENT_LAST);
+               }
+               GOTO(out, rc = 0);
+       }
 
         if (fiemap_count_to_size(fm_key->fiemap.fm_extent_count) < buffer_size)
                 buffer_size = fiemap_count_to_size(fm_key->fiemap.fm_extent_count);
 
         if (fiemap_count_to_size(fm_key->fiemap.fm_extent_count) < buffer_size)
                 buffer_size = fiemap_count_to_size(fm_key->fiemap.fm_extent_count);
@@ -2475,7 +2496,8 @@ skip_last_device_calc:
         fiemap->fm_mapped_extents = current_extent;
 
 out:
         fiemap->fm_mapped_extents = current_extent;
 
 out:
-        OBD_FREE_LARGE(fm_local, buffer_size);
+       if (fm_local)
+               OBD_FREE_LARGE(fm_local, buffer_size);
         return rc;
 }
 
         return rc;
 }
 
index ea4c4c3..8687a61 100644 (file)
@@ -2946,6 +2946,41 @@ test_227() {
 }
 run_test 227 "changelog when explicit setting of HSM flags"
 
 }
 run_test 227 "changelog when explicit setting of HSM flags"
 
+test_228() {
+       # test needs a running copytool
+       copytool_setup
+
+       dd if=/dev/urandom of=$DIR/$tfile bs=1M count=1 conv=sync ||
+               error "creating $DIR/$tfile"
+       $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tfile
+       wait_request_state $(path2fid $DIR/$tfile) ARCHIVE SUCCEED
+
+       $LFS hsm_release $DIR/$tfile
+       check_hsm_flags $DIR/$tfile "0x0000000d"
+
+       filefrag $DIR/$tfile | grep " 1 extent found" ||
+               error "filefrag on released file must return only one extent"
+
+       # only newer versions of cp detect sparse files by stat/FIEMAP
+       # (LU-2580)
+       cp --sparse=auto $DIR/$tfile $DIR/$tfile.2 ||
+               error "copying $DIR/$tfile"
+       cmp $DIR/$tfile $DIR/$tfile.2 || error "comparing copied $DIR/$tfile"
+
+       $LFS hsm_release $DIR/$tfile
+       check_hsm_flags $DIR/$tfile "0x0000000d"
+
+       mkdir $DIR/$tdir
+
+       tar cf - --sparse $DIR/$tfile | tar xvf - -C $DIR/$tdir ||
+               error "tar failed"
+       cmp $DIR/$tfile $DIR/$tdir/$DIR/$tfile ||
+               error "comparing untarred $DIR/$tfile"
+
+       copytool_cleanup
+}
+run_test 228 "On released file, return extend to FIEMAP. For [cp,tar] --sparse"
+
 test_250() {
        # test needs a running copytool
        copytool_setup
 test_250() {
        # test needs a running copytool
        copytool_setup