1
0
mirror of https://git.yoctoproject.org/poky synced 2026-06-01 13:09:50 +00:00

e2fsprogs: Update to upstream version of a patch

Switch to the upstream version of the xattr patch.

(From OE-Core rev: 631217cc3cb15a7ec4f3cdf6e8d1ff67de2a72b3)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2016-02-14 14:34:20 +00:00
parent 5394ada142
commit 120a1605eb
@@ -1,66 +1,219 @@
[Message sent to linux-ext4 on 2016/2/7] From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: tytso@mit.edu, darrick.wong@oracle.com
Cc: linux-ext4@vger.kernel.org, Darren Hart <dvhart@linux.intel.com>,
Richard Purdie <richard.purdie@linuxfoundation.org>
Date: Sat, 13 Feb 2016 14:38:24 -0800
Message-ID: <20160213223824.25381.8002.stgit@birch.djwong.org>
In-Reply-To: <20160213223725.25381.20929.stgit@birch.djwong.org>
References: <20160213223725.25381.20929.stgit@birch.djwong.org>
User-Agent: StGit/0.17.1-dirty
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
X-Source-IP: aserv0022.oracle.com [141.146.126.234]
X-Evolution-Source: 1358860361.4566.33@ted
Content-Transfer-Encoding: 8bit
I'm using the -d option of mke2fs to construct a filesystem, I'm seeing Richard Purdie reports that libext2fs doesn't sort attribute keys in
that some xattrs are being corrupted. The filesystem builds with no the xattr block correctly, causing the kernel to return -ENODATA when
errors but when mounted by the kernel, I see errors like "security.ima: querying attributes that should be there. Therefore, sort attributes
No such attribute". The strace from such a failure is: so that whatever ends up in the xattr block is sorted according to
what the kernel expects.
mmap(NULL, 26258, PROT_READ, MAP_SHARED, 3, 0) = 0x7fdb36a8c000 Cc: Darren Hart <dvhart@linux.intel.com>
close(3) = 0 Reported-by: Richard Purdie <richard.purdie@linuxfoundation.org>
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=64*1024}) = 0 Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
lstat("mnt/foobar", {st_mode=S_IFREG|0755, st_size=1, ...}) = 0 ---
listxattr("mnt/foobar", NULL, 0) = 30 lib/ext2fs/ext_attr.c | 24 +++++++++++-
listxattr("mnt/foobar", "security.SMACK64\0security.ima\0", 256) = 30 tests/d_xattr_sorting/expect | 29 ++++++++++++++
getxattr("mnt/foobar", "security.SMACK64", 0x0, 0) = 1 tests/d_xattr_sorting/name | 1
getxattr("mnt/foobar", "security.SMACK64", "_", 256) = 1 tests/d_xattr_sorting/script | 86 ++++++++++++++++++++++++++++++++++++++++++
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 13), ...}) = 0 4 files changed, 139 insertions(+), 1 deletion(-)
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdb36a8b000 create mode 100644 tests/d_xattr_sorting/expect
write(1, "# file: mnt/foobar\n", 19# file: mnt/foobar) = 19 create mode 100644 tests/d_xattr_sorting/name
write(1, "security.SMACK64=\"_\"\n", 21security.SMACK64="_") = 21 create mode 100644 tests/d_xattr_sorting/script
getxattr("mnt/foobar", "security.ima", 0x0, 0) = -1 ENODATA (No data available)
write(2, "mnt/foobar: ", 12mnt/foobar: ) = 12
write(2, "security.ima: No such attribute\n", 32security.ima: No such attribute) = 32= 32
so the attribute is there but the kernel gives ENODATA when trying
to read it.
http://www.nongnu.org/ext2-doc/ext2.html#CONTRIB-EXTENDED-ATTRIBUTES co
ntains the small snippet that " The entry descriptors are sorted by
attribute name, so that two extended attribute blocks can be compared
efficiently. ". It doesn't specify what kind of sort.
Looking at ext2fs, there is some sorting code through the qsort call
using attr_compare() but it doesn't match what the kernel is doing in
ext4_xattr_find_entry().
This patch fixes the problem.
Upstream-Status: Submitted Upstream-Status: Submitted
RP
2016/2/7
Index: git/lib/ext2fs/ext_attr.c
=================================================================== diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c
--- git.orig/lib/ext2fs/ext_attr.c index 0a4f8c0..b121837 100644
+++ git/lib/ext2fs/ext_attr.c --- a/lib/ext2fs/ext_attr.c
@@ -258,6 +258,7 @@ static struct ea_name_index ea_names[] = +++ b/lib/ext2fs/ext_attr.c
@@ -254,10 +254,15 @@ static struct ea_name_index ea_names[] = {
{0, NULL},
};
+static int find_ea_index(char *fullname, char **name, int *index);
+
/* Push empty attributes to the end and inlinedata to the front. */
static int attr_compare(const void *a, const void *b) static int attr_compare(const void *a, const void *b)
{ {
const struct ext2_xattr *xa = a, *xb = b; const struct ext2_xattr *xa = a, *xb = b;
+ size_t len; + char *xa_suffix, *xb_suffix;
+ int xa_idx, xb_idx;
+ int cmp;
if (xa->name == NULL) if (xa->name == NULL)
return +1; return +1;
@@ -267,7 +268,11 @@ static int attr_compare(const void *a, c @@ -267,7 +272,24 @@ static int attr_compare(const void *a, const void *b)
return -1; return -1;
else if (!strcmp(xb->name, "system.data")) else if (!strcmp(xb->name, "system.data"))
return +1; return +1;
- return 0; - return 0;
+ len = strlen(xa->name) - strlen(xb->name);
+ if (len)
+ return len;
+ +
+ return strcmp(xa->name, xb->name); + /*
+ * Duplicate the kernel's sorting algorithm because xattr blocks
+ * require sorted keys.
+ */
+ xa_suffix = xa->name;
+ xb_suffix = xb->name;
+ xa_idx = xb_idx = 0;
+ find_ea_index(xa->name, &xa_suffix, &xa_idx);
+ find_ea_index(xb->name, &xb_suffix, &xb_idx);
+ cmp = xa_idx - xb_idx;
+ if (cmp)
+ return cmp;
+ cmp = strlen(xa_suffix) - strlen(xb_suffix);
+ if (cmp)
+ return cmp;
+ cmp = strcmp(xa_suffix, xb_suffix);
+ return cmp;
} }
static const char *find_ea_prefix(int index) static const char *find_ea_prefix(int index)
diff --git a/tests/d_xattr_sorting/expect b/tests/d_xattr_sorting/expect
new file mode 100644
index 0000000..17da663
--- /dev/null
+++ b/tests/d_xattr_sorting/expect
@@ -0,0 +1,29 @@
+debugfs sort extended attributes
+mke2fs -Fq -b 1024 test.img 512
+Exit status is 0
+ea_set / security.SMEG64 -f /tmp/b
+Exit status is 0
+ea_set / security.imb -f /tmp/b
+Exit status is 0
+ea_set / user.moo cow
+Exit status is 0
+ea_list /
+Extended attributes:
+ user.moo = "cow" (3)
+ security.imb = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" (256)
+ security.SMEG64 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" (256)
+Exit status is 0
+ea_get / security.imb
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Exit status is 0
+ea_get / nosuchea
+ea_get: Extended attribute key not found while getting extended attribute
+Exit status is 0
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/64 files (0.0% non-contiguous), 29/512 blocks
+Exit status is 0
diff --git a/tests/d_xattr_sorting/name b/tests/d_xattr_sorting/name
new file mode 100644
index 0000000..dde8926
--- /dev/null
+++ b/tests/d_xattr_sorting/name
@@ -0,0 +1 @@
+sort extended attributes in debugfs
diff --git a/tests/d_xattr_sorting/script b/tests/d_xattr_sorting/script
new file mode 100644
index 0000000..30c189a
--- /dev/null
+++ b/tests/d_xattr_sorting/script
@@ -0,0 +1,86 @@
+if test -x $DEBUGFS_EXE; then
+
+OUT=$test_name.log
+EXP=$test_dir/expect
+VERIFY_FSCK_OPT=-yf
+
+TEST_DATA=$test_name.tmp
+VERIFY_DATA=$test_name.ver.tmp
+
+echo "debugfs sort extended attributes" > $OUT
+
+dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1
+
+echo "mke2fs -Fq -b 1024 test.img 512" >> $OUT
+
+$MKE2FS -Fq $TMPFILE 512 > /dev/null 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+perl -e 'print "x" x 256;' > /tmp/b
+
+echo "ea_set / security.SMEG64 -f /tmp/b" > $OUT.new
+$DEBUGFS -w -R "ea_set / security.SMEG64 -f /tmp/b" $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+echo "ea_set / security.imb -f /tmp/b" > $OUT.new
+$DEBUGFS -w -R "ea_set / security.imb -f /tmp/b" $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+echo "ea_set / user.moo cow" > $OUT.new
+$DEBUGFS -w -R "ea_set / user.moo cow" $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+rm -rf /tmp/b
+
+echo "ea_list /" > $OUT.new
+$DEBUGFS -w -R "ea_list /" $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+echo "ea_get / security.imb" > $OUT.new
+$DEBUGFS -w -R "ea_get / security.imb" $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+echo "ea_get / nosuchea" > $OUT.new
+$DEBUGFS -w -R "ea_get / nosuchea" $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
+
+#
+# Do the verification
+#
+
+rm -f $TMPFILE $OUT.new
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset VERIFY_FSCK_OPT NATIVE_FSCK_OPT OUT EXP TEST_DATA VERIFY_DATA
+
+else #if test -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi