Latest working kernel version: haven't seen it working Earliest failing kernel version: 2.6.28-gentoo-r1 had the same issue Distribution: Gentoo Hardware Environment: SMP Sun Mar 1 14:15:44 EET 2009 i686 Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz GenuineIntel GNU/Linux Software Environment: Gentoo ~x86 Problem Description: From man attr_set: attr_set will fail if one or more of the following are true: [ENOATTR] The attribute name given is not associated with the indicated filesystem object and the ATTR_REPLACE flag bit was set. [E2BIG] The value of the given attribute is too large, it exceeds the maximum allowable size of an attribute value. This is what the test script gives for ext4: 3900 4000 4100 Traceback (most recent call last): File "test_xattr.py", line 10, in <module> xattr.set('/mnt/test/header.txt','user.test',s) IOError: [Errno 28] No space left on device This is what xfs gives: 65500 65600 Traceback (most recent call last): File "test_xattr.py", line 10, in <module> xattr.set('/mnt/test/header.txt','user.test',s) IOError: [Errno 7] Argument list too long >>> errno.errorcode[7] 'E2BIG' >>> errno.errorcode[28] 'ENOSPC' Steps to reproduce: betelgeuse@pena ~/python $ cat test_xattr.py import xattr hundred = '' for i in range(100): hundred+='a' s=hundred while True: print len(s) xattr.set('/mnt/test/header.txt','user.test',s) s+=hundred
The following patch fixes the issue. ====Patch starts iff -uNr linux-2.6.30.3-orig/fs/ext4/xattr.c linux-2.6.30.3-fix/fs/ext4/xattr.c --- linux-2.6.30.3-orig/fs/ext4/xattr.c 2009-07-25 03:17:51.000000000 +0530 +++ linux-2.6.30.3-fix/fs/ext4/xattr.c 2009-08-07 20:27:40.907412651 +0530 @@ -698,7 +698,7 @@ #define header(x) ((struct ext4_xattr_header *)(x)) if (i->value && i->value_len > sb->s_blocksize) - return -ENOSPC; + return -E2BIG; if (s->base) { ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev, bs->bh->b_blocknr); ====Patch ends Ran test_xattr.py on the kernel with above fix, it terminates with OSError 7.
I'm not convinced this change to use E2BIG instead of ENOSPC is always the right thing. Consider the wording of E2BIG: "The value of the given attribute is too large, IT EXCEEDS THE MAXIMUM ALLOWABLE SIZE OF AN ATTRIBUTE VALUE". In other words E2BIG implies that a request was made to create an attribute where the size exceeded some static value. So if we pass in a request to create an attribute which is 2MB, E2BIG makes sense. On the other hand, if the EA block is almost full, a request to create an attribute value which is 2 bytes long could result in an error --- and in that case, ENOSPC makes a lot more sense that E2BIG.