Skip to contentSkip to conversation

SIGSEGV with 'cp -a'

DISCUSSION Alexander Clouter 1 participant 1 message May 23, 2011 1 message not in the archive

lore
Share & tools
lore
#1 lore raw
In reply to a message not in the archive

Hi,

I *think* it all boils down to XFS[1] being bad and it should be returning ENOATTR rather than EINVAL for unknown xattr names; according to the getxattr() manpage.

The previous patch just plasters over the problem (as we should never be getting to acl_ptn4_acl_trans() on an XFS filesystem). The result is that you see the ACL's on a NFSv4 mount, but local filesystems they are invisible.

The attached patch fixes things (hopefully) properly.

Cheers

[1] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=fs/xfs/xfs_attr.c#l87

Quoted 35 lines · Alexander Clouter

Unsure if you are interested, as it really looks like your nfs4 libacl patches[1] are no longer being maintained, but after moving my Debian installation from lenny to squeeze I got segfaults when copying files:
----
Program received signal SIGSEGV, Segmentation fault. acl_ptn4_acl_trans (pacl=0x8062f8c, acl=0x0, type=32768, is_dir=1,

    nfs_domain=0xbffff108 "elar.soas.ac.uk") at acl_ptn4_acl_trans.c:109
109             purge_aces(acl, type);
(gdb) where
#0  acl_ptn4_acl_trans (pacl=0x8062f8c, acl=0x0, type=32768, is_dir=1,
    nfs_domain=0xbffff108 "elar.soas.ac.uk") at acl_ptn4_acl_trans.c:109
#1  0xb7fac969 in acl_set_file (path_p=0x8062d20 "moo/private", 
type=32768, acl=0x8062f8c)
    at acl_set_file.c:114

[snipped]
----

Seems to come about as getxattr("system.nfs4_acl") on an XFS filesystem pops back with (iirc) EINVAL which trickles into libacl as NULL in acl when being passed to purge_aces().

Obvious fix is to drop in a quick check for NULL, as done in the attached patch. Would be great if you could could commit this to your dusty git tree, spit out a new patch and tell us all to "get with the program and use richacls" ;)

Having 'native' ACLs with NFSv4 has helped me no end, so my thanks to you (and any other contributors).

Cheers

[1] http://www.citi.umich.edu/projects/nfsv4/linux/
[2] I'm using the Debian acl/libacl 2.2.49-4 package with

	acl-2.2.42-CITI_NFS4_ALL-2.diff applied
Signature · 3 lines
Alexander Clouter
.sigmonster says: problem drinker, n.:
                  	A man who never buys.
debian/changelog +18 -0
diff -u -r acl-2.2.49.orig/debian/changelog acl-2.2.49/debian/changelog
@@ -1,3 +1,21 @@
+acl (2.2.49-4.nfsv4-3) unstable; urgency=low
+
+  * Handle that XFS comes back with EINVAL for xattr ops
+
+ -- Alexander Clouter <[email protected]>  Fri,  6 May 2011 23:36:00 +0100
+
+acl (2.2.49-4.nfsv4-2) unstable; urgency=low
+
+  * Fix a nfsv4->posix mapping problem that gave groups spurious bits
+
+ -- J. Bruce Fields <[email protected]>  Mon,  5 Nov 2007 18:49:20 -0500
+
+acl (2.2.49-4.nfsv4-1) unstable; urgency=low
+
+  * Add support for NFSv4 ACLs
+
+ -- J. Bruce Fields <[email protected]>  Fri, 02 Sep 2006 00:22:07 -0400
+
 acl (2.2.49-4) unstable; urgency=low
 
   * Migrate to having binaries in sbindir (closes: #590240)
libacl/acl_extended_file.c +1 -1
diff -u -r acl-2.2.49.orig/libacl/acl_extended_file.c acl-2.2.49/libacl/acl_extended_file.c
@@ -40,7 +40,7 @@
 	 * NFS4 stuff that's going on.  We need a cleaner separation. */
 #ifdef USE_NFSV4_TRANS
 	retval = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0);
-	if (retval < 0 && errno != ENOATTR && errno != EOPNOTSUPP)
+	if (retval < 0 && errno != ENOATTR && errno != EOPNOTSUPP && errno != EINVAL)
 		return -1;
 	if (retval >= 0) {
 		struct nfs4_acl *nfsacl;
libacl/acl_get_fd.c +1 -1
diff -u -r acl-2.2.49.orig/libacl/acl_get_fd.c acl-2.2.49/libacl/acl_get_fd.c
@@ -51,7 +51,7 @@
 
 #ifdef USE_NFSV4_TRANS
 	retval = fgetxattr(fd, ACL_NFS4_XATTR, ext_acl_p, size_guess);
-	if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) {
+	if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP || errno == EINVAL)) {
 		nfsv4acls = ACL_NFS4_NOT_USED;
 		retval = fgetxattr(fd, name, ext_acl_p, size_guess);
 	} else {
libacl/acl_get_file.c +1 -1
diff -u -r acl-2.2.49.orig/libacl/acl_get_file.c acl-2.2.49/libacl/acl_get_file.c
@@ -63,7 +63,7 @@
 		return NULL;
 #ifdef USE_NFSV4_TRANS
 	retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, size_guess);
-	if((retval == -1) && (errno == ENOATTR || errno == EOPNOTSUPP)) {
+	if((retval == -1) && (errno == ENOATTR || errno == EOPNOTSUPP || errno == EINVAL)) {
 		nfsv4acls = ACL_NFS4_NOT_USED;
 		retval = getxattr(path_p, name, ext_acl_p, size_guess);
 	} else {
libacl/acl_set_fd.c +1 -1
diff -u -r acl-2.2.49.orig/libacl/acl_set_fd.c acl-2.2.49/libacl/acl_set_fd.c
@@ -53,7 +53,7 @@
 #ifdef USE_NFSV4_TRANS
 	retval = fgetxattr(fd, ACL_NFS4_XATTR, NULL, 0);
 
-	if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) {
+	if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP || errno == EINVAL)) {
 		ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
 	} else {
 		char domain[NFS4_MAX_DOMAIN_LEN];
libacl/acl_set_file.c +1 -1
diff -u -r acl-2.2.49.orig/libacl/acl_set_file.c acl-2.2.49/libacl/acl_set_file.c
@@ -100,7 +100,7 @@
 		return -1;
 	}
 	nacl = get_nfs4_acl(path_p, is_dir);
-	if (nacl == NULL && (errno == ENOATTR || errno == EOPNOTSUPP))
+	if (nacl == NULL && (errno == ENOATTR || errno == EOPNOTSUPP || errno == EINVAL))
 		ext_acl_p = __acl_to_xattr(acl_obj_p, &size);
 	else {
 		char domain[NFS4_MAX_DOMAIN_LEN];

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs