Commit 73769d9b authored by Paul Menage's avatar Paul Menage Committed by Linus Torvalds

[PATCH] Push BKL into ->permission() calls

This patch (against 2.5.22) removes the BKL from around the call
to i_op->permission() in fs/namei.c, and pushes the BKL into those
filesystems that have permission() methods that require it.
parent 67aa3988
......@@ -50,27 +50,27 @@ prototypes:
int (*removexattr) (struct dentry *, const char *);
locking rules:
all may block
BKL i_sem(inode)
lookup: no yes
create: no yes
link: no yes (both)
mknod: no yes
symlink: no yes
mkdir: no yes
unlink: no yes (both)
rmdir: no yes (both) (see below)
rename: no yes (all) (see below)
readlink: no no
follow_link: no no
truncate: no yes (see below)
setattr: no yes
permission: yes no
getattr: no no
setxattr: no yes
getxattr: no yes
listxattr: no yes
removexattr: no yes
all may block, none have BKL
i_sem(inode)
lookup: yes
create: yes
link: yes (both)
mknod: yes
symlink: yes
mkdir: yes
unlink: yes (both)
rmdir: yes (both) (see below)
rename: yes (all) (see below)
readlink: no
follow_link: no
truncate: yes (see below)
setattr: yes
permission: no
getattr: no
setxattr: yes
getxattr: yes
listxattr: yes
removexattr: yes
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_sem on
victim.
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
......
......@@ -81,9 +81,9 @@ can relax your locking.
[mandatory]
->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod(), ->mkdir(),
->rmdir(), ->link(), ->lseek(), ->symlink(), ->rename() and ->readdir()
are called without BKL now. Grab it on the entry, drop upon return - that
will guarantee the same locking you used to have. If your method or its
->rmdir(), ->link(), ->lseek(), ->symlink(), ->rename(), ->permission()
and ->readdir() are called without BKL now. Grab it on entry, drop upon return
- that will guarantee the same locking you used to have. If your method or its
parts do not need BKL - better yet, now you can shift lock_kernel() and
unlock_kernel() so that they would protect exactly what needs to be
protected.
......
......@@ -147,21 +147,26 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
int coda_permission(struct inode *inode, int mask)
{
int error;
int error = 0;
if (!mask)
return 0;
lock_kernel();
coda_vfs_stat.permission++;
if (coda_cache_check(inode, mask))
return 0;
goto out;
error = venus_access(inode->i_sb, coda_i2f(inode), mask);
if (!error)
coda_cache_enter(inode, mask);
out:
unlock_kernel();
return error;
}
......
......@@ -785,13 +785,15 @@ int presto_permission(struct inode *inode, int mask)
{
unsigned short mode = inode->i_mode;
struct presto_cache *cache;
int rc;
int rc = 0;
lock_kernel();
ENTRY;
if ( presto_can_ilookup() && !(mask & S_IWOTH)) {
CDEBUG(D_CACHE, "ilookup on %ld OK\n", inode->i_ino);
EXIT;
return 0;
EXIT;
goto out;
}
cache = presto_get_cache(inode);
......@@ -803,25 +805,22 @@ int presto_permission(struct inode *inode, int mask)
if ( S_ISREG(mode) && fiops && fiops->permission ) {
EXIT;
return fiops->permission(inode, mask);
rc = fiops->permission(inode, mask);
goto out;
}
if ( S_ISDIR(mode) && diops && diops->permission ) {
EXIT;
return diops->permission(inode, mask);
rc = diops->permission(inode, mask);
goto out;
}
}
/* The cache filesystem doesn't have its own permission function,
* but we don't want to duplicate the VFS code here. In order
* to avoid looping from permission calling this function again,
* we temporarily override the permission operation while we call
* the VFS permission function.
*/
inode->i_op->permission = NULL;
rc = permission(inode, mask);
inode->i_op->permission = &presto_permission;
rc = vfs_permission(inode, mask);
EXIT;
out:
unlock_kernel();
return rc;
}
......
......@@ -204,13 +204,8 @@ int vfs_permission(struct inode * inode, int mask)
int permission(struct inode * inode,int mask)
{
if (inode->i_op && inode->i_op->permission) {
int retval;
lock_kernel();
retval = inode->i_op->permission(inode, mask);
unlock_kernel();
return retval;
}
if (inode->i_op && inode->i_op->permission)
return inode->i_op->permission(inode, mask);
return vfs_permission(inode, mask);
}
......
......@@ -1123,6 +1123,8 @@ nfs_permission(struct inode *inode, int mask)
&& error != -EACCES)
goto out;
lock_kernel();
error = NFS_PROTO(inode)->access(inode, mask, 0);
if (error == -EACCES && NFS_CLIENT(inode)->cl_droppriv &&
......@@ -1130,6 +1132,8 @@ nfs_permission(struct inode *inode, int mask)
(current->fsuid != current->uid || current->fsgid != current->gid))
error = NFS_PROTO(inode)->access(inode, mask, 1);
unlock_kernel();
out:
return error;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment