Commit 6a6d70cf authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] BKL shifted into ->lookup()

	OK, here comes: ->lookup() had lost BKL, all in-tree instances of
->lookup() converted.

	I'm adding Documentation/filesystems/porting - with the list of
API changes since 2.4.  Are you OK with that format?

(and yes, this sucker is *post*-compile ;-)
parent 0e44d4c5
...@@ -49,7 +49,7 @@ prototypes: ...@@ -49,7 +49,7 @@ prototypes:
locking rules: locking rules:
all may block all may block
BKL i_sem(inode) BKL i_sem(inode)
lookup: yes yes lookup: no yes
create: yes yes create: yes yes
link: yes yes link: yes yes
mknod: yes yes mknod: yes yes
......
Changes since 2.5.0:
---
[recommeneded]
New helpers: sb_bread(), sb_getblk(), sb_get_hash_table(), set_bh(),
sb_set_blocksize() and sb_min_blocksize().
Use them.
---
[recommeneded]
New methods: ->alloc_inode() and ->destroy_inode().
Remove inode->u.foo_inode_i
Declare
struct foo_inode_info {
/* fs-private stuff */
struct inode vfs_inode;
};
static inline FOO_I(struct inode *inode)
{
return list_entry(inode, struct foo_inode_info, vfs_inode);
}
Use FOO_I(inode) instead of &inode->u.foo_inode_i;
Add foo_alloc_inode() and foo_destory_inode() - the former should allocate
foo_inode_info and return the address of ->vfs_inode, the latter should free
FOO_I(inode) (see in-tree filesystems for examples).
Make them ->alloc_inode and ->destroy_inode in your super_operations.
Keep in mind that now you need explicit initialization of private data -
typically in ->read_inode() and after getting an inode from new_inode().
At some point that will become mandatory.
---
[mandatory]
Change of file_system_type method (->read_super to ->get_sb)
->read_super() is no more. Ditto for DECLARE_FSTYPE and DECLARE_FSTYPE_DEV.
Turn your foo_read_super() into a function that would return 0 in case of
success and negative number in case of error (-EINVAL unless you have more
informative error value to report). Call it foo_fill_super(). Now declare
struct super_block foo_get_sb(struct file_system_type *fs_type,
int flags, char *dev_name, void *data)
{
return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
}
(or similar with s/bdev/nodev/ or s/bdev/single/, depending on the kind of
filesystem).
Replace DECLARE_FSTYPE... with explicit initializer and have ->get_sb set as
foo_get_sb.
---
[mandatory]
Locking change: ->s_vfs_rename_sem is taken only by cross-directory renames.
Most likely there is no need to change anything, but if you relied on
global exclusion between renames for some internal purpose - you need to
change your internal locking. Otherwise exclusion warranties remain the
same (i.e. parents are victim are locked, etc.).
---
[informational]
Now we have the exclusion between ->lookup() and directory removal (by
->rmdir() and ->rename()). If you used to need that exclusion and do
it by internal locking (most of filesystems couldn't care less) - you
can relax your locking.
---
[mandatory]
->lookup() is called without BKL now. Grab it on the entry, drop upon return
- that will guarantee the same locking you used to have. If your ->lookup()
or its parts do not need BKL - better yet, now you can shift lock_kernel()/
unlock_kernel() so that they would protect exactly what needs to be protected.
...@@ -94,6 +94,7 @@ static int pcihpfs_statfs (struct super_block *sb, struct statfs *buf) ...@@ -94,6 +94,7 @@ static int pcihpfs_statfs (struct super_block *sb, struct statfs *buf)
return 0; return 0;
} }
/* SMP-safe */
static struct dentry *pcihpfs_lookup (struct inode *dir, struct dentry *dentry) static struct dentry *pcihpfs_lookup (struct inode *dir, struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/major.h> #include <linux/major.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/smp_lock.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -170,10 +171,12 @@ static struct dentry *capifs_root_lookup(struct inode * dir, struct dentry * den ...@@ -170,10 +171,12 @@ static struct dentry *capifs_root_lookup(struct inode * dir, struct dentry * den
if (tmp == p || *tmp) if (tmp == p || *tmp)
return NULL; return NULL;
lock_kernel();
for (i = 0, np = sbi->nccis ; i < sbi->max_ncci; i++, np++) { for (i = 0, np = sbi->nccis ; i < sbi->max_ncci; i++, np++) {
if (np->used && np->num == num && np->type == type) if (np->used && np->num == num && np->type == type)
break; break;
} }
unlock_kernel();
if ( i >= sbi->max_ncci ) if ( i >= sbi->max_ncci )
return NULL; return NULL;
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h>
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
#include <linux/kmod.h> #include <linux/kmod.h>
...@@ -928,6 +929,7 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry) ...@@ -928,6 +929,7 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry)
struct proc_dir_entry *de; struct proc_dir_entry *de;
struct inode *inode = NULL; struct inode *inode = NULL;
lock_kernel();
if ((de = PDE(dir)) != NULL) { if ((de = PDE(dir)) != NULL) {
for (de = de->subdir ; de ; de = de->next) { for (de = de->subdir ; de ; de = de->next) {
if ((de && de->low_ino) && if ((de && de->low_ino) &&
...@@ -937,12 +939,14 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry) ...@@ -937,12 +939,14 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry)
if ((inode = proc_get_inode(dir->i_sb, if ((inode = proc_get_inode(dir->i_sb,
de->low_ino, de)) == NULL) { de->low_ino, de)) == NULL) {
printk(KERN_ERR "COMX: lookup error\n"); printk(KERN_ERR "COMX: lookup error\n");
unlock_kernel();
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
break; break;
} }
} }
} }
unlock_kernel();
dentry->d_op = &comx_dentry_operations; dentry->d_op = &comx_dentry_operations;
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
......
...@@ -142,6 +142,7 @@ static int parse_options(struct super_block *s, char *data) ...@@ -142,6 +142,7 @@ static int parse_options(struct super_block *s, char *data)
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* SMP-safe */
static struct dentry *usbfs_lookup (struct inode *dir, struct dentry *dentry) static struct dentry *usbfs_lookup (struct inode *dir, struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include "adfs.h" #include "adfs.h"
...@@ -271,6 +272,7 @@ struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -271,6 +272,7 @@ struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry)
int error; int error;
dentry->d_op = &adfs_dentry_operations; dentry->d_op = &adfs_dentry_operations;
lock_kernel();
error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj); error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj);
if (error == 0) { if (error == 0) {
error = -EACCES; error = -EACCES;
...@@ -282,6 +284,7 @@ struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -282,6 +284,7 @@ struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry)
if (inode) if (inode)
error = 0; error = 0;
} }
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return ERR_PTR(error); return ERR_PTR(error);
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/amigaffs.h> #include <linux/amigaffs.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -217,11 +218,14 @@ affs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -217,11 +218,14 @@ affs_lookup(struct inode *dir, struct dentry *dentry)
pr_debug("AFFS: lookup(\"%.*s\")\n",(int)dentry->d_name.len,dentry->d_name.name); pr_debug("AFFS: lookup(\"%.*s\")\n",(int)dentry->d_name.len,dentry->d_name.name);
lock_kernel();
affs_lock_dir(dir); affs_lock_dir(dir);
bh = affs_find_entry(dir, dentry); bh = affs_find_entry(dir, dentry);
affs_unlock_dir(dir); affs_unlock_dir(dir);
if (IS_ERR(bh)) if (IS_ERR(bh)) {
unlock_kernel();
return ERR_PTR(PTR_ERR(bh)); return ERR_PTR(PTR_ERR(bh));
}
if (bh) { if (bh) {
u32 ino = bh->b_blocknr; u32 ino = bh->b_blocknr;
...@@ -235,10 +239,13 @@ affs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -235,10 +239,13 @@ affs_lookup(struct inode *dir, struct dentry *dentry)
} }
affs_brelse(bh); affs_brelse(bh);
inode = iget(sb, ino); inode = iget(sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
dentry->d_op = AFFS_SB->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations; dentry->d_op = AFFS_SB->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations;
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* layer. So all children are negative and dcache-based versions of operations * layer. So all children are negative and dcache-based versions of operations
* are OK. * are OK.
*/ */
/* SMP-safe */
static struct dentry *autofs_dir_lookup(struct inode *dir,struct dentry *dentry) static struct dentry *autofs_dir_lookup(struct inode *dir,struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -197,10 +197,13 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr ...@@ -197,10 +197,13 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
int oz_mode; int oz_mode;
DPRINTK(("autofs_root_lookup: name = ")); DPRINTK(("autofs_root_lookup: name = "));
lock_kernel();
autofs_say(dentry->d_name.name,dentry->d_name.len); autofs_say(dentry->d_name.name,dentry->d_name.len);
if (dentry->d_name.len > NAME_MAX) if (dentry->d_name.len > NAME_MAX) {
unlock_kernel();
return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */ return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */
}
sbi = autofs_sbi(dir->i_sb); sbi = autofs_sbi(dir->i_sb);
...@@ -231,9 +234,12 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr ...@@ -231,9 +234,12 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
* a signal. If so we can force a restart.. * a signal. If so we can force a restart..
*/ */
if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
if (signal_pending(current)) if (signal_pending(current)) {
unlock_kernel();
return ERR_PTR(-ERESTARTNOINTR); return ERR_PTR(-ERESTARTNOINTR);
} }
}
unlock_kernel();
/* /*
* If this dentry is unhashed, then we shouldn't honour this * If this dentry is unhashed, then we shouldn't honour this
......
...@@ -229,6 +229,7 @@ static struct dentry_operations autofs4_dentry_operations = { ...@@ -229,6 +229,7 @@ static struct dentry_operations autofs4_dentry_operations = {
/* Lookups in non-root dirs never find anything - if it's there, it's /* Lookups in non-root dirs never find anything - if it's there, it's
already in the dcache */ already in the dcache */
/* SMP-safe */
static struct dentry *autofs4_dir_lookup(struct inode *dir, struct dentry *dentry) static struct dentry *autofs4_dir_lookup(struct inode *dir, struct dentry *dentry)
{ {
#if 0 #if 0
...@@ -256,6 +257,7 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent ...@@ -256,6 +257,7 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent
sbi = autofs4_sbi(dir->i_sb); sbi = autofs4_sbi(dir->i_sb);
lock_kernel();
oz_mode = autofs4_oz_mode(sbi); oz_mode = autofs4_oz_mode(sbi);
DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
current->pid, current->pgrp, sbi->catatonic, oz_mode)); current->pid, current->pgrp, sbi->catatonic, oz_mode));
...@@ -288,9 +290,12 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent ...@@ -288,9 +290,12 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent
* a signal. If so we can force a restart.. * a signal. If so we can force a restart..
*/ */
if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
if (signal_pending(current)) if (signal_pending(current)) {
unlock_kernel();
return ERR_PTR(-ERESTARTNOINTR); return ERR_PTR(-ERESTARTNOINTR);
} }
}
unlock_kernel();
/* /*
* If this dentry is unhashed, then we shouldn't honour this * If this dentry is unhashed, then we shouldn't honour this
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/bfs_fs.h> #include <linux/bfs_fs.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/smp_lock.h>
#include "bfs_defs.h" #include "bfs_defs.h"
...@@ -125,14 +126,18 @@ static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry) ...@@ -125,14 +126,18 @@ static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry)
if (dentry->d_name.len > BFS_NAMELEN) if (dentry->d_name.len > BFS_NAMELEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
if (bh) { if (bh) {
unsigned long ino = le32_to_cpu(de->ino); unsigned long ino = le32_to_cpu(de->ino);
brelse(bh); brelse(bh);
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -618,6 +618,7 @@ static struct file_operations bm_status_operations = { ...@@ -618,6 +618,7 @@ static struct file_operations bm_status_operations = {
/* / */ /* / */
/* SMP-safe */
static struct dentry * bm_lookup(struct inode *dir, struct dentry *dentry) static struct dentry * bm_lookup(struct inode *dir, struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -112,6 +112,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry) ...@@ -112,6 +112,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
CDEBUG(D_INODE, "name %s, len %ld in ino %ld, fid %s\n", CDEBUG(D_INODE, "name %s, len %ld in ino %ld, fid %s\n",
name, (long)length, dir->i_ino, coda_i2s(dir)); name, (long)length, dir->i_ino, coda_i2s(dir));
lock_kernel();
/* control object, create inode on the fly */ /* control object, create inode on the fly */
if (coda_isroot(dir) && coda_iscontrol(name, length)) { if (coda_isroot(dir) && coda_iscontrol(name, length)) {
error = coda_cnode_makectl(&res_inode, dir->i_sb); error = coda_cnode_makectl(&res_inode, dir->i_sb);
...@@ -135,10 +136,14 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry) ...@@ -135,10 +136,14 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
} }
error = coda_cnode_make(&res_inode, &resfid, dir->i_sb); error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
if (error) return ERR_PTR(error); if (error) {
unlock_kernel();
return ERR_PTR(error);
}
} else if (error != -ENOENT) { } else if (error != -ENOENT) {
CDEBUG(D_INODE, "error for %s(%*s)%d\n", CDEBUG(D_INODE, "error for %s(%*s)%d\n",
coda_i2s(dir), (int)length, name, error); coda_i2s(dir), (int)length, name, error);
unlock_kernel();
return ERR_PTR(error); return ERR_PTR(error);
} }
CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n", CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
...@@ -152,6 +157,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry) ...@@ -152,6 +157,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
d_drop(entry); d_drop(entry);
coda_flag_inode(res_inode, C_VATTR); coda_flag_inode(res_inode, C_VATTR);
} }
unlock_kernel();
return NULL; return NULL;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/cramfs_fs.h> #include <linux/cramfs_fs.h>
#include <linux/smp_lock.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -330,8 +331,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -330,8 +331,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry) static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
{ {
unsigned int offset = 0; unsigned int offset = 0;
int sorted = dir->i_sb->CRAMFS_SB_FLAGS & CRAMFS_FLAG_SORTED_DIRS; int sorted;
lock_kernel();
sorted = dir->i_sb->CRAMFS_SB_FLAGS & CRAMFS_FLAG_SORTED_DIRS;
while (offset < dir->i_size) { while (offset < dir->i_size) {
struct cramfs_inode *de; struct cramfs_inode *de;
char *name; char *name;
...@@ -354,8 +357,10 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -354,8 +357,10 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
continue; continue;
for (;;) { for (;;) {
if (!namelen) if (!namelen) {
unlock_kernel();
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
}
if (name[namelen-1]) if (name[namelen-1])
break; break;
namelen--; namelen--;
...@@ -367,12 +372,14 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -367,12 +372,14 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
continue; continue;
if (!retval) { if (!retval) {
d_add(dentry, get_cramfs_inode(dir->i_sb, de)); d_add(dentry, get_cramfs_inode(dir->i_sb, de));
unlock_kernel();
return NULL; return NULL;
} }
/* else (retval < 0) */ /* else (retval < 0) */
if (sorted) if (sorted)
break; break;
} }
unlock_kernel();
d_add(dentry, NULL); d_add(dentry, NULL);
return NULL; return NULL;
} }
......
...@@ -2944,10 +2944,14 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) ...@@ -2944,10 +2944,14 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
up on any error */ up on any error */
dentry->d_op = &devfs_dops; dentry->d_op = &devfs_dops;
/* First try to get the devfs entry for this directory */ /* First try to get the devfs entry for this directory */
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir); parent = get_devfs_entry_from_vfs_inode (dir);
DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n", DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
dentry->d_name.name, dentry, parent, current->comm); dentry->d_name.name, dentry, parent, current->comm);
if (parent == NULL) return ERR_PTR (-ENOENT); if (parent == NULL) {
unlock_kernel();
return ERR_PTR (-ENOENT);
}
read_lock (&parent->u.dir.lock); read_lock (&parent->u.dir.lock);
de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len); de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
read_unlock (&parent->u.dir.lock); read_unlock (&parent->u.dir.lock);
...@@ -2972,6 +2976,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) ...@@ -2972,6 +2976,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
if (try_modload (parent, fs_info, if (try_modload (parent, fs_info,
dentry->d_name.name, dentry->d_name.len, &tmp) < 0) dentry->d_name.name, dentry->d_name.len, &tmp) < 0)
{ /* Lookup event was not queued to devfsd */ { /* Lookup event was not queued to devfsd */
unlock_kernel();
d_add (dentry, NULL); d_add (dentry, NULL);
return NULL; return NULL;
} }
...@@ -3014,6 +3019,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) ...@@ -3014,6 +3019,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
wake_up (&lookup_info.wait_queue); wake_up (&lookup_info.wait_queue);
write_unlock (&parent->u.dir.lock); write_unlock (&parent->u.dir.lock);
devfs_put (de); devfs_put (de);
unlock_kernel();
return retval; return retval;
} /* End Function devfs_lookup */ } /* End Function devfs_lookup */
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/param.h> #include <linux/param.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/smp_lock.h>
#include "devpts_i.h" #include "devpts_i.h"
static int devpts_root_readdir(struct file *,void *,filldir_t); static int devpts_root_readdir(struct file *,void *,filldir_t);
...@@ -126,10 +127,12 @@ static struct dentry *devpts_root_lookup(struct inode * dir, struct dentry * den ...@@ -126,10 +127,12 @@ static struct dentry *devpts_root_lookup(struct inode * dir, struct dentry * den
if ( entry >= sbi->max_ptys ) if ( entry >= sbi->max_ptys )
return NULL; return NULL;
lock_kernel();
if ( sbi->inodes[entry] ) if ( sbi->inodes[entry] )
atomic_inc(&sbi->inodes[entry]->i_count); atomic_inc(&sbi->inodes[entry]->i_count);
d_add(dentry, sbi->inodes[entry]); d_add(dentry, sbi->inodes[entry]);
unlock_kernel();
return NULL; return NULL;
} }
...@@ -68,6 +68,7 @@ static int driverfs_statfs(struct super_block *sb, struct statfs *buf) ...@@ -68,6 +68,7 @@ static int driverfs_statfs(struct super_block *sb, struct statfs *buf)
return 0; return 0;
} }
/* SMP-safe */
static struct dentry *driverfs_lookup(struct inode *dir, struct dentry *dentry) static struct dentry *driverfs_lookup(struct inode *dir, struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/efs_fs.h> #include <linux/efs_fs.h>
#include <linux/smp_lock.h>
static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
struct buffer_head *bh; struct buffer_head *bh;
...@@ -57,18 +58,17 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) ...@@ -57,18 +58,17 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len)
struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry) { struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry) {
efs_ino_t inodenum; efs_ino_t inodenum;
struct inode * inode; struct inode * inode = NULL;
if (!dir || !S_ISDIR(dir->i_mode))
return ERR_PTR(-ENOENT);
inode = NULL;
lock_kernel();
inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
if (inodenum) { if (inodenum) {
if (!(inode = iget(dir->i_sb, inodenum))) if (!(inode = iget(dir->i_sb, inodenum))) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "ext2.h" #include "ext2.h"
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
/* /*
* Couple of helper functions - make the code slightly cleaner. * Couple of helper functions - make the code slightly cleaner.
...@@ -72,13 +73,17 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry) ...@@ -72,13 +73,17 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
if (dentry->d_name.len > EXT2_NAME_LEN) if (dentry->d_name.len > EXT2_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = ext2_inode_by_name(dir, dentry); ino = ext2_inode_by_name(dir, dentry);
inode = NULL; inode = NULL;
if (ino) { if (ino) {
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/smp_lock.h>
/* /*
...@@ -205,6 +206,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) ...@@ -205,6 +206,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
if (dentry->d_name.len > EXT3_NAME_LEN) if (dentry->d_name.len > EXT3_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
bh = ext3_find_entry(dentry, &de); bh = ext3_find_entry(dentry, &de);
inode = NULL; inode = NULL;
if (bh) { if (bh) {
...@@ -212,9 +214,12 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) ...@@ -212,9 +214,12 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
brelse (bh); brelse (bh);
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include "vxfs.h" #include "vxfs.h"
#include "vxfs_dir.h" #include "vxfs_dir.h"
...@@ -210,13 +211,16 @@ vxfs_lookup(struct inode *dip, struct dentry *dp) ...@@ -210,13 +211,16 @@ vxfs_lookup(struct inode *dip, struct dentry *dp)
if (dp->d_name.len > VXFS_NAMELEN) if (dp->d_name.len > VXFS_NAMELEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = vxfs_inode_by_name(dip, dp); ino = vxfs_inode_by_name(dip, dp);
if (ino == 0) if (ino) {
return NULL;
ip = iget(dip->i_sb, ino); ip = iget(dip->i_sb, ino);
if (!ip) if (!ip) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dp, ip); d_add(dp, ip);
return NULL; return NULL;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h> #include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h> #include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ Forward declarations ================*/ /*================ Forward declarations ================*/
...@@ -102,6 +103,8 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry) ...@@ -102,6 +103,8 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
struct hfs_cat_key key; struct hfs_cat_key key;
struct inode *inode = NULL; struct inode *inode = NULL;
lock_kernel();
dentry->d_op = &hfs_dentry_operations; dentry->d_op = &hfs_dentry_operations;
entry = HFS_I(dir)->entry; entry = HFS_I(dir)->entry;
dtype = HFS_ITYPE(dir->i_ino); dtype = HFS_ITYPE(dir->i_ino);
...@@ -112,7 +115,7 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry) ...@@ -112,7 +115,7 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
/* no need to check for "." or ".." */ /* no need to check for "." or ".." */
/* Check for special directories if in a normal directory. /* Check for epecial directories if in a normal directory.
Note that cap_dupdir() does an iput(dir). */ Note that cap_dupdir() does an iput(dir). */
if (dtype==HFS_CAP_NDIR) { if (dtype==HFS_CAP_NDIR) {
/* Check for ".resource", ".finderinfo" and ".rootinfo" */ /* Check for ".resource", ".finderinfo" and ".rootinfo" */
...@@ -149,6 +152,7 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry) ...@@ -149,6 +152,7 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
} }
done: done:
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h> #include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h> #include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ Forward declarations ================*/ /*================ Forward declarations ================*/
...@@ -114,6 +115,7 @@ static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry) ...@@ -114,6 +115,7 @@ static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry)
struct hfs_cat_key key; struct hfs_cat_key key;
struct inode *inode = NULL; struct inode *inode = NULL;
lock_kernel();
dentry->d_op = &hfs_dentry_operations; dentry->d_op = &hfs_dentry_operations;
entry = HFS_I(dir)->entry; entry = HFS_I(dir)->entry;
...@@ -145,6 +147,7 @@ static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry) ...@@ -145,6 +147,7 @@ static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry)
} }
done: done:
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h> #include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h> #include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ Forward declarations ================*/ /*================ Forward declarations ================*/
...@@ -104,6 +105,7 @@ static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry) ...@@ -104,6 +105,7 @@ static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry)
struct hfs_cat_key key; struct hfs_cat_key key;
struct inode *inode = NULL; struct inode *inode = NULL;
lock_kernel();
dentry->d_op = &hfs_dentry_operations; dentry->d_op = &hfs_dentry_operations;
entry = HFS_I(dir)->entry; entry = HFS_I(dir)->entry;
dtype = HFS_ITYPE(dir->i_ino); dtype = HFS_ITYPE(dir->i_ino);
...@@ -154,6 +156,7 @@ static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry) ...@@ -154,6 +156,7 @@ static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry)
} }
done: done:
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -189,6 +189,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -189,6 +189,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
struct inode *result = NULL; struct inode *result = NULL;
struct hpfs_inode_info *hpfs_result; struct hpfs_inode_info *hpfs_result;
lock_kernel();
if ((err = hpfs_chk_name((char *)name, &len))) { if ((err = hpfs_chk_name((char *)name, &len))) {
if (err == -ENAMETOOLONG) return ERR_PTR(-ENAMETOOLONG); if (err == -ENAMETOOLONG) return ERR_PTR(-ENAMETOOLONG);
goto end_add; goto end_add;
...@@ -273,6 +274,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -273,6 +274,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
hpfs_unlock_inode(dir); hpfs_unlock_inode(dir);
end_add: end_add:
hpfs_set_dentry_operations(dentry); hpfs_set_dentry_operations(dentry);
unlock_kernel();
d_add(dentry, result); d_add(dentry, result);
return NULL; return NULL;
...@@ -286,5 +288,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -286,5 +288,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
/*bail:*/ /*bail:*/
hpfs_unlock_inode(dir); hpfs_unlock_inode(dir);
unlock_kernel();
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/config.h> /* Joliet? */ #include <linux/config.h> /* Joliet? */
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -167,6 +168,7 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry) ...@@ -167,6 +168,7 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
if (!page) if (!page)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
lock_kernel();
ino = isofs_find_entry(dir, dentry, page_address(page), ino = isofs_find_entry(dir, dentry, page_address(page),
1024 + page_address(page)); 1024 + page_address(page));
__free_page(page); __free_page(page);
...@@ -174,9 +176,12 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry) ...@@ -174,9 +176,12 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
inode = NULL; inode = NULL;
if (ino) { if (ino) {
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
...@@ -631,6 +631,8 @@ jffs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -631,6 +631,8 @@ jffs_lookup(struct inode *dir, struct dentry *dentry)
len = dentry->d_name.len; len = dentry->d_name.len;
name = dentry->d_name.name; name = dentry->d_name.name;
lock_kernel();
D3({ D3({
char *s = (char *)kmalloc(len + 1, GFP_KERNEL); char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
memcpy(s, name, len); memcpy(s, name, len);
...@@ -698,6 +700,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -698,6 +700,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry)
d_add(dentry, inode); d_add(dentry, inode);
D3(printk (KERN_NOTICE "lookup(): up biglock\n")); D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
unlock_kernel();
return NULL; return NULL;
jffs_lookup_end: jffs_lookup_end:
...@@ -705,6 +708,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -705,6 +708,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry)
up(&c->fmc->biglock); up(&c->fmc->biglock);
jffs_lookup_end_no_biglock: jffs_lookup_end_no_biglock:
unlock_kernel();
return ERR_PTR(r); return ERR_PTR(r);
} /* jffs_lookup() */ } /* jffs_lookup() */
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <linux/jffs2_fs_i.h> #include <linux/jffs2_fs_i.h>
#include <linux/jffs2_fs_sb.h> #include <linux/jffs2_fs_sb.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/smp_lock.h>
#include "nodelist.h" #include "nodelist.h"
static int jffs2_readdir (struct file *, void *, filldir_t); static int jffs2_readdir (struct file *, void *, filldir_t);
...@@ -98,6 +99,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target) ...@@ -98,6 +99,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
D1(printk(KERN_DEBUG "jffs2_lookup()\n")); D1(printk(KERN_DEBUG "jffs2_lookup()\n"));
lock_kernel();
dir_f = JFFS2_INODE_INFO(dir_i); dir_f = JFFS2_INODE_INFO(dir_i);
c = JFFS2_SB_INFO(dir_i->i_sb); c = JFFS2_SB_INFO(dir_i->i_sb);
...@@ -118,10 +120,12 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target) ...@@ -118,10 +120,12 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
if (ino) { if (ino) {
inode = iget(dir_i->i_sb, ino); inode = iget(dir_i->i_sb, ino);
if (!inode) { if (!inode) {
unlock_kernel();
printk(KERN_WARNING "iget() failed for ino #%u\n", ino); printk(KERN_WARNING "iget() failed for ino #%u\n", ino);
return (ERR_PTR(-EIO)); return (ERR_PTR(-EIO));
} }
} }
unlock_kernel();
d_add(target, inode); d_add(target, inode);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/minix_fs.h> #include <linux/minix_fs.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
static inline void inc_count(struct inode *inode) static inline void inc_count(struct inode *inode)
...@@ -66,13 +67,17 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry) ...@@ -66,13 +67,17 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
if (dentry->d_name.len > dir->i_sb->u.minix_sb.s_namelen) if (dentry->d_name.len > dir->i_sb->u.minix_sb.s_namelen)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = minix_inode_by_name(dentry); ino = minix_inode_by_name(dentry);
if (ino) { if (ino) {
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/smp_lock.h>
#define MSDOS_DEBUG 0 #define MSDOS_DEBUG 0
#define PRINTK(x) #define PRINTK(x)
...@@ -215,6 +216,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry) ...@@ -215,6 +216,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
dentry->d_op = &msdos_dentry_operations; dentry->d_op = &msdos_dentry_operations;
lock_kernel();
res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
&de, &ino); &de, &ino);
...@@ -231,6 +233,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry) ...@@ -231,6 +233,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
out: out:
if (bh) if (bh)
fat_brelse(sb, bh); fat_brelse(sb, bh);
unlock_kernel();
return ERR_PTR(res); return ERR_PTR(res);
} }
......
...@@ -304,9 +304,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i ...@@ -304,9 +304,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i
struct dentry * dentry = d_alloc(parent, name); struct dentry * dentry = d_alloc(parent, name);
result = ERR_PTR(-ENOMEM); result = ERR_PTR(-ENOMEM);
if (dentry) { if (dentry) {
lock_kernel();
result = dir->i_op->lookup(dir, dentry); result = dir->i_op->lookup(dir, dentry);
unlock_kernel();
if (result) if (result)
dput(dentry); dput(dentry);
else else
...@@ -778,9 +776,7 @@ struct dentry * lookup_hash(struct qstr *name, struct dentry * base) ...@@ -778,9 +776,7 @@ struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
dentry = ERR_PTR(-ENOMEM); dentry = ERR_PTR(-ENOMEM);
if (!new) if (!new)
goto out; goto out;
lock_kernel();
dentry = inode->i_op->lookup(inode, new); dentry = inode->i_op->lookup(inode, new);
unlock_kernel();
if (!dentry) if (!dentry)
dentry = new; dentry = new;
else else
......
...@@ -741,6 +741,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry) ...@@ -741,6 +741,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry)
int error, res, len = dentry->d_name.len + 1; int error, res, len = dentry->d_name.len + 1;
__u8 __name[len]; __u8 __name[len];
lock_kernel();
error = -EIO; error = -EIO;
if (!ncp_conn_valid(server)) if (!ncp_conn_valid(server))
goto finished; goto finished;
...@@ -785,6 +786,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry) ...@@ -785,6 +786,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry)
finished: finished:
PPRINTK("ncp_lookup: result=%d\n", error); PPRINTK("ncp_lookup: result=%d\n", error);
unlock_kernel();
return ERR_PTR(error); return ERR_PTR(error);
} }
......
...@@ -579,6 +579,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry) ...@@ -579,6 +579,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
error = -ENOMEM; error = -ENOMEM;
dentry->d_op = &nfs_dentry_operations; dentry->d_op = &nfs_dentry_operations;
lock_kernel();
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
inode = NULL; inode = NULL;
if (error == -ENOENT) if (error == -ENOENT)
...@@ -593,6 +594,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry) ...@@ -593,6 +594,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
} }
nfs_renew_times(dentry); nfs_renew_times(dentry);
} }
unlock_kernel();
out: out:
return ERR_PTR(error); return ERR_PTR(error);
} }
......
...@@ -529,6 +529,7 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d) ...@@ -529,6 +529,7 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
walk.name = NULL; walk.name = NULL;
walk.namelen = 0; walk.namelen = 0;
/* Convert to wide string. */ /* Convert to wide string. */
lock_kernel();
err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name, err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name,
d->d_name.len, &walk.name, &walk.namelen); d->d_name.len, &walk.name, &walk.namelen);
if (err) if (err)
...@@ -548,10 +549,12 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d) ...@@ -548,10 +549,12 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
d_add(d, res); d_add(d, res);
ntfs_free(item); ntfs_free(item);
ntfs_free(walk.name); ntfs_free(walk.name);
unlock_kernel();
/* Always return success, the dcache will handle negative entries. */ /* Always return success, the dcache will handle negative entries. */
return NULL; return NULL;
err_ret: err_ret:
ntfs_free(walk.name); ntfs_free(walk.name);
unlock_kernel();
return ERR_PTR(err); return ERR_PTR(err);
} }
......
...@@ -633,6 +633,7 @@ static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentr ...@@ -633,6 +633,7 @@ static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentr
inode = NULL; inode = NULL;
name = dentry->d_name.name; name = dentry->d_name.name;
len = dentry->d_name.len; len = dentry->d_name.len;
lock_kernel();
if (name [0] == '.' && len == 5 && !strncmp (name + 1, "node", 4)) { if (name [0] == '.' && len == 5 && !strncmp (name + 1, "node", 4)) {
ino = NODEP2INO(NODE(dir->i_ino).first_prop); ino = NODEP2INO(NODE(dir->i_ino).first_prop);
type = OPFSL_NODENUM; type = OPFSL_NODENUM;
...@@ -692,10 +693,13 @@ static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentr ...@@ -692,10 +693,13 @@ static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentr
ino = lookup_children (NODE(dir->i_ino).child, name, len); ino = lookup_children (NODE(dir->i_ino).child, name, len);
if (ino) if (ino)
type = OPFSL_DIR; type = OPFSL_DIR;
else else {
unlock_kernel();
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
}
inode = iget (dir->i_sb, ino); inode = iget (dir->i_sb, ino);
unlock_kernel();
if (!inode) if (!inode)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
switch (type) { switch (type) {
......
...@@ -777,6 +777,7 @@ static struct dentry_operations pid_base_dentry_operations = ...@@ -777,6 +777,7 @@ static struct dentry_operations pid_base_dentry_operations =
/* Lookups */ /* Lookups */
#define MAX_MULBY10 ((~0U-9)/10) #define MAX_MULBY10 ((~0U-9)/10)
/* SMP-safe */
static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
{ {
unsigned int fd, c; unsigned int fd, c;
...@@ -855,6 +856,7 @@ static struct inode_operations proc_fd_inode_operations = { ...@@ -855,6 +856,7 @@ static struct inode_operations proc_fd_inode_operations = {
permission: proc_permission, permission: proc_permission,
}; };
/* SMP-safe */
static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
{ {
struct inode *inode; struct inode *inode;
...@@ -984,6 +986,7 @@ static struct inode_operations proc_self_inode_operations = { ...@@ -984,6 +986,7 @@ static struct inode_operations proc_self_inode_operations = {
follow_link: proc_self_follow_link, follow_link: proc_self_follow_link,
}; };
/* SMP-safe */
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry) struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
{ {
unsigned int pid, c; unsigned int pid, c;
......
...@@ -258,12 +258,11 @@ static struct dentry_operations proc_dentry_operations = ...@@ -258,12 +258,11 @@ static struct dentry_operations proc_dentry_operations =
*/ */
struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry) struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
{ {
struct inode *inode; struct inode *inode = NULL;
struct proc_dir_entry * de; struct proc_dir_entry * de;
int error; int error = -ENOENT;
error = -ENOENT; lock_kernel();
inode = NULL;
de = PDE(dir); de = PDE(dir);
if (de) { if (de) {
for (de = de->subdir; de ; de = de->next) { for (de = de->subdir; de ; de = de->next) {
...@@ -279,6 +278,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry) ...@@ -279,6 +278,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
} }
} }
} }
unlock_kernel();
if (inode) { if (inode) {
dentry->d_op = &proc_dentry_operations; dentry->d_op = &proc_dentry_operations;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <linux/smp_lock.h>
struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver; struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
...@@ -80,15 +81,14 @@ void __init proc_root_init(void) ...@@ -80,15 +81,14 @@ void __init proc_root_init(void)
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry) static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
{ {
if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */ if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
int nlink = proc_root.nlink; lock_kernel();
dir->i_nlink = proc_root.nlink + nr_threads;
nlink += nr_threads; unlock_kernel();
dir->i_nlink = nlink;
} }
if (!proc_lookup(dir, dentry)) if (!proc_lookup(dir, dentry)) {
return NULL; return NULL;
}
return proc_pid_lookup(dir, dentry); return proc_pid_lookup(dir, dentry);
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp_lock.h>
/* /*
...@@ -115,6 +116,7 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry) ...@@ -115,6 +116,7 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry)
int len = dentry->d_name.len; int len = dentry->d_name.len;
struct inode *foundinode = NULL; struct inode *foundinode = NULL;
lock_kernel();
if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino))) if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
goto out; goto out;
/* The entry is linked, let's get the real info */ /* The entry is linked, let's get the real info */
...@@ -127,10 +129,12 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry) ...@@ -127,10 +129,12 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry)
brelse(bh); brelse(bh);
if ((foundinode = iget(dir->i_sb, ino)) == NULL) { if ((foundinode = iget(dir->i_sb, ino)) == NULL) {
unlock_kernel();
QNX4DEBUG(("qnx4: lookup->iget -> NULL\n")); QNX4DEBUG(("qnx4: lookup->iget -> NULL\n"));
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
out: out:
unlock_kernel();
d_add(dentry, foundinode); d_add(dentry, foundinode);
return NULL; return NULL;
......
...@@ -53,6 +53,7 @@ static int ramfs_statfs(struct super_block *sb, struct statfs *buf) ...@@ -53,6 +53,7 @@ static int ramfs_statfs(struct super_block *sb, struct statfs *buf)
* Lookup the data. This is trivial - if the dentry didn't already * Lookup the data. This is trivial - if the dentry didn't already
* exist, we know it is negative. * exist, we know it is negative.
*/ */
/* SMP-safe */
static struct dentry * ramfs_lookup(struct inode *dir, struct dentry *dentry) static struct dentry * ramfs_lookup(struct inode *dir, struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
...@@ -349,15 +349,18 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent ...@@ -349,15 +349,18 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent
if (dentry->d_name.len > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize)) if (dentry->d_name.len > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize))
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
de.de_gen_number_bit_string = 0; de.de_gen_number_bit_string = 0;
retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de); retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
pathrelse (&path_to_entry); pathrelse (&path_to_entry);
if (retval == NAME_FOUND) { if (retval == NAME_FOUND) {
inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
if (!inode || IS_ERR(inode)) { if (!inode || IS_ERR(inode)) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
} }
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
......
...@@ -318,6 +318,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry) ...@@ -318,6 +318,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry)
res = -EACCES; /* placeholder for "no data here" */ res = -EACCES; /* placeholder for "no data here" */
offset = dir->i_ino & ROMFH_MASK; offset = dir->i_ino & ROMFH_MASK;
lock_kernel();
if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
goto out; goto out;
...@@ -378,7 +379,8 @@ out0: inode = NULL; ...@@ -378,7 +379,8 @@ out0: inode = NULL;
outi: res = 0; outi: res = 0;
d_add (dentry, inode); d_add (dentry, inode);
out: return ERR_PTR(res); out: unlock_kernel();
return ERR_PTR(res);
} }
/* /*
......
...@@ -399,6 +399,7 @@ smb_lookup(struct inode *dir, struct dentry *dentry) ...@@ -399,6 +399,7 @@ smb_lookup(struct inode *dir, struct dentry *dentry)
if (dentry->d_name.len > SMB_MAXNAMELEN) if (dentry->d_name.len > SMB_MAXNAMELEN)
goto out; goto out;
lock_kernel();
error = smb_proc_getattr(dentry, &finfo); error = smb_proc_getattr(dentry, &finfo);
#ifdef SMBFS_PARANOIA #ifdef SMBFS_PARANOIA
if (error && error != -ENOENT) if (error && error != -ENOENT)
...@@ -426,6 +427,7 @@ smb_lookup(struct inode *dir, struct dentry *dentry) ...@@ -426,6 +427,7 @@ smb_lookup(struct inode *dir, struct dentry *dentry)
error = 0; error = 0;
} }
} }
unlock_kernel();
out: out:
return ERR_PTR(error); return ERR_PTR(error);
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sysv_fs.h> #include <linux/sysv_fs.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
static inline void inc_count(struct inode *inode) static inline void inc_count(struct inode *inode)
{ {
...@@ -72,13 +73,17 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry) ...@@ -72,13 +73,17 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry)
dentry->d_op = dir->i_sb->s_root->d_op; dentry->d_op = dir->i_sb->s_root->d_op;
if (dentry->d_name.len > SYSV_NAMELEN) if (dentry->d_name.len > SYSV_NAMELEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = sysv_inode_by_name(dentry); ino = sysv_inode_by_name(dentry);
if (ino) { if (ino) {
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -298,15 +298,18 @@ udf_lookup(struct inode *dir, struct dentry *dentry) ...@@ -298,15 +298,18 @@ udf_lookup(struct inode *dir, struct dentry *dentry)
if (dentry->d_name.len > UDF_NAME_LEN) if (dentry->d_name.len > UDF_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
#ifdef UDF_RECOVERY #ifdef UDF_RECOVERY
/* temporary shorthand for specifying files by inode number */ /* temporary shorthand for specifying files by inode number */
if (!strncmp(dentry->d_name.name, ".B=", 3) ) if (!strncmp(dentry->d_name.name, ".B=", 3) )
{ {
lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) }; lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) };
inode = udf_iget(dir->i_sb, lb); inode = udf_iget(dir->i_sb, lb);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
else else
#endif /* UDF_RECOVERY */ #endif /* UDF_RECOVERY */
...@@ -317,9 +320,12 @@ udf_lookup(struct inode *dir, struct dentry *dentry) ...@@ -317,9 +320,12 @@ udf_lookup(struct inode *dir, struct dentry *dentry)
udf_release_data(fibh.sbh); udf_release_data(fibh.sbh);
inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
if ( !inode ) if ( !inode ) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/ufs_fs.h> #include <linux/ufs_fs.h>
#include <linux/smp_lock.h>
#undef UFS_NAMEI_DEBUG #undef UFS_NAMEI_DEBUG
...@@ -68,12 +69,16 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry) ...@@ -68,12 +69,16 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)
if (dentry->d_name.len > UFS_MAXNAMLEN) if (dentry->d_name.len > UFS_MAXNAMLEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = ufs_inode_by_name(dir, dentry); ino = ufs_inode_by_name(dir, dentry);
if (ino) { if (ino) {
inode = iget(dir->i_sb, ino); inode = iget(dir->i_sb, ino);
if (!inode) if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
}
unlock_kernel();
d_add(dentry, inode); d_add(dentry, inode);
return NULL; return NULL;
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#define DEBUG_LEVEL 0 #define DEBUG_LEVEL 0
#if (DEBUG_LEVEL >= 1) #if (DEBUG_LEVEL >= 1)
...@@ -986,6 +987,7 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry) ...@@ -986,6 +987,7 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry)
PRINTK2(("vfat_lookup: name=%s, len=%d\n", PRINTK2(("vfat_lookup: name=%s, len=%d\n",
dentry->d_name.name, dentry->d_name.len)); dentry->d_name.name, dentry->d_name.len));
lock_kernel();
table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0; table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
dentry->d_op = &vfat_dentry_ops[table]; dentry->d_op = &vfat_dentry_ops[table];
...@@ -997,19 +999,23 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry) ...@@ -997,19 +999,23 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry)
} }
inode = fat_build_inode(dir->i_sb, de, sinfo.ino, &res); inode = fat_build_inode(dir->i_sb, de, sinfo.ino, &res);
fat_brelse(dir->i_sb, bh); fat_brelse(dir->i_sb, bh);
if (res) if (res) {
unlock_kernel();
return ERR_PTR(res); return ERR_PTR(res);
}
alias = d_find_alias(inode); alias = d_find_alias(inode);
if (alias) { if (alias) {
if (d_invalidate(alias)==0) if (d_invalidate(alias)==0)
dput(alias); dput(alias);
else { else {
iput(inode); iput(inode);
unlock_kernel();
return alias; return alias;
} }
} }
error: error:
unlock_kernel();
dentry->d_op = &vfat_dentry_ops[table]; dentry->d_op = &vfat_dentry_ops[table];
dentry->d_time = dentry->d_parent->d_inode->i_version; dentry->d_time = dentry->d_parent->d_inode->i_version;
d_add(dentry,inode); d_add(dentry,inode);
......
...@@ -973,6 +973,7 @@ static int shmem_statfs(struct super_block *sb, struct statfs *buf) ...@@ -973,6 +973,7 @@ static int shmem_statfs(struct super_block *sb, struct statfs *buf)
* Lookup the data. This is trivial - if the dentry didn't already * Lookup the data. This is trivial - if the dentry didn't already
* exist, we know it is negative. * exist, we know it is negative.
*/ */
/* SMP-safe */
static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry) static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
{ {
d_add(dentry, NULL); d_add(dentry, NULL);
......
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