Whamcloud - gitweb
LU-9008 pfl: Read should not trigger layout write intent 99/26499/10
authorJinshan Xiong <jinshan.xiong@intel.com>
Tue, 11 Apr 2017 11:08:16 +0000 (19:08 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 26 Apr 2017 03:39:54 +0000 (03:39 +0000)
In lov_io_rw_iter_init(), only write not read operation should
trigger layout write intent.

For append write, it has to make sure all uninited components
are instantiated.

Page mkwrite should also trigger write intent.

Fixed sanity-pfl test cases as well - in order to instantiate
a component by truncate, the truncated size must be within the
extent of component.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: I3c5257c5799ae0df35a572b9ee981f583260e8ec
Reviewed-on: https://review.whamcloud.com/26499
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/llite/vvp_io.c
lustre/lov/lov_io.c
lustre/tests/sanity-pfl.sh

index 700b179..809c4a0 100644 (file)
@@ -340,17 +340,25 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
         */
        if (io->ci_need_write_intent) {
                loff_t start = 0;
-               loff_t end = 0;
-
-               LASSERT(io->ci_type == CIT_WRITE || cl_io_is_trunc(io));
+               loff_t end = OBD_OBJECT_EOF;
 
                io->ci_need_write_intent = 0;
 
+               LASSERT(io->ci_type == CIT_WRITE ||
+                       cl_io_is_trunc(io) || cl_io_is_mkwrite(io));
+
                if (io->ci_type == CIT_WRITE) {
-                       start = io->u.ci_rw.crw_pos;
-                       end = io->u.ci_rw.crw_pos + io->u.ci_rw.crw_count;
-               } else {
+                       if (!cl_io_is_append(io)) {
+                               start = io->u.ci_rw.crw_pos;
+                               end = start + io->u.ci_rw.crw_count;
+                       }
+               } else if (cl_io_is_trunc(io)) {
                        end = io->u.ci_setattr.sa_attr.lvb_size;
+               } else { /* mkwrite */
+                       pgoff_t index = io->u.ci_fault.ft_index;
+
+                       start = cl_offset(io->ci_obj, index);
+                       end = cl_offset(io->ci_obj, index + 1);
                }
 
                CDEBUG(D_VFSTRACE, DFID" type %d [%llx, %llx)\n",
index aa32f58..1bf1bcb 100644 (file)
@@ -384,6 +384,7 @@ static loff_t lov_offset_mod(loff_t val, int delta)
 static int lov_io_iter_init(const struct lu_env *env,
                            const struct cl_io_slice *ios)
 {
+       struct cl_io         *io = ios->cis_io;
        struct lov_io        *lio = cl2lov_io(env, ios);
        struct lov_stripe_md *lsm = lio->lis_object->lo_lsm;
        struct lov_io_sub    *sub;
@@ -404,15 +405,26 @@ static int lov_io_iter_init(const struct lu_env *env,
                u64 end;
                int stripe;
 
-               CDEBUG(D_VFSTRACE, "component[%d] flags %#x\n",
-                      index, lsm->lsm_entries[index]->lsme_flags);
-               if (!lsm_entry_inited(lsm, index))
-                       break;
-
                index++;
                if (!lu_extent_is_overlapped(&ext, &le->lle_extent))
                        continue;
 
+               CDEBUG(D_VFSTRACE, "component[%d] flags %#x\n",
+                      index - 1, lsm->lsm_entries[index - 1]->lsme_flags);
+               if (!lsm_entry_inited(lsm, index - 1)) {
+                       /* truncate IO will trigger write intent as well, and
+                        * it's handled in lov_io_setattr_iter_init() */
+                       if (io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io)) {
+                               io->ci_need_write_intent = 1;
+                               rc = -ENODATA;
+                               break;
+                       }
+
+                       /* Read from uninitialized components should return
+                        * zero filled pages. */
+                       continue;
+               }
+
                for (stripe = 0; stripe < r0->lo_nr; stripe++) {
                        if (!lov_stripe_intersects(lsm, index - 1, stripe,
                                                   &ext, &start, &end))
@@ -507,12 +519,6 @@ static int lov_io_rw_iter_init(const struct lu_env *env,
               (__u64)start, lio->lis_pos, lio->lis_endpos,
               (__u64)lio->lis_io_endpos, io->u.ci_rw.crw_count);
 
-       index = lov_lsm_entry(lsm, lio->lis_endpos - 1);
-       if (index > 0 && !lsm_entry_inited(lsm, index)) {
-               io->ci_need_write_intent = 1;
-               RETURN(io->ci_result = -ENODATA);
-       }
-
        /*
         * XXX The following call should be optimized: we know, that
         * [lio->lis_pos, lio->lis_endpos) intersects with exactly one stripe.
@@ -529,7 +535,7 @@ static int lov_io_setattr_iter_init(const struct lu_env *env,
        int index;
        ENTRY;
 
-       if (cl_io_is_trunc(io) && lio->lis_pos) {
+       if (cl_io_is_trunc(io) && lio->lis_pos > 0) {
                index = lov_lsm_entry(lsm, lio->lis_pos - 1);
                if (index > 0 && !lsm_entry_inited(lsm, index)) {
                        io->ci_need_write_intent = 1;
index f1c7f8f..ceb6245 100644 (file)
@@ -48,7 +48,7 @@ test_0() {
                error "Create $comp_file failed"
 
        #instantiate all components, so that objs are allocted
-       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=1k
+       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=2k
 
        local ost_idx1=$($LFS getstripe -I 1 -i $comp_file)
        local ost_idx2=$($LFS getstripe -I 2 -i $comp_file)
@@ -71,7 +71,7 @@ test_1() {
                error "Create $comp_file failed"
 
        #instantiate all components, so that objs are allocted
-       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=1k
+       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=2k
 
        local ost_idx1=$($LFS getstripe -I 1 -i $comp_file)
        local ost_idx2=$($LFS getstripe -I 2 -i $comp_file)
@@ -173,7 +173,7 @@ test_3() {
                error "Create second $comp_file failed"
 
        #instantiate all components, so that objs are allocted
-       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=16k
+       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=17k
 
        del_comp_and_verify $comp_file "init" 0 0
        rm -f $comp_file || error "Delete second $comp_file failed"
@@ -205,7 +205,7 @@ test_5() {
        [ $comp_cnt -ne 2 ] && error "file $comp_cnt != 2"
 
        #instantiate all components, so that objs are allocted
-       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=64k
+       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=65k
 
        local ost_idx=$($LFS getstripe -I 1 -i $comp_file)
        [ $ost_idx -ne 0 ] &&
@@ -346,7 +346,7 @@ test_9() {
        replay_barrier $SINGLEMDS
 
        # instantiate the 2nd component
-       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=1k
+       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=2k
 
        local f1=$($LFS getstripe -I 2 $comp_file |
                        awk '/l_fid:/ {print $7}')
@@ -451,8 +451,11 @@ test_11() {
        f4=$($LFS getstripe -I 4 $comp_file | grep "l_fid")
        [[ -n $f4 ]] && error "3: 4th component instantiated"
 
-       # all 4 components instantiated
-       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=3k
+       # all 4 components instantiated, using append write
+       dd if=/dev/zero of=$comp_file bs=1k count=1 seek=2k
+       ls -l $comp_file
+       rwv -f $comp_file -w -a -n 2 $((1024*1023)) 1
+       ls -l $comp_file
 
        f4=$($LFS getstripe -I 4 $comp_file | grep "l_fid")
        [[ -z $f4 ]] && error "4: 4th component uninstantiated"