* another bug report (thread)
http://thread.gmane.org/gmane.comp.shells.dash/36/focus=37
* another nice conversation with kernel hackers
http://thread.gmane.org/gmane.linux.file-systems/23151/focus=23160
the most simple shell `test` tool fail, yet they discuss case-insensitive renames, oh gee. Code part is raceless stripped linux-2.6/fs/open.c:sys_faccessat():
asmlinkage long sys_feuidaccessat(int dfd, const char __user *filename, int mode)
{
struct nameidata nd;
int res;
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
return -EINVAL;
res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
if (res)
goto out;
res = vfs_permission(&nd, mode);
/* SuS v2 requires we report a read only fs too */
if(res || !(mode & S_IWOTH) ||
special_file(nd.dentry->d_inode->i_mode))
goto out_path_release;
if(IS_RDONLY(nd.dentry->d_inode))
res = -EROFS;
out_path_release:
path_release(&nd);
out:
return res;
}
And if we excpect non-error part to be likely, and we don't generally like goto in basic stuff, and we don't want to use unlikely_buggy(optimizing) gcc:
asmlinkage long sys_feuidaccessat(int dfd, const char __user *filename, int mode)
{
struct nameidata nd;
int res;
/* where's F_OK, X_OK, W_OK, R_OK? */
if (!(mode & ~S_IRWXO)) {
/* here */
res = __user_walk_fd(dfd, filename,
LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
if (!res) {
res = vfs_permission(&nd, mode);
/* SuS v2 requires we report a read only fs too */
if (res || !(mode & S_IWOTH) ||
special_file(nd.dentry->d_inode->i_mode))
{} else if (IS_RDONLY(nd.dentry->d_inode))
res = -EROFS;
path_release(&nd);
}
return res;
}
return -EINVAL;
}
Simple, isn't it?
____