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:
locking rules:
all may block
BKL i_sem(inode)
lookup: yes yes
lookup: no yes
create: yes yes
link: 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)
return 0;
}
/* SMP-safe */
static struct dentry *pcihpfs_lookup (struct inode *dir, struct dentry *dentry)
{
d_add(dentry, NULL);
......
......@@ -25,6 +25,7 @@
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/smp_lock.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
......@@ -170,10 +171,12 @@ static struct dentry *capifs_root_lookup(struct inode * dir, struct dentry * den
if (tmp == p || *tmp)
return NULL;
lock_kernel();
for (i = 0, np = sbi->nccis ; i < sbi->max_ncci; i++, np++) {
if (np->used && np->num == num && np->type == type)
break;
}
unlock_kernel();
if ( i >= sbi->max_ncci )
return NULL;
......
......@@ -64,6 +64,7 @@
#include <asm/uaccess.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
......@@ -928,6 +929,7 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry)
struct proc_dir_entry *de;
struct inode *inode = NULL;
lock_kernel();
if ((de = PDE(dir)) != NULL) {
for (de = de->subdir ; de ; de = de->next) {
if ((de && de->low_ino) &&
......@@ -937,12 +939,14 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry)
if ((inode = proc_get_inode(dir->i_sb,
de->low_ino, de)) == NULL) {
printk(KERN_ERR "COMX: lookup error\n");
unlock_kernel();
return ERR_PTR(-EINVAL);
}
break;
}
}
}
unlock_kernel();
dentry->d_op = &comx_dentry_operations;
d_add(dentry, inode);
return NULL;
......
......@@ -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)
{
d_add(dentry, NULL);
......
......@@ -17,6 +17,7 @@
#include <linux/time.h>
#include <linux/stat.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include "adfs.h"
......@@ -271,6 +272,7 @@ struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry)
int error;
dentry->d_op = &adfs_dentry_operations;
lock_kernel();
error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj);
if (error == 0) {
error = -EACCES;
......@@ -282,6 +284,7 @@ struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry)
if (inode)
error = 0;
}
unlock_kernel();
d_add(dentry, inode);
return ERR_PTR(error);
}
......
......@@ -16,6 +16,7 @@
#include <linux/fcntl.h>
#include <linux/locks.h>
#include <linux/amigaffs.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
......@@ -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);
lock_kernel();
affs_lock_dir(dir);
bh = affs_find_entry(dir, dentry);
affs_unlock_dir(dir);
if (IS_ERR(bh))
if (IS_ERR(bh)) {
unlock_kernel();
return ERR_PTR(PTR_ERR(bh));
}
if (bh) {
u32 ino = bh->b_blocknr;
......@@ -235,10 +239,13 @@ affs_lookup(struct inode *dir, struct dentry *dentry)
}
affs_brelse(bh);
inode = iget(sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
dentry->d_op = AFFS_SB->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations;
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -17,6 +17,7 @@
* layer. So all children are negative and dcache-based versions of operations
* are OK.
*/
/* SMP-safe */
static struct dentry *autofs_dir_lookup(struct inode *dir,struct dentry *dentry)
{
d_add(dentry, NULL);
......
......@@ -197,10 +197,13 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
int oz_mode;
DPRINTK(("autofs_root_lookup: name = "));
lock_kernel();
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 */
}
sbi = autofs_sbi(dir->i_sb);
......@@ -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..
*/
if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
if (signal_pending(current))
if (signal_pending(current)) {
unlock_kernel();
return ERR_PTR(-ERESTARTNOINTR);
}
}
unlock_kernel();
/*
* If this dentry is unhashed, then we shouldn't honour this
......
......@@ -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
already in the dcache */
/* SMP-safe */
static struct dentry *autofs4_dir_lookup(struct inode *dir, struct dentry *dentry)
{
#if 0
......@@ -256,6 +257,7 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent
sbi = autofs4_sbi(dir->i_sb);
lock_kernel();
oz_mode = autofs4_oz_mode(sbi);
DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
current->pid, current->pgrp, sbi->catatonic, oz_mode));
......@@ -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..
*/
if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
if (signal_pending(current))
if (signal_pending(current)) {
unlock_kernel();
return ERR_PTR(-ERESTARTNOINTR);
}
}
unlock_kernel();
/*
* If this dentry is unhashed, then we shouldn't honour this
......
......@@ -8,6 +8,7 @@
#include <linux/string.h>
#include <linux/bfs_fs.h>
#include <linux/locks.h>
#include <linux/smp_lock.h>
#include "bfs_defs.h"
......@@ -125,14 +126,18 @@ static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry)
if (dentry->d_name.len > BFS_NAMELEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
if (bh) {
unsigned long ino = le32_to_cpu(de->ino);
brelse(bh);
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -618,6 +618,7 @@ static struct file_operations bm_status_operations = {
/* / */
/* SMP-safe */
static struct dentry * bm_lookup(struct inode *dir, struct dentry *dentry)
{
d_add(dentry, NULL);
......
......@@ -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",
name, (long)length, dir->i_ino, coda_i2s(dir));
lock_kernel();
/* control object, create inode on the fly */
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
error = coda_cnode_makectl(&res_inode, dir->i_sb);
......@@ -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);
if (error) return ERR_PTR(error);
if (error) {
unlock_kernel();
return ERR_PTR(error);
}
} else if (error != -ENOENT) {
CDEBUG(D_INODE, "error for %s(%*s)%d\n",
coda_i2s(dir), (int)length, name, error);
unlock_kernel();
return ERR_PTR(error);
}
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)
d_drop(entry);
coda_flag_inode(res_inode, C_VATTR);
}
unlock_kernel();
return NULL;
}
......
......@@ -19,6 +19,7 @@
#include <linux/locks.h>
#include <linux/blkdev.h>
#include <linux/cramfs_fs.h>
#include <linux/smp_lock.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
......@@ -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)
{
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) {
struct cramfs_inode *de;
char *name;
......@@ -354,8 +357,10 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
continue;
for (;;) {
if (!namelen)
if (!namelen) {
unlock_kernel();
return ERR_PTR(-EIO);
}
if (name[namelen-1])
break;
namelen--;
......@@ -367,12 +372,14 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry)
continue;
if (!retval) {
d_add(dentry, get_cramfs_inode(dir->i_sb, de));
unlock_kernel();
return NULL;
}
/* else (retval < 0) */
if (sorted)
break;
}
unlock_kernel();
d_add(dentry, NULL);
return NULL;
}
......
......@@ -2944,10 +2944,14 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
up on any error */
dentry->d_op = &devfs_dops;
/* First try to get the devfs entry for this directory */
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir);
DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
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);
de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
read_unlock (&parent->u.dir.lock);
......@@ -2972,6 +2976,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
if (try_modload (parent, fs_info,
dentry->d_name.name, dentry->d_name.len, &tmp) < 0)
{ /* Lookup event was not queued to devfsd */
unlock_kernel();
d_add (dentry, NULL);
return NULL;
}
......@@ -3014,6 +3019,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
wake_up (&lookup_info.wait_queue);
write_unlock (&parent->u.dir.lock);
devfs_put (de);
unlock_kernel();
return retval;
} /* End Function devfs_lookup */
......
......@@ -14,6 +14,7 @@
#include <linux/stat.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
#include "devpts_i.h"
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
if ( entry >= sbi->max_ptys )
return NULL;
lock_kernel();
if ( sbi->inodes[entry] )
atomic_inc(&sbi->inodes[entry]->i_count);
d_add(dentry, sbi->inodes[entry]);
unlock_kernel();
return NULL;
}
......@@ -68,6 +68,7 @@ static int driverfs_statfs(struct super_block *sb, struct statfs *buf)
return 0;
}
/* SMP-safe */
static struct dentry *driverfs_lookup(struct inode *dir, struct dentry *dentry)
{
d_add(dentry, NULL);
......
......@@ -8,6 +8,7 @@
#include <linux/string.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) {
struct buffer_head *bh;
......@@ -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) {
efs_ino_t inodenum;
struct inode * inode;
if (!dir || !S_ISDIR(dir->i_mode))
return ERR_PTR(-ENOENT);
inode = NULL;
struct inode * inode = NULL;
lock_kernel();
inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
if (inodenum) {
if (!(inode = iget(dir->i_sb, inodenum)))
if (!(inode = iget(dir->i_sb, inodenum))) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
......
......@@ -31,6 +31,7 @@
#include "ext2.h"
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
/*
* Couple of helper functions - make the code slightly cleaner.
......@@ -72,13 +73,17 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
if (dentry->d_name.len > EXT2_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = ext2_inode_by_name(dir, dentry);
inode = NULL;
if (ino) {
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -28,6 +28,7 @@
#include <linux/string.h>
#include <linux/locks.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)
if (dentry->d_name.len > EXT3_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
bh = ext3_find_entry(dentry, &de);
inode = NULL;
if (bh) {
......@@ -212,9 +214,12 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry)
brelse (bh);
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -38,6 +38,7 @@
#include <linux/highmem.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include "vxfs.h"
#include "vxfs_dir.h"
......@@ -210,13 +211,16 @@ vxfs_lookup(struct inode *dip, struct dentry *dp)
if (dp->d_name.len > VXFS_NAMELEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = vxfs_inode_by_name(dip, dp);
if (ino == 0)
return NULL;
ip = iget(dip->i_sb, ino);
if (!ip)
return ERR_PTR(-EACCES);
if (ino) {
ip = iget(dip->i_sb, ino);
if (!ip) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dp, ip);
return NULL;
}
......
......@@ -24,6 +24,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ Forward declarations ================*/
......@@ -102,6 +103,8 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
struct hfs_cat_key key;
struct inode *inode = NULL;
lock_kernel();
dentry->d_op = &hfs_dentry_operations;
entry = HFS_I(dir)->entry;
dtype = HFS_ITYPE(dir->i_ino);
......@@ -112,7 +115,7 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
/* 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). */
if (dtype==HFS_CAP_NDIR) {
/* Check for ".resource", ".finderinfo" and ".rootinfo" */
......@@ -149,6 +152,7 @@ static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
}
done:
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -20,6 +20,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ Forward declarations ================*/
......@@ -114,6 +115,7 @@ static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry)
struct hfs_cat_key key;
struct inode *inode = NULL;
lock_kernel();
dentry->d_op = &hfs_dentry_operations;
entry = HFS_I(dir)->entry;
......@@ -145,6 +147,7 @@ static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry)
}
done:
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -26,6 +26,7 @@
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
#include <linux/smp_lock.h>
/*================ Forward declarations ================*/
......@@ -104,6 +105,7 @@ static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry)
struct hfs_cat_key key;
struct inode *inode = NULL;
lock_kernel();
dentry->d_op = &hfs_dentry_operations;
entry = HFS_I(dir)->entry;
dtype = HFS_ITYPE(dir->i_ino);
......@@ -154,6 +156,7 @@ static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry)
}
done:
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -189,6 +189,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
struct inode *result = NULL;
struct hpfs_inode_info *hpfs_result;
lock_kernel();
if ((err = hpfs_chk_name((char *)name, &len))) {
if (err == -ENAMETOOLONG) return ERR_PTR(-ENAMETOOLONG);
goto end_add;
......@@ -273,6 +274,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
hpfs_unlock_inode(dir);
end_add:
hpfs_set_dentry_operations(dentry);
unlock_kernel();
d_add(dentry, result);
return NULL;
......@@ -286,5 +288,6 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
/*bail:*/
hpfs_unlock_inode(dir);
unlock_kernel();
return ERR_PTR(-ENOENT);
}
......@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/config.h> /* Joliet? */
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
......@@ -167,6 +168,7 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
if (!page)
return ERR_PTR(-ENOMEM);
lock_kernel();
ino = isofs_find_entry(dir, dentry, page_address(page),
1024 + page_address(page));
__free_page(page);
......@@ -174,9 +176,12 @@ struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
inode = NULL;
if (ino) {
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......@@ -631,6 +631,8 @@ jffs_lookup(struct inode *dir, struct dentry *dentry)
len = dentry->d_name.len;
name = dentry->d_name.name;
lock_kernel();
D3({
char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
memcpy(s, name, len);
......@@ -698,6 +700,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry)
d_add(dentry, inode);
D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
up(&c->fmc->biglock);
unlock_kernel();
return NULL;
jffs_lookup_end:
......@@ -705,6 +708,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry)
up(&c->fmc->biglock);
jffs_lookup_end_no_biglock:
unlock_kernel();
return ERR_PTR(r);
} /* jffs_lookup() */
......
......@@ -43,6 +43,7 @@
#include <linux/jffs2_fs_i.h>
#include <linux/jffs2_fs_sb.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include "nodelist.h"
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)
D1(printk(KERN_DEBUG "jffs2_lookup()\n"));
lock_kernel();
dir_f = JFFS2_INODE_INFO(dir_i);
c = JFFS2_SB_INFO(dir_i->i_sb);
......@@ -118,10 +120,12 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
if (ino) {
inode = iget(dir_i->i_sb, ino);
if (!inode) {
unlock_kernel();
printk(KERN_WARNING "iget() failed for ino #%u\n", ino);
return (ERR_PTR(-EIO));
}
}
unlock_kernel();
d_add(target, inode);
......
......@@ -6,6 +6,7 @@
#include <linux/fs.h>
#include <linux/minix_fs.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
static inline void inc_count(struct inode *inode)
......@@ -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)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = minix_inode_by_name(dentry);
if (ino) {
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -12,6 +12,7 @@
#include <linux/time.h>
#include <linux/msdos_fs.h>
#include <linux/smp_lock.h>
#define MSDOS_DEBUG 0
#define PRINTK(x)
......@@ -215,6 +216,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
dentry->d_op = &msdos_dentry_operations;
lock_kernel();
res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
&de, &ino);
......@@ -231,6 +233,7 @@ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
out:
if (bh)
fat_brelse(sb, bh);
unlock_kernel();
return ERR_PTR(res);
}
......
......@@ -304,9 +304,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i
struct dentry * dentry = d_alloc(parent, name);
result = ERR_PTR(-ENOMEM);
if (dentry) {
lock_kernel();
result = dir->i_op->lookup(dir, dentry);
unlock_kernel();
if (result)
dput(dentry);
else
......@@ -778,9 +776,7 @@ struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
dentry = ERR_PTR(-ENOMEM);
if (!new)
goto out;
lock_kernel();
dentry = inode->i_op->lookup(inode, new);
unlock_kernel();
if (!dentry)
dentry = new;
else
......
......@@ -741,6 +741,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry)
int error, res, len = dentry->d_name.len + 1;
__u8 __name[len];
lock_kernel();
error = -EIO;
if (!ncp_conn_valid(server))
goto finished;
......@@ -785,6 +786,7 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry)
finished:
PPRINTK("ncp_lookup: result=%d\n", error);
unlock_kernel();
return ERR_PTR(error);
}
......
......@@ -579,6 +579,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
error = -ENOMEM;
dentry->d_op = &nfs_dentry_operations;
lock_kernel();
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
inode = NULL;
if (error == -ENOENT)
......@@ -593,6 +594,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
}
nfs_renew_times(dentry);
}
unlock_kernel();
out:
return ERR_PTR(error);
}
......
......@@ -529,6 +529,7 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
walk.name = NULL;
walk.namelen = 0;
/* Convert to wide string. */
lock_kernel();
err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name,
d->d_name.len, &walk.name, &walk.namelen);
if (err)
......@@ -548,10 +549,12 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
d_add(d, res);
ntfs_free(item);
ntfs_free(walk.name);
unlock_kernel();
/* Always return success, the dcache will handle negative entries. */
return NULL;
err_ret:
ntfs_free(walk.name);
unlock_kernel();
return ERR_PTR(err);
}
......
......@@ -633,6 +633,7 @@ static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentr
inode = NULL;
name = dentry->d_name.name;
len = dentry->d_name.len;
lock_kernel();
if (name [0] == '.' && len == 5 && !strncmp (name + 1, "node", 4)) {
ino = NODEP2INO(NODE(dir->i_ino).first_prop);
type = OPFSL_NODENUM;
......@@ -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);
if (ino)
type = OPFSL_DIR;
else
else {
unlock_kernel();
return ERR_PTR(-ENOENT);
}
}
inode = iget (dir->i_sb, ino);
unlock_kernel();
if (!inode)
return ERR_PTR(-EINVAL);
switch (type) {
......
......@@ -777,6 +777,7 @@ static struct dentry_operations pid_base_dentry_operations =
/* Lookups */
#define MAX_MULBY10 ((~0U-9)/10)
/* SMP-safe */
static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
{
unsigned int fd, c;
......@@ -855,6 +856,7 @@ static struct inode_operations proc_fd_inode_operations = {
permission: proc_permission,
};
/* SMP-safe */
static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
{
struct inode *inode;
......@@ -984,6 +986,7 @@ static struct inode_operations proc_self_inode_operations = {
follow_link: proc_self_follow_link,
};
/* SMP-safe */
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
{
unsigned int pid, c;
......
......@@ -258,12 +258,11 @@ static struct dentry_operations proc_dentry_operations =
*/
struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
{
struct inode *inode;
struct inode *inode = NULL;
struct proc_dir_entry * de;
int error;
int error = -ENOENT;
error = -ENOENT;
inode = NULL;
lock_kernel();
de = PDE(dir);
if (de) {
for (de = de->subdir; de ; de = de->next) {
......@@ -279,6 +278,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
}
}
}
unlock_kernel();
if (inode) {
dentry->d_op = &proc_dentry_operations;
......
......@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <asm/bitops.h>
#include <linux/smp_lock.h>
struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
......@@ -80,15 +81,14 @@ void __init proc_root_init(void)
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
{
if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
int nlink = proc_root.nlink;
nlink += nr_threads;
dir->i_nlink = nlink;
lock_kernel();
dir->i_nlink = proc_root.nlink + nr_threads;
unlock_kernel();
}
if (!proc_lookup(dir, dentry))
if (!proc_lookup(dir, dentry)) {
return NULL;
}
return proc_pid_lookup(dir, dentry);
}
......
......@@ -21,6 +21,7 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
/*
......@@ -115,6 +116,7 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry)
int len = dentry->d_name.len;
struct inode *foundinode = NULL;
lock_kernel();
if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
goto out;
/* The entry is linked, let's get the real info */
......@@ -127,10 +129,12 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry)
brelse(bh);
if ((foundinode = iget(dir->i_sb, ino)) == NULL) {
unlock_kernel();
QNX4DEBUG(("qnx4: lookup->iget -> NULL\n"));
return ERR_PTR(-EACCES);
}
out:
unlock_kernel();
d_add(dentry, foundinode);
return NULL;
......
......@@ -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
* exist, we know it is negative.
*/
/* SMP-safe */
static struct dentry * ramfs_lookup(struct inode *dir, struct dentry *dentry)
{
d_add(dentry, NULL);
......
......@@ -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))
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
de.de_gen_number_bit_string = 0;
retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
pathrelse (&path_to_entry);
if (retval == NAME_FOUND) {
inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
if (!inode || IS_ERR(inode)) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
......
......@@ -318,6 +318,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry)
res = -EACCES; /* placeholder for "no data here" */
offset = dir->i_ino & ROMFH_MASK;
lock_kernel();
if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
goto out;
......@@ -378,7 +379,8 @@ out0: inode = NULL;
outi: res = 0;
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)
if (dentry->d_name.len > SMB_MAXNAMELEN)
goto out;
lock_kernel();
error = smb_proc_getattr(dentry, &finfo);
#ifdef SMBFS_PARANOIA
if (error && error != -ENOENT)
......@@ -426,6 +427,7 @@ smb_lookup(struct inode *dir, struct dentry *dentry)
error = 0;
}
}
unlock_kernel();
out:
return ERR_PTR(error);
}
......
......@@ -15,6 +15,7 @@
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
static inline void inc_count(struct inode *inode)
{
......@@ -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;
if (dentry->d_name.len > SYSV_NAMELEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = sysv_inode_by_name(dentry);
if (ino) {
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -298,14 +298,17 @@ udf_lookup(struct inode *dir, struct dentry *dentry)
if (dentry->d_name.len > UDF_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
#ifdef UDF_RECOVERY
/* temporary shorthand for specifying files by inode number */
if (!strncmp(dentry->d_name.name, ".B=", 3) )
{
lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) };
inode = udf_iget(dir->i_sb, lb);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
else
#endif /* UDF_RECOVERY */
......@@ -317,9 +320,12 @@ udf_lookup(struct inode *dir, struct dentry *dentry)
udf_release_data(fibh.sbh);
inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
if ( !inode )
if ( !inode ) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -27,6 +27,7 @@
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/smp_lock.h>
#undef UFS_NAMEI_DEBUG
......@@ -68,12 +69,16 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)
if (dentry->d_name.len > UFS_MAXNAMLEN)
return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = ufs_inode_by_name(dir, dentry);
if (ino) {
inode = iget(dir->i_sb, ino);
if (!inode)
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
d_add(dentry, inode);
return NULL;
}
......
......@@ -21,6 +21,7 @@
#include <linux/msdos_fs.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#define DEBUG_LEVEL 0
#if (DEBUG_LEVEL >= 1)
......@@ -986,6 +987,7 @@ struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry)
PRINTK2(("vfat_lookup: name=%s, len=%d\n",
dentry->d_name.name, dentry->d_name.len));
lock_kernel();
table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
dentry->d_op = &vfat_dentry_ops[table];
......@@ -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);
fat_brelse(dir->i_sb, bh);
if (res)
if (res) {
unlock_kernel();
return ERR_PTR(res);
}
alias = d_find_alias(inode);
if (alias) {
if (d_invalidate(alias)==0)
dput(alias);
else {
iput(inode);
unlock_kernel();
return alias;
}
}
error:
unlock_kernel();
dentry->d_op = &vfat_dentry_ops[table];
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_add(dentry,inode);
......
......@@ -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
* exist, we know it is negative.
*/
/* SMP-safe */
static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
{
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