From 280746c37e3c5acf9922e6574123ff1b6945b8fb Mon Sep 17 00:00:00 2001
From: kalpak <kalpak>
Date: Thu, 15 May 2008 14:03:42 +0000
Subject: [PATCH] Description: MDS may lose file striping (and hence file data)
 in some cases   Details    : If there are additional extended attributes
 stored on the MDS,              in particular ACLs, SELinux, or user
 attributes (if user_xattr              is specified for the client mount
 options) then there is a risk              of attribute loss.  Additionally,
 the Lustre file striping              needs to be larger than default (e.g.
 striped over all OSTs),              and an additional attribute must be
 stored initially in the              inode and then increase in size enough
 to be moved to the              external attribute block (e.g. ACL growing in
 size) for file              data to be lost. i=adilger i=kalpak.shah (test by
 adilger) b=15777

---
 lustre/ChangeLog       | 14 ++++++++++++++
 lustre/tests/sanity.sh | 44 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 8132526489..36265d42cc 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -996,6 +996,20 @@ Severity   : normal
 Bugzilla   : 15212
 Description: Reinitialize optind to 0 so that interactive lfs works in all cases
 
+Severity   : critical
+Frequency  : very rare, if additional xattrs are used on kernels >= 2.6.12
+Bugzilla   : 15777
+Description: MDS may lose file striping (and hence file data) in some cases
+Details    : If there are additional extended attributes stored on the MDS,
+	     in particular ACLs, SELinux, or user attributes (if user_xattr
+	     is specified for the client mount options) then there is a risk
+	     of attribute loss.  Additionally, the Lustre file striping
+	     needs to be larger than default (e.g. striped over all OSTs),
+	     and an additional attribute must be stored initially in the
+	     inode and then increase in size enough to be moved to the
+	     external attribute block (e.g. ACL growing in size) for file
+	     data to be lost.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh
index 691e47fee3..b3099510fe 100644
--- a/lustre/tests/sanity.sh
+++ b/lustre/tests/sanity.sh
@@ -3874,6 +3874,50 @@ test_102g() {
 }
 run_test 102g "star copy files, keep osts ==========="
 
+test_102h() { # bug 15777
+	[ -z $(lctl get_param -n mdc.*.connect_flags | grep xattr) ] &&
+		skip "must have user_xattr" && return
+	[ -z "$(which setfattr 2>/dev/null)" ] &&
+		skip "could not find setfattr" && return
+
+	XBIG=trusted.big
+	XSIZE=1024
+	touch $DIR/$tfile
+	VALUE=datadatadatadatadatadatadatadata
+	while [ $(echo $VALUE | wc -c) -lt $XSIZE ]; do
+		VALUE="$VALUE$VALUE"
+	done
+	log "save $XBIG on $DIR/$tfile"
+        setfattr -n $XBIG -v "$VALUE" $DIR/$tfile ||
+		error "saving $XBIG on $DIR/$tfile failed"
+        ORIG=$(getfattr -n $XBIG $DIR/$tfile 2> /dev/null | grep $XBIG)
+	OSIZE=$(echo $ORIG | wc -c)
+	[ $OSIZE -lt $XSIZE ] && error "set $XBIG too small ($OSIZE < $XSIZE)"
+
+	XSML=trusted.sml
+	log "save $XSML on $DIR/$tfile"
+        setfattr -n $XSML -v val $DIR/$tfile ||
+		error "saving $XSML on $DIR/$tfile failed"
+        NEW=$(getfattr -n $XBIG $DIR/$tfile 2> /dev/null | grep $XBIG)
+	if [ "$NEW" != "$ORIG" ]; then
+		log "orig: $ORIG"
+		log "new: $NEW"
+		error "$XBIG different after saving $XSML"
+	fi
+
+	log "grow $XSML on $DIR/$tfile"
+        setfattr -n $XSML -v "$VALUE" $DIR/$tfile ||
+		error "growing $XSML on $DIR/$tfile failed"
+        NEW=$(getfattr -n $XBIG $DIR/$tfile 2> /dev/null | grep $XBIG)
+	if [ "$NEW" != "$ORIG" ]; then
+		log "orig: $ORIG"
+		log "new: $NEW"
+		error "$XBIG different after growing $XSML"
+	fi
+	log "$XBIG still valid after growing $XSML"
+}
+run_test 102h "grow xattr from inside inode to external block"
+
 run_acl_subtest()
 {
     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
-- 
GitLab