Whamcloud - gitweb
LU-7261 ldiskfs: fix large_xattr overwrite 77/16777/4
authorAlexey Lyashkov <alexey.lyashkov@seagate.com>
Fri, 9 Oct 2015 06:23:47 +0000 (00:23 -0600)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 21 Oct 2015 22:48:46 +0000 (22:48 +0000)
Handle the case where a large (external inode) xattr is being replaced
correctly.  The special case for this in ext4_set_xattr() was
incorrectly setting the offset of the xattr data within the inode
when it shouldn't have.

Add an e2fsck check of the large_xattr filesystem in conf-sanity
test_61 to verify this is working correctly.

Signed-off-by: Alexey Lyashkov <alexey.lyashkov@seagate.com>
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Change-Id: I27123d7985eff0538b6f64139cebc2f0f1806260
Reviewed-on: http://review.whamcloud.com/16777
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Jian Yu <jian.yu@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
ldiskfs/kernel_patches/patches/rhel6.3/ext4-large-eas.patch
ldiskfs/kernel_patches/patches/rhel7/ext4-large-eas.patch
ldiskfs/kernel_patches/patches/sles11sp2/ext4-large-eas.patch
ldiskfs/kernel_patches/patches/sles12/ext4-large-eas.patch
lustre/tests/conf-sanity.sh

index 5981307..142fec2 100644 (file)
@@ -471,13 +471,13 @@ Index: linux-stage/fs/ext4/xattr.c
                        void *first_val = s->base + min_offs;
                        size_t offs = le16_to_cpu(s->here->e_value_offs);
                        void *val = s->base + offs;
