Re: Minor Bug in 2.4.29 patchset and legacy SMP bug in 2.2.xx :)
Andreas Gruenbacher <[email protected]> Mon, 21 Feb 2005 17:49:23 +0100
| Newsgroups | gmane.linux.file-systems.acl.devel |
|---|---|
| Organization | SUSE Labs |
| Message-ID | <[email protected]> |
Hello Peter,
your bug report and analysis nicely explains the problems reported by
Robert and Thomas. Thanks a lot.
On Fri, 2005-02-18 at 08:51, Peter K. wrote:
> Hi! I'm working with your testing brunch of acl patch for 2.4.29
> kernel and there is some bug... I'm speaking english bad, but i'll
> trying to explain.
>
> Looking the case, when there is the xattrs on the file, but no "acl"
> attribute is set. So...first, at ext?_read_inode
>
> #ifdef CONFIG_EXT3_FS_POSIX_ACL
> if (inode->u.ext3_i.i_file_acl) {
> /* The filesystem is mounted with ACL support, and there
> are extended attributes for this inode. However we do
> not yet know whether there are actually any ACLs. */
> inode->u.ext3_i.i_acl = EXT3_ACL_NOT_CACHED;
> inode->u.ext3_i.i_default_acl = EXT3_ACL_NOT_CACHED;
> }
> #endif
>
> So, i_acl == i_default_acl == EXT3_ACL_NOT_CACHED couse i_file_acl is
> used for xattr layer and posix_acl is just it's subset.
>
> In ext3_permission ...
>
> if (ei->i_acl == EXT3_ACL_NOT_CACHED) {
> struct posix_acl *acl =
> ext3_get_acl(inode, ACL_TYPE_ACCESS);
>
> if (IS_ERR(acl))
> return PTR_ERR(acl);
> posix_acl_release(acl);
> if (ei->i_acl == EXT3_ACL_NOT_CACHED)
> return -EIO;
> }
>
> So, i_acl == ... CACHED, we will try to ext3_get_acl. and logically
> got -ENODATA inside ext3_get_acl, but in fact, the function returns 0
> outside in that case, so we got in the 3-d "if" and got -EIO (because
> i_acl is still NOT_CACHED).
>
> So, when we wants to get acces to the file, that have some xattr, but
> no acl xattr, we got -EIO error.
>
> It's seems like the problem is in
>
> if (retval <= 0) {
> if (retval == -ENODATA || retval == -ENOSYS)
> // { /* my dirty fix */
> // ei->i_acl = 0;
> // ei->i_default_acl = 0;
> retval = 0; /* original code */
> // }
> return ERR_PTR(retval);
>
>
> the past version of patch (2.4.25) was:
>
> if (retval > 0)
> acl = ext3_acl_from_disk(value, retval);
> else if (retval == -ENODATA || retval == -ENOSYS)
> acl = NULL;
>
> And we got dup acl from posix modes here, and it works.
Yes, that's much better. How do you like the attached patch? I have also
added it to the 2.4.29 testing snapshot.
> By the way. i have used your legacy patches for 2.2.xx kernels (about
> 2 years ago) and found there SMP sync. bug, thats leads sometimes to
> deadlocking (there was race cond. ) In fact, i have not my patch right
> here (on my machine where i am typing now) but if it's interesting
> (just for fun) i can remember it =).
Well, 2.2 is totally dead as far as those patches are concerned ;)
Cheers,
--
Andreas Gruenbacher <[email protected]>
SUSE Labs, SUSE LINUX GMBH
_______________________________________________
acl-devel mailing list
[email protected]
http://acl.bestbits.at/mailman/listinfo/acl-devel
acl-fix
(text/x-patch, 2 KB)
Index: linux-2.4.29/fs/ext2/acl.c
===================================================================
--- linux-2.4.29.orig/fs/ext2/acl.c
+++ linux-2.4.29/fs/ext2/acl.c
@@ -134,7 +134,7 @@ ext2_get_acl(struct inode *inode, int ty
struct ext2_inode_info *ei = EXT2_I(inode);
int name_index;
char *value;
- struct posix_acl *acl;
+ struct posix_acl *acl = NULL;
int retval;
if (!IS_POSIXACL(inode))
@@ -167,18 +167,20 @@ ext2_get_acl(struct inode *inode, int ty
kfree(value);
}
if (retval <= 0) {
+ acl = ERR_PTR(retval);
if (retval == -ENODATA || retval == -ENOSYS)
- retval = 0;
- return ERR_PTR(retval);
+ acl = NULL;
}
- switch(type) {
- case ACL_TYPE_ACCESS:
- ei->i_acl = posix_acl_dup(acl);
- break;
+ if (!IS_ERR(acl)) {
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ ei->i_acl = posix_acl_dup(acl);
+ break;
- case ACL_TYPE_DEFAULT:
- ei->i_default_acl = posix_acl_dup(acl);
- break;
+ case ACL_TYPE_DEFAULT:
+ ei->i_default_acl = posix_acl_dup(acl);
+ break;
+ }
}
return acl;
}
Index: linux-2.4.29/fs/ext3/acl.c
===================================================================
--- linux-2.4.29.orig/fs/ext3/acl.c
+++ linux-2.4.29/fs/ext3/acl.c
@@ -137,7 +137,7 @@ ext3_get_acl(struct inode *inode, int ty
struct ext3_inode_info *ei = EXT3_I(inode);
int name_index;
char *value;
- struct posix_acl *acl;
+ struct posix_acl *acl = NULL;
int retval;
if (!IS_POSIXACL(inode))
@@ -170,18 +170,20 @@ ext3_get_acl(struct inode *inode, int ty
kfree(value);
}
if (retval <= 0) {
+ acl = ERR_PTR(retval);
if (retval == -ENODATA || retval == -ENOSYS)
- retval = 0;
- return ERR_PTR(retval);
+ acl = NULL;
}
- switch(type) {
- case ACL_TYPE_ACCESS:
- ei->i_acl = posix_acl_dup(acl);
- break;
+ if (!IS_ERR(acl)) {
+ switch(type) {
+ case ACL_TYPE_ACCESS:
+ ei->i_acl = posix_acl_dup(acl);
+ break;
- case ACL_TYPE_DEFAULT:
- ei->i_default_acl = posix_acl_dup(acl);
- break;
+ case ACL_TYPE_DEFAULT:
+ ei->i_default_acl = posix_acl_dup(acl);
+ break;
+ }
}
return acl;
}