-@@ -606,13 +884,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i
+@@ -606,13 +884,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i
                        last = s->first;
                        while (!IS_LAST_ENTRY(last)) {
                                size_t o = le16_to_cpu(last->e_value_offs);
 -                              if (!last->e_value_block &&
--                                  last->e_value_size && o < offs)
-+                              if (last->e_value_size > 0 && o < offs)
++                              if (!last->e_value_inum &&
+                                   last->e_value_size && o < offs)
                                        last->e_value_offs =
                                                cpu_to_le16(o + size);
                                last = EXT4_XATTR_NEXT(last);
index 1fd34aa..b7251db 100644 (file)
@@ -568,13 +568,13 @@ Index: linux-stage/fs/ext4/xattr.c
                        void *first_val = s->base + min_offs;
                        size_t offs = le16_to_cpu(s->here->e_value_offs);
                        void *val = s->base + offs;
-@@ -685,13 +966,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i
+@@ -685,13 +966,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i
                        last = s->first;
                        while (!IS_LAST_ENTRY(last)) {
                                size_t o = le16_to_cpu(last->e_value_offs);
 -                              if (!last->e_value_block &&
--                                  last->e_value_size && o < offs)
-+                              if (last->e_value_size > 0 && o < offs)
++                              if (!last->e_value_inum &&
+                                   last->e_value_size && o < offs)
                                        last->e_value_offs =
                                                cpu_to_le16(o + size);
                                last = EXT4_XATTR_NEXT(last);
index 57e5f90..ba0e281 100644 (file)
@@ -575,13 +575,13 @@ Index: linux-stage/fs/ext4/xattr.c
                        void *first_val = s->base + min_offs;
                        size_t offs = le16_to_cpu(s->here->e_value_offs);
                        void *val = s->base + offs;
-@@ -607,13 +888,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i
+@@ -607,13 +888,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i
                        last = s->first;
                        while (!IS_LAST_ENTRY(last)) {
                                size_t o = le16_to_cpu(last->e_value_offs);
 -                              if (!last->e_value_block &&
--                                  last->e_value_size && o < offs)
-+                              if (last->e_value_size > 0 && o < offs)
++                              if (!last->e_value_inum &&
+                                   last->e_value_size && o < offs)
                                        last->e_value_offs =
                                                cpu_to_le16(o + size);
                                last = EXT4_XATTR_NEXT(last);
index d596093..8ff7f93 100644 (file)
@@ -558,13 +558,13 @@ Index: linux-stage/fs/ext4/xattr.c
                        void *first_val = s->base + min_offs;
                        size_t offs = le16_to_cpu(s->here->e_value_offs);
                        void *val = s->base + offs;
-@@ -680,13 +958,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i
+@@ -680,13 +958,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i
                        last = s->first;
                        while (!IS_LAST_ENTRY(last)) {
                                size_t o = le16_to_cpu(last->e_value_offs);
 -                              if (!last->e_value_block &&
--                                  last->e_value_size && o < offs)
-+                              if (last->e_value_size > 0 && o < offs)
++                              if (!last->e_value_inum &&
+                                   last->e_value_size && o < offs)
                                        last->e_value_offs =
                                                cpu_to_le16(o + size);
                                last = EXT4_XATTR_NEXT(last);
index eeef083..492a32f 100644 (file)
@@ -4108,42 +4108,53 @@ test_61() { # LU-80
        local large_value="$(generate_string $(max_xattr_size))"
        local small_value="bar"
 
-    local name="trusted.big"
-    log "save large xattr $name on $file"
-    setfattr -n $name -v $large_value $file ||
-        error "saving $name on $file failed"
-
-    local new_value=$(get_xattr_value $name $file)
-    [[ "$new_value" != "$large_value" ]] &&
-        error "$name different after saving"
-
-    log "shrink value of $name on $file"
-    setfattr -n $name -v $small_value $file ||
-        error "shrinking value of $name on $file failed"
-
-    new_value=$(get_xattr_value $name $file)
-    [[ "$new_value" != "$small_value" ]] &&
-        error "$name different after shrinking"
-
-    log "grow value of $name on $file"
-    setfattr -n $name -v $large_value $file ||
-        error "growing value of $name on $file failed"
-
-    new_value=$(get_xattr_value $name $file)
-    [[ "$new_value" != "$large_value" ]] &&
-        error "$name different after growing"
-
-    log "check value of $name on $file after remounting MDS"
-    fail $SINGLEMDS
-    new_value=$(get_xattr_value $name $file)
-    [[ "$new_value" != "$large_value" ]] &&
-        error "$name different after remounting MDS"
-
-    log "remove large xattr $name from $file"
-    setfattr -x $name $file || error "removing $name from $file failed"
-
-    rm -f $file
-    stopall
+       local name="trusted.big"
+       log "save large xattr $name on $file"
+       setfattr -n $name -v $large_value $file ||
+               error "saving $name on $file failed"
+
+       local new_value=$(get_xattr_value $name $file)
+       [[ "$new_value" != "$large_value" ]] &&
+               error "$name different after saving"
+
+       log "shrink value of $name on $file"
+       setfattr -n $name -v $small_value $file ||
+               error "shrinking value of $name on $file failed"
+
+       new_value=$(get_xattr_value $name $file)
+       [[ "$new_value" != "$small_value" ]] &&
+               error "$name different after shrinking"
+
+       log "grow value of $name on $file"
+       setfattr -n $name -v $large_value $file ||
+               error "growing value of $name on $file failed"
+
+       new_value=$(get_xattr_value $name $file)
+       [[ "$new_value" != "$large_value" ]] &&
+               error "$name different after growing"
+
+       log "check value of $name on $file after remounting MDS"
+       fail $SINGLEMDS
+       new_value=$(get_xattr_value $name $file)
+       [[ "$new_value" != "$large_value" ]] &&
+               error "$name different after remounting MDS"
+
+       log "remove large xattr $name from $file"
+       setfattr -x $name $file || error "removing $name from $file failed"
+
+       if $lxattr; then
+               stopall || error "stopping for e2fsck run"
+               for num in $(seq $MDSCOUNT); do
+                       run_e2fsck $(facet_active_host mds$num) \
+                               $(mdsdevname $num) "-y" ||
+                               error "e2fsck MDT$num failed"
+               done
+               setup_noconfig || error "remounting the filesystem failed"
+       fi
+
+       # need to delete this file to avoid problems in other tests
+       rm -f $file
+       stopall || error "stopping systems to turn off large_xattr"
        if $lxattr; then
                for num in $(seq $MDSCOUNT); do
                        do_facet mds${num} $TUNE2FS -O ^large_xattr \