From: Dave Hansen <haveblue@us.ibm.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] shift BKL out of vfs_readdir
Date: Wed, 24 Apr 2002 16:23:26 -0700 [thread overview]
Message-ID: <3CC73E6E.9090405@us.ibm.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 661 bytes --]
Oh boy, here's another one. This patch takes the BKL out of
vfs_readdir() and moves it into the individual filesystems, all 35 of
them. I have the feeling that this wasn't done before because there are
a lot of these to change and it was a pain to find them all. I
definitely got all of those that were defined in the in the structure
declaration like this "readdir: fs_readdir;" vxfs_readdir was assigned
strangely, but I found it anyway. I also left devfs out of this one.
Richard seems confident that devfs has no need for the BKL.
Anyway, patch attached. Unlike the last one, this one actually compiles :)
--
Dave Hansen
haveblue@us.ibm.com
[-- Attachment #2: vfs_readdir-bkl_shift-2.5.9-7.patch --]
[-- Type: text/plain, Size: 45777 bytes --]
diff -ur linux-2.5.10/Documentation/filesystems/Locking linux-2.5.10-dirty/Documentation/filesystems/Locking
--- linux-2.5.10/Documentation/filesystems/Locking Wed Apr 24 00:15:15 2002
+++ linux-2.5.10-dirty/Documentation/filesystems/Locking Wed Apr 24 16:07:07 2002
@@ -254,7 +254,7 @@
llseek: yes (see below)
read: no
write: no
-readdir: yes (see below)
+readdir: no
poll: no
ioctl: yes (see below)
mmap: no
diff -ur linux-2.5.10/drivers/isdn/capi/capifs.c linux-2.5.10-dirty/drivers/isdn/capi/capifs.c
--- linux-2.5.10/drivers/isdn/capi/capifs.c Wed Apr 24 00:15:13 2002
+++ linux-2.5.10-dirty/drivers/isdn/capi/capifs.c Wed Apr 24 15:50:15 2002
@@ -97,18 +97,20 @@
off_t nr;
char numbuf[32];
+ lock_kernel();
+
nr = filp->f_pos;
switch(nr)
{
case 0:
if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos = ++nr;
/* fall through */
case 1:
if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos = ++nr;
/* fall through */
default:
@@ -120,13 +122,15 @@
if (np->type) *p++ = np->type;
sprintf(p, "%u", np->num);
if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_UNKNOWN) < 0 )
- return 0;
+ goto out;
}
filp->f_pos = ++nr;
}
break;
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/adfs/dir.c linux-2.5.10-dirty/fs/adfs/dir.c
--- linux-2.5.10/fs/adfs/dir.c Wed Apr 24 00:15:10 2002
+++ linux-2.5.10-dirty/fs/adfs/dir.c Wed Apr 24 15:50:15 2002
@@ -36,6 +36,8 @@
struct adfs_dir dir;
int ret = 0;
+ lock_kernel();
+
if (filp->f_pos >> 32)
goto out;
@@ -77,6 +79,7 @@
ops->free(&dir);
out:
+ unlock_kernel();
return ret;
}
diff -ur linux-2.5.10/fs/affs/dir.c linux-2.5.10-dirty/fs/affs/dir.c
--- linux-2.5.10/fs/affs/dir.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/affs/dir.c Wed Apr 24 15:50:15 2002
@@ -22,6 +22,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/amigaffs.h>
+#include <linux/smp_lock.h>
static int affs_readdir(struct file *, void *, filldir_t);
@@ -63,6 +64,8 @@
int stored;
int res;
+ lock_kernel();
+
pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)filp->f_pos);
stored = 0;
@@ -158,6 +161,7 @@
affs_brelse(dir_bh);
affs_brelse(fh_bh);
affs_unlock_dir(inode);
+ unlock_kernel();
pr_debug("AFFS: readdir()=%d\n", stored);
return res;
}
diff -ur linux-2.5.10/fs/autofs/root.c linux-2.5.10-dirty/fs/autofs/root.c
--- linux-2.5.10/fs/autofs/root.c Wed Apr 24 00:15:19 2002
+++ linux-2.5.10-dirty/fs/autofs/root.c Wed Apr 24 15:50:15 2002
@@ -47,6 +47,8 @@
struct inode * inode = filp->f_dentry->d_inode;
off_t onr, nr;
+ lock_kernel();
+
sbi = autofs_sbi(inode->i_sb);
dirhash = &sbi->dirhash;
nr = filp->f_pos;
@@ -55,25 +57,27 @@
{
case 0:
if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos = ++nr;
/* fall through */
case 1:
if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos = ++nr;
/* fall through */
default:
while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent) ) {
if ( !ent->dentry || d_mountpoint(ent->dentry) ) {
if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0)
- return 0;
+ goto out;
filp->f_pos = nr;
}
}
break;
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/bad_inode.c linux-2.5.10-dirty/fs/bad_inode.c
--- linux-2.5.10/fs/bad_inode.c Wed Apr 24 00:15:12 2002
+++ linux-2.5.10-dirty/fs/bad_inode.c Wed Apr 24 15:50:15 2002
@@ -9,6 +9,7 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/time.h>
+#include <linux/smp_lock.h>
/*
* The follow_link operation is special: it must behave as a no-op
diff -ur linux-2.5.10/fs/bfs/dir.c linux-2.5.10-dirty/fs/bfs/dir.c
--- linux-2.5.10/fs/bfs/dir.c Wed Apr 24 00:15:22 2002
+++ linux-2.5.10-dirty/fs/bfs/dir.c Wed Apr 24 15:50:15 2002
@@ -32,9 +32,12 @@
unsigned int offset;
int block;
+ lock_kernel();
+
if (f->f_pos & (BFS_DIRENT_SIZE-1)) {
printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos,
dir->i_sb->s_id, dir->i_ino);
+ unlock_kernel();
return -EBADF;
}
@@ -52,6 +55,7 @@
int size = strnlen(de->name, BFS_NAMELEN);
if (filldir(dirent, de->name, size, f->f_pos, de->ino, DT_UNKNOWN) < 0) {
brelse(bh);
+ unlock_kernel();
return 0;
}
}
@@ -62,6 +66,7 @@
}
UPDATE_ATIME(dir);
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/cramfs/inode.c linux-2.5.10-dirty/fs/cramfs/inode.c
--- linux-2.5.10/fs/cramfs/inode.c Wed Apr 24 00:15:09 2002
+++ linux-2.5.10-dirty/fs/cramfs/inode.c Wed Apr 24 15:50:15 2002
@@ -293,6 +293,8 @@
if (offset & 3)
return -EINVAL;
+ lock_kernel();
+
copied = 0;
while (offset < inode->i_size) {
struct cramfs_inode *de;
@@ -313,8 +315,10 @@
namelen = de->namelen << 2;
nextoffset = offset + sizeof(*de) + namelen;
for (;;) {
- if (!namelen)
+ if (!namelen) {
+ unlock_kernel();
return -EIO;
+ }
if (name[namelen-1])
break;
namelen--;
@@ -327,6 +331,7 @@
filp->f_pos = offset;
copied++;
}
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/devpts/root.c linux-2.5.10-dirty/fs/devpts/root.c
--- linux-2.5.10/fs/devpts/root.c Wed Apr 24 00:15:08 2002
+++ linux-2.5.10-dirty/fs/devpts/root.c Wed Apr 24 15:50:15 2002
@@ -48,18 +48,20 @@
off_t nr;
char numbuf[16];
+ lock_kernel();
+
nr = filp->f_pos;
switch(nr)
{
case 0:
if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos = ++nr;
/* fall through */
case 1:
if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos = ++nr;
/* fall through */
default:
@@ -68,13 +70,15 @@
if ( sbi->inodes[ptynr] ) {
genptsname(numbuf, ptynr);
if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 )
- return 0;
+ goto out;
}
filp->f_pos = ++nr;
}
break;
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/efs/dir.c linux-2.5.10-dirty/fs/efs/dir.c
--- linux-2.5.10/fs/efs/dir.c Wed Apr 24 00:15:21 2002
+++ linux-2.5.10-dirty/fs/efs/dir.c Wed Apr 24 15:50:15 2002
@@ -5,6 +5,7 @@
*/
#include <linux/efs_fs.h>
+#include <linux/smp_lock.h>
static int efs_readdir(struct file *, void *, filldir_t);
@@ -31,6 +32,8 @@
if (inode->i_size & (EFS_DIRBSIZE-1))
printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n");
+ lock_kernel();
+
/* work out where this entry can be found */
block = filp->f_pos >> EFS_DIRBSIZE_BITS;
@@ -91,7 +94,7 @@
}
brelse(bh);
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
- return 0;
+ goto out;
}
slot++;
}
@@ -102,6 +105,8 @@
}
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/ext2/dir.c linux-2.5.10-dirty/fs/ext2/dir.c
--- linux-2.5.10/fs/ext2/dir.c Wed Apr 24 00:15:08 2002
+++ linux-2.5.10-dirty/fs/ext2/dir.c Wed Apr 24 15:50:15 2002
@@ -23,6 +23,7 @@
#include "ext2.h"
#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
@@ -246,6 +247,8 @@
unsigned char *types = NULL;
int need_revalidate = (filp->f_version != inode->i_version);
+ lock_kernel();
+
if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
goto done;
@@ -290,6 +293,7 @@
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
filp->f_version = inode->i_version;
UPDATE_ATIME(inode);
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/ext3/dir.c linux-2.5.10-dirty/fs/ext3/dir.c
--- linux-2.5.10/fs/ext3/dir.c Wed Apr 24 00:15:20 2002
+++ linux-2.5.10-dirty/fs/ext3/dir.c Wed Apr 24 16:10:07 2002
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/jbd.h>
#include <linux/ext3_fs.h>
+#include <linux/smp_lock.h>
static unsigned char ext3_filetype_table[] = {
DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
@@ -30,7 +31,7 @@
struct file_operations ext3_dir_operations = {
read: generic_read_dir,
- readdir: ext3_readdir, /* BKL held */
+ readdir: ext3_readdir, /* we take BKL. needed?*/
ioctl: ext3_ioctl, /* BKL held */
fsync: ext3_sync_file, /* BKL held */
};
@@ -77,6 +78,8 @@
int err;
struct inode *inode = filp->f_dentry->d_inode;
+ lock_kernel();
+
sb = inode->i_sb;
stored = 0;
@@ -150,6 +153,7 @@
filp->f_pos = (filp->f_pos |
(sb->s_blocksize - 1)) + 1;
brelse (bh);
+ unlock_kernel();
return stored;
}
offset += le16_to_cpu(de->rec_len);
@@ -186,5 +190,6 @@
brelse (bh);
}
UPDATE_ATIME(inode);
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/fat/dir.c linux-2.5.10-dirty/fs/fat/dir.c
--- linux-2.5.10/fs/fat/dir.c Wed Apr 24 00:15:09 2002
+++ linux-2.5.10-dirty/fs/fat/dir.c Wed Apr 24 15:50:15 2002
@@ -17,6 +17,7 @@
#include <linux/time.h>
#include <linux/msdos_fs.h>
#include <linux/dirent.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -363,13 +364,16 @@
unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname;
int ino, inum, chi, chl, i, i2, j, last, last_u, dotoffset = 0;
loff_t cpos;
+ int ret = 0;
+
+ lock_kernel();
cpos = filp->f_pos;
/* Fake . and .. for the root directory. */
if (inode->i_ino == MSDOS_ROOT_INO) {
while (cpos < 2) {
if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0)
- return 0;
+ goto out;
cpos++;
filp->f_pos++;
}
@@ -379,8 +383,10 @@
cpos = 0;
}
}
- if (cpos & (sizeof(struct msdos_dir_entry)-1))
- return -ENOENT;
+ if (cpos & (sizeof(struct msdos_dir_entry)-1)) {
+ ret = -ENOENT;
+ goto out;
+ }
bh = NULL;
GetNew:
@@ -414,7 +420,8 @@
if (!unicode) {
filp->f_pos = cpos;
fat_brelse(sb, bh);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
}
ParseLong:
@@ -580,7 +587,9 @@
if (unicode) {
free_page((unsigned long) unicode);
}
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
diff -ur linux-2.5.10/fs/freevxfs/vxfs_lookup.c linux-2.5.10-dirty/fs/freevxfs/vxfs_lookup.c
--- linux-2.5.10/fs/freevxfs/vxfs_lookup.c Wed Apr 24 00:15:19 2002
+++ linux-2.5.10-dirty/fs/freevxfs/vxfs_lookup.c Wed Apr 24 16:20:09 2002
@@ -262,8 +262,10 @@
pos = fp->f_pos - 2;
- if (pos > VXFS_DIRROUND(ip->i_size))
+ if (pos > VXFS_DIRROUND(ip->i_size)) {
+ unlock_kernel();
return 0;
+ }
npages = dir_pages(ip);
nblocks = dir_blocks(ip);
@@ -322,5 +324,6 @@
done:
fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/hfs/dir_cap.c linux-2.5.10-dirty/fs/hfs/dir_cap.c
--- linux-2.5.10/fs/hfs/dir_cap.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/hfs/dir_cap.c Wed Apr 24 15:50:15 2002
@@ -188,6 +188,8 @@
struct hfs_cat_entry *entry;
struct inode *dir = filp->f_dentry->d_inode;
+ lock_kernel();
+
entry = HFS_I(dir)->entry;
type = HFS_ITYPE(dir->i_ino);
skip_dirs = (type == HFS_CAP_RDIR);
@@ -195,7 +197,7 @@
if (filp->f_pos == 0) {
/* Entry 0 is for "." */
if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, DT_DIR)) {
- return 0;
+ goto out;
}
filp->f_pos = 1;
}
@@ -212,7 +214,7 @@
if (filldir(dirent, DOT_DOT->Name,
DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) {
- return 0;
+ goto out;
}
filp->f_pos = 2;
}
@@ -223,11 +225,11 @@
if (hfs_cat_open(entry, &brec) ||
hfs_cat_next(entry, &brec, filp->f_pos - 2, &cnid, &type)) {
- return 0;
+ goto out;
}
while (filp->f_pos < (dir->i_size - 3)) {
if (hfs_cat_next(entry, &brec, 1, &cnid, &type)) {
- return 0;
+ goto out;
}
if (!skip_dirs || (type != HFS_CDR_DIR)) {
ino_t ino;
@@ -240,7 +242,7 @@
if (filldir(dirent, tmp_name, len,
filp->f_pos, ino, DT_UNKNOWN)) {
hfs_cat_close(entry, &brec);
- return 0;
+ goto out;
}
}
++filp->f_pos;
@@ -256,7 +258,7 @@
DOT_ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_FNDR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
}
++filp->f_pos;
@@ -269,7 +271,7 @@
DOT_FINDERINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_FDIR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
}
++filp->f_pos;
@@ -282,12 +284,14 @@
DOT_RESOURCE_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_RDIR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
}
++filp->f_pos;
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/hfs/dir_dbl.c linux-2.5.10-dirty/fs/hfs/dir_dbl.c
--- linux-2.5.10/fs/hfs/dir_dbl.c Wed Apr 24 00:15:15 2002
+++ linux-2.5.10-dirty/fs/hfs/dir_dbl.c Wed Apr 24 15:50:15 2002
@@ -182,13 +182,15 @@
struct hfs_cat_entry *entry;
struct inode *dir = filp->f_dentry->d_inode;
+ lock_kernel();
+
entry = HFS_I(dir)->entry;
if (filp->f_pos == 0) {
/* Entry 0 is for "." */
if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino,
DT_DIR)) {
- return 0;
+ goto out;
}
filp->f_pos = 1;
}
@@ -197,7 +199,7 @@
/* Entry 1 is for ".." */
if (filldir(dirent, DOT_DOT->Name, DOT_DOT_LEN, 1,
hfs_get_hl(entry->key.ParID), DT_DIR)) {
- return 0;
+ goto out;
}
filp->f_pos = 2;
}
@@ -209,7 +211,7 @@
if (hfs_cat_open(entry, &brec) ||
hfs_cat_next(entry, &brec, (filp->f_pos - 1) >> 1,
&cnid, &type)) {
- return 0;
+ goto out;
}
while (filp->f_pos < (dir->i_size - 1)) {
@@ -226,7 +228,7 @@
} else {
if (hfs_cat_next(entry, &brec, 1,
&cnid, &type)) {
- return 0;
+ goto out;
}
ino = ntohl(cnid);
len = hfs_namein(dir, tmp_name,
@@ -236,7 +238,7 @@
if (filldir(dirent, tmp_name, len, filp->f_pos, ino,
DT_UNKNOWN)) {
hfs_cat_close(entry, &brec);
- return 0;
+ goto out;
}
++filp->f_pos;
}
@@ -250,12 +252,14 @@
PCNT_ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_DBL_HDR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
}
++filp->f_pos;
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/hfs/dir_nat.c linux-2.5.10-dirty/fs/hfs/dir_nat.c
--- linux-2.5.10/fs/hfs/dir_nat.c Wed Apr 24 00:15:23 2002
+++ linux-2.5.10-dirty/fs/hfs/dir_nat.c Wed Apr 24 15:50:15 2002
@@ -188,6 +188,8 @@
struct hfs_cat_entry *entry;
struct inode *dir = filp->f_dentry->d_inode;
+ lock_kernel();
+
entry = HFS_I(dir)->entry;
type = HFS_ITYPE(dir->i_ino);
skip_dirs = (type == HFS_NAT_HDIR);
@@ -196,7 +198,7 @@
/* Entry 0 is for "." */
if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino,
DT_DIR)) {
- return 0;
+ goto out;
}
filp->f_pos = 1;
}
@@ -213,7 +215,7 @@
if (filldir(dirent, DOT_DOT->Name,
DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) {
- return 0;
+ goto out;
}
filp->f_pos = 2;
}
@@ -224,11 +226,11 @@
if (hfs_cat_open(entry, &brec) ||
hfs_cat_next(entry, &brec, filp->f_pos - 2, &cnid, &type)) {
- return 0;
+ goto out;
}
while (filp->f_pos < (dir->i_size - 2)) {
if (hfs_cat_next(entry, &brec, 1, &cnid, &type)) {
- return 0;
+ goto out;
}
if (!skip_dirs || (type != HFS_CDR_DIR)) {
ino_t ino;
@@ -241,7 +243,7 @@
if (filldir(dirent, tmp_name, len,
filp->f_pos, ino, DT_UNKNOWN)) {
hfs_cat_close(entry, &brec);
- return 0;
+ goto out;
}
}
++filp->f_pos;
@@ -256,7 +258,7 @@
DOT_APPLEDOUBLE_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDIR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
} else if (type == HFS_NAT_HDIR) {
/* In .AppleDouble entry 2 is for ".Parent" */
@@ -264,7 +266,7 @@
DOT_PARENT_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
}
++filp->f_pos;
@@ -278,12 +280,14 @@
ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDR,
DT_UNKNOWN)) {
- return 0;
+ goto out;
}
}
++filp->f_pos;
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/hpfs/dir.c linux-2.5.10-dirty/fs/hpfs/dir.c
--- linux-2.5.10/fs/hpfs/dir.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/hpfs/dir.c Wed Apr 24 15:50:15 2002
@@ -62,19 +62,26 @@
long old_pos;
char *tempname;
int c1, c2 = 0;
+ int ret = 0;
if (inode->i_sb->s_hpfs_chk) {
- if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode"))
- return -EFSERROR;
- if (hpfs_chk_sectors(inode->i_sb, hpfs_inode->i_dno, 4, "dir_dnode"))
- return -EFSERROR;
+ if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
+ ret = -EFSERROR;
+ goto out;
+ }
+ if (hpfs_chk_sectors(inode->i_sb, hpfs_inode->i_dno, 4, "dir_dnode")) {
+ ret = -EFSERROR;
+ goto out;
+ }
}
if (inode->i_sb->s_hpfs_chk >= 2) {
struct buffer_head *bh;
struct fnode *fno;
int e = 0;
- if (!(fno = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh)))
- return -EIOERROR;
+ if (!(fno = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) {
+ ret = -EIOERROR;
+ goto out;
+ }
if (!fno->dirflag) {
e = 1;
hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino);
@@ -84,14 +91,20 @@
hpfs_error(inode->i_sb, "corrupted inode: i_dno == %08x, fnode -> dnode == %08x", hpfs_inode->i_dno, fno->u.external[0].disk_secno);
}
brelse(bh);
- if (e) return -EFSERROR;
+ if (e) {
+ ret = -EFSERROR;
+ goto out;
+ }
}
lc = inode->i_sb->s_hpfs_lowercase;
if (filp->f_pos == 12) { /* diff -r requires this (note, that diff -r */
filp->f_pos = 13; /* also fails on msdos filesystem in 2.0) */
- return 0;
+ goto out;
+ }
+ if (filp->f_pos == 13) {
+ ret = -ENOENT;
+ goto out;
}
- if (filp->f_pos == 13) return -ENOENT;
hpfs_lock_inode(inode);
@@ -103,28 +116,29 @@
if (inode->i_sb->s_hpfs_chk)
if (hpfs_stop_cycles(inode->i_sb, filp->f_pos, &c1, &c2, "hpfs_readdir")) {
hpfs_unlock_inode(inode);
- return -EFSERROR;
+ ret = -EFSERROR;
+ goto out;
}
if (filp->f_pos == 12) {
hpfs_unlock_inode(inode);
- return 0;
+ goto out;
}
if (filp->f_pos == 3 || filp->f_pos == 4 || filp->f_pos == 5) {
printk("HPFS: warning: pos==%d\n",(int)filp->f_pos);
hpfs_unlock_inode(inode);
- return 0;
+ goto out;
}
if (filp->f_pos == 0) {
if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
hpfs_unlock_inode(inode);
- return 0;
+ goto out;
}
filp->f_pos = 11;
}
if (filp->f_pos == 11) {
if (filldir(dirent, "..", 2, filp->f_pos, hpfs_inode->i_parent_dir, DT_DIR) < 0) {
hpfs_unlock_inode(inode);
- return 0;
+ goto out;
}
filp->f_pos = 1;
}
@@ -135,12 +149,14 @@
}
/*if (filp->f_version != inode->i_version) {
hpfs_unlock_inode(inode);
- return -ENOENT;
+ ret = -ENOENT;
+ goto out;
}*/
old_pos = filp->f_pos;
if (!(de = map_pos_dirent(inode, &filp->f_pos, &qbh))) {
hpfs_unlock_inode(inode);
- return -EIOERROR;
+ ret = -EIOERROR;
+ goto out;
}
if (de->first || de->last) {
if (inode->i_sb->s_hpfs_chk) {
@@ -156,11 +172,14 @@
if (tempname != (char *)de->name) kfree(tempname);
hpfs_brelse4(&qbh);
hpfs_unlock_inode(inode);
- return 0;
+ goto out;
}
if (tempname != (char *)de->name) kfree(tempname);
hpfs_brelse4(&qbh);
}
+out:
+ unlock_kernel();
+ return ret;
}
/*
diff -ur linux-2.5.10/fs/isofs/dir.c linux-2.5.10-dirty/fs/isofs/dir.c
--- linux-2.5.10/fs/isofs/dir.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/isofs/dir.c Wed Apr 24 15:50:15 2002
@@ -21,6 +21,7 @@
#include <linux/time.h>
#include <linux/locks.h>
#include <linux/config.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -253,6 +254,8 @@
struct iso_directory_record * tmpde;
struct inode *inode = filp->f_dentry->d_inode;
+ lock_kernel();
+
tmpname = (char *) __get_free_page(GFP_KERNEL);
if (!tmpname)
return -ENOMEM;
@@ -261,5 +264,6 @@
result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde);
free_page((unsigned long) tmpname);
+ unlock_kernel();
return result;
}
diff -ur linux-2.5.10/fs/jffs/inode-v23.c linux-2.5.10-dirty/fs/jffs/inode-v23.c
--- linux-2.5.10/fs/jffs/inode-v23.c Wed Apr 24 00:15:20 2002
+++ linux-2.5.10-dirty/fs/jffs/inode-v23.c Wed Apr 24 15:50:15 2002
@@ -48,6 +48,7 @@
#include <linux/stat.h>
#include <linux/blkdev.h>
#include <linux/quotaops.h>
+#include <linux/smp_lock.h>
#include <asm/semaphore.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
@@ -568,6 +569,7 @@
struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
int j;
int ddino;
+ lock_kernel();
D3(printk (KERN_NOTICE "readdir(): down biglock\n"));
down(&c->fmc->biglock);
@@ -577,6 +579,7 @@
if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock);
+ unlock_kernel();
return 0;
}
filp->f_pos = 1;
@@ -593,6 +596,7 @@
if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock);
+ unlock_kernel();
return 0;
}
filp->f_pos++;
@@ -611,6 +615,7 @@
filp->f_pos , f->ino, DT_UNKNOWN) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock);
+ unlock_kernel();
return 0;
}
filp->f_pos++;
@@ -620,6 +625,7 @@
}
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock);
+ unlock_kernel();
return filp->f_pos;
} /* jffs_readdir() */
diff -ur linux-2.5.10/fs/jffs2/dir.c linux-2.5.10-dirty/fs/jffs2/dir.c
--- linux-2.5.10/fs/jffs2/dir.c Wed Apr 24 00:15:13 2002
+++ linux-2.5.10-dirty/fs/jffs2/dir.c Wed Apr 24 15:50:15 2002
@@ -45,6 +45,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);
@@ -143,6 +144,8 @@
D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_dentry->d_inode->i_ino));
+ lock_kernel();
+
f = JFFS2_INODE_INFO(inode);
c = JFFS2_SB_INFO(inode->i_sb);
@@ -186,6 +189,7 @@
up(&f->sem);
out:
filp->f_pos = offset;
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/jfs/jfs_dtree.c linux-2.5.10-dirty/fs/jfs/jfs_dtree.c
--- linux-2.5.10/fs/jfs/jfs_dtree.c Wed Apr 24 00:15:12 2002
+++ linux-2.5.10-dirty/fs/jfs/jfs_dtree.c Wed Apr 24 15:50:15 2002
@@ -102,6 +102,7 @@
#include <linux/fs.h>
#include <linux/locks.h>
+#include <linux/smp_lock.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_filsys.h"
@@ -2868,6 +2869,8 @@
if (filp->f_pos == DIREND)
return 0;
+ lock_kernel();
+
if (DO_INDEX(ip)) {
/*
* persistent index is stored in directory entries.
@@ -2885,12 +2888,14 @@
if (dtEmpty(ip)) {
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
repeat:
rc = get_index(ip, dir_index, &dirtab_slot);
if (rc) {
filp->f_pos = DIREND;
+ unlock_kernel();
return rc;
}
if (dirtab_slot.flag == DIR_INDEX_FREE) {
@@ -2898,11 +2903,13 @@
jERROR(1, ("jfs_readdir detected "
"infinite loop!\n"));
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
dir_index = le32_to_cpu(dirtab_slot.addr2);
if (dir_index == -1) {
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
goto repeat;
@@ -2912,12 +2919,14 @@
DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
if (rc) {
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
if (p->header.flag & BT_INTERNAL) {
jERROR(1,("jfs_readdir: bad index table\n"));
DT_PUTPAGE(mp);
filp->f_pos = -1;
+ unlock_kernel();
return 0;
}
} else {
@@ -2927,27 +2936,34 @@
*/
filp->f_pos = 0;
if (filldir(dirent, ".", 1, 0, ip->i_ino,
- DT_DIR))
+ DT_DIR)) {
+ unlock_kernel();
return 0;
+ }
}
/*
* parent ".."
*/
filp->f_pos = 1;
if (filldir
- (dirent, "..", 2, 1, PARENT(ip), DT_DIR))
+ (dirent, "..", 2, 1, PARENT(ip), DT_DIR)) {
+ unlock_kernel();
return 0;
+ }
/*
* Find first entry of left-most leaf
*/
if (dtEmpty(ip)) {
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
- if ((rc = dtReadFirst(ip, &btstack)))
+ if ((rc = dtReadFirst(ip, &btstack))) {
+ unlock_kernel();
return -rc;
+ }
DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
}
@@ -2966,8 +2982,10 @@
/* build "." entry */
if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino,
- DT_DIR))
+ DT_DIR)) {
+ unlock_kernel();
return 0;
+ }
dtoffset->index = 1;
}
@@ -2976,8 +2994,10 @@
/* build ".." entry */
if (filldir(dirent, "..", 2, filp->f_pos,
- PARENT(ip), DT_DIR))
+ PARENT(ip), DT_DIR)) {
+ unlock_kernel();
return 0;
+ }
} else {
jERROR(1,
("jfs_readdir called with invalid offset!\n"));
@@ -2988,6 +3008,7 @@
if (dtEmpty(ip)) {
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
@@ -2996,6 +3017,7 @@
("jfs_readdir: unexpected rc = %d from dtReadNext\n",
rc));
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
/* get start leaf page and index */
@@ -3004,6 +3026,7 @@
/* offset beyond directory eof ? */
if (bn < 0) {
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
}
@@ -3013,6 +3036,7 @@
DT_PUTPAGE(mp);
jERROR(1, ("jfs_readdir: kmalloc failed!\n"));
filp->f_pos = DIREND;
+ unlock_kernel();
return 0;
}
while (1) {
@@ -3087,6 +3111,7 @@
DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
if (rc) {
kfree(d_name);
+ unlock_kernel();
return -rc;
}
@@ -3102,7 +3127,7 @@
out:
kfree(d_name);
DT_PUTPAGE(mp);
-
+ unlock_kernel();
return rc;
}
diff -ur linux-2.5.10/fs/libfs.c linux-2.5.10-dirty/fs/libfs.c
--- linux-2.5.10/fs/libfs.c Wed Apr 24 00:15:08 2002
+++ linux-2.5.10-dirty/fs/libfs.c Wed Apr 24 15:50:15 2002
@@ -4,6 +4,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
int simple_statfs(struct super_block *sb, struct statfs *buf)
{
@@ -40,6 +41,8 @@
int i;
struct dentry *dentry = filp->f_dentry;
+ lock_kernel();
+
i = filp->f_pos;
switch (i) {
case 0:
@@ -64,6 +67,7 @@
for (;;) {
if (list == &dentry->d_subdirs) {
spin_unlock(&dcache_lock);
+ unlock_kernel();
return 0;
}
if (!j)
@@ -94,6 +98,7 @@
}
}
}
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/minix/dir.c linux-2.5.10-dirty/fs/minix/dir.c
--- linux-2.5.10/fs/minix/dir.c Wed Apr 24 00:15:13 2002
+++ linux-2.5.10-dirty/fs/minix/dir.c Wed Apr 24 15:50:15 2002
@@ -7,6 +7,7 @@
*/
#include "minix.h"
+#include <linux/smp_lock.h>
typedef struct minix_dir_entry minix_dirent;
@@ -78,6 +79,8 @@
struct minix_sb_info *sbi = minix_sb(sb);
unsigned chunk_size = sbi->s_dirsize;
+ lock_kernel();
+
pos = (pos + chunk_size-1) & ~(chunk_size-1);
if (pos >= inode->i_size)
goto done;
@@ -113,6 +116,7 @@
done:
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode);
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/ncpfs/dir.c linux-2.5.10-dirty/fs/ncpfs/dir.c
--- linux-2.5.10/fs/ncpfs/dir.c Wed Apr 24 00:15:08 2002
+++ linux-2.5.10-dirty/fs/ncpfs/dir.c Wed Apr 24 15:50:15 2002
@@ -400,6 +400,8 @@
int result, mtime_valid = 0;
time_t mtime = 0;
+ lock_kernel();
+
ctl.page = NULL;
ctl.cache = NULL;
@@ -533,6 +535,7 @@
page_cache_release(ctl.page);
}
out:
+ unlock_kernel();
return result;
}
diff -ur linux-2.5.10/fs/nfs/dir.c linux-2.5.10-dirty/fs/nfs/dir.c
--- linux-2.5.10/fs/nfs/dir.c Wed Apr 24 00:15:19 2002
+++ linux-2.5.10-dirty/fs/nfs/dir.c Wed Apr 24 15:50:15 2002
@@ -355,9 +355,13 @@
struct nfs_entry my_entry;
long res;
+ lock_kernel();
+
res = nfs_revalidate(dentry);
- if (res < 0)
+ if (res < 0) {
+ unlock_kernel();
return res;
+ }
/*
* filp->f_pos points to the file offset in the page cache.
@@ -394,6 +398,7 @@
break;
}
}
+ unlock_kernel();
if (desc->error < 0)
return desc->error;
if (res < 0)
diff -ur linux-2.5.10/fs/nfs/nfs3proc.c linux-2.5.10-dirty/fs/nfs/nfs3proc.c
--- linux-2.5.10/fs/nfs/nfs3proc.c Wed Apr 24 00:15:19 2002
+++ linux-2.5.10-dirty/fs/nfs/nfs3proc.c Wed Apr 24 15:50:15 2002
@@ -14,6 +14,7 @@
#include <linux/nfs.h>
#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
+#include <linux/smp_lock.h>
#define NFSDBG_FACILITY NFSDBG_PROC
@@ -560,6 +561,8 @@
u32 *verf = NFS_COOKIEVERF(dir);
int status;
+ lock_kernel();
+
arg.buffer = entry;
arg.bufsiz = size;
arg.verf[0] = verf[0];
@@ -580,6 +583,7 @@
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_refresh_inode(dir, &dir_attr);
dprintk("NFS reply readdir: %d\n", status);
+ unlock_kernel();
return status;
}
diff -ur linux-2.5.10/fs/nfs/proc.c linux-2.5.10-dirty/fs/nfs/proc.c
--- linux-2.5.10/fs/nfs/proc.c Wed Apr 24 00:15:16 2002
+++ linux-2.5.10-dirty/fs/nfs/proc.c Wed Apr 24 15:50:15 2002
@@ -41,6 +41,7 @@
#include <linux/nfs.h>
#include <linux/nfs2.h>
#include <linux/nfs_fs.h>
+#include <linux/smp_lock.h>
#define NFSDBG_FACILITY NFSDBG_PROC
@@ -440,6 +441,8 @@
};
int status;
+ lock_kernel();
+
arg.fh = NFS_FH(dir);
arg.cookie = cookie;
arg.buffer = entry;
@@ -451,6 +454,7 @@
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
dprintk("NFS reply readdir: %d\n", status);
+ unlock_kernel();
return status;
}
diff -ur linux-2.5.10/fs/ntfs/fs.c linux-2.5.10-dirty/fs/ntfs/fs.c
--- linux-2.5.10/fs/ntfs/fs.c Wed Apr 24 00:15:12 2002
+++ linux-2.5.10-dirty/fs/ntfs/fs.c Wed Apr 24 15:50:15 2002
@@ -250,6 +250,8 @@
int err;
struct ntfs_filldir cb;
+ lock_kernel();
+
cb.ret_code = 0;
cb.pl = filp->f_pos & 0xffff;
cb.ph = (filp->f_pos >> 16) & 0x7fff;
@@ -312,10 +314,12 @@
"returned %i, returning 0, f_pos "
"0x%Lx.\n", cb.ret_code, filp->f_pos);
#endif
+ unlock_kernel();
return 0;
}
ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning %i, f_pos 0x%Lx.\n",
err, filp->f_pos);
+ unlock_kernel();
return err;
}
diff -ur linux-2.5.10/fs/openpromfs/inode.c linux-2.5.10-dirty/fs/openpromfs/inode.c
--- linux-2.5.10/fs/openpromfs/inode.c Wed Apr 24 00:15:18 2002
+++ linux-2.5.10-dirty/fs/openpromfs/inode.c Wed Apr 24 15:50:15 2002
@@ -756,12 +756,14 @@
u16 node;
char *p;
char buffer2[64];
+
+ lock_kernel();
ino = inode->i_ino;
i = filp->f_pos;
switch (i) {
case 0:
- if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) return 0;
+ if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) goto out;
i++;
filp->f_pos++;
/* fall thru */
@@ -769,7 +771,7 @@
if (filldir(dirent, "..", 2, i,
(NODE(ino).parent == 0xffff) ?
OPENPROM_ROOT_INO : NODE2INO(NODE(ino).parent), DT_DIR) < 0)
- return 0;
+ goto out;
i++;
filp->f_pos++;
/* fall thru */
@@ -782,17 +784,17 @@
}
while (node != 0xffff) {
if (prom_getname (nodes[node].node, buffer, 128) < 0)
- return 0;
+ goto out;
if (filldir(dirent, buffer, strlen(buffer),
filp->f_pos, NODE2INO(node), DT_DIR) < 0)
- return 0;
+ goto out;
filp->f_pos++;
node = nodes[node].next;
}
j = NODEP2INO(NODE(ino).first_prop);
if (!i) {
if (filldir(dirent, ".node", 5, filp->f_pos, j, DT_REG) < 0)
- return 0;
+ goto out;
filp->f_pos++;
} else
i--;
@@ -802,7 +804,7 @@
if (alias_names [i]) {
if (filldir (dirent, alias_names [i],
strlen (alias_names [i]),
- filp->f_pos, j, DT_REG) < 0) return 0;
+ filp->f_pos, j, DT_REG) < 0) goto out;
filp->f_pos++;
}
}
@@ -815,12 +817,14 @@
else {
if (filldir(dirent, p, strlen(p),
filp->f_pos, j, DT_REG) < 0)
- return 0;
+ goto out;
filp->f_pos++;
}
}
}
}
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/proc/base.c linux-2.5.10-dirty/fs/proc/base.c
--- linux-2.5.10/fs/proc/base.c Wed Apr 24 00:15:10 2002
+++ linux-2.5.10-dirty/fs/proc/base.c Wed Apr 24 15:50:15 2002
@@ -26,6 +26,7 @@
#include <linux/seq_file.h>
#include <linux/namespace.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
/*
* For hysterical raisins we keep the same inumbers as in the old procfs.
@@ -571,6 +572,8 @@
struct dentry *de;
struct vfsmount *mnt = NULL;
+ lock_kernel();
+
if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
goto out;
error = proc_check_root(inode);
@@ -585,6 +588,7 @@
dput(de);
mntput(mnt);
out:
+ unlock_kernel();
return error;
}
@@ -665,38 +669,49 @@
int pid;
struct inode *inode = filp->f_dentry->d_inode;
struct pid_entry *p;
+ int ret = 0;
+
+ lock_kernel();
pid = proc_task(inode)->pid;
- if (!pid)
- return -ENOENT;
+ if (!pid) {
+ ret = -ENOENT;
+ goto out;
+ }
i = filp->f_pos;
switch (i) {
case 0:
if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0)
- return 0;
+ goto out;
i++;
filp->f_pos++;
/* fall through */
case 1:
if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0)
- return 0;
+ goto out;
i++;
filp->f_pos++;
/* fall through */
default:
i -= 2;
- if (i>=sizeof(base_stuff)/sizeof(base_stuff[0]))
- return 1;
+ if (i>=sizeof(base_stuff)/sizeof(base_stuff[0])) {
+ ret = 1;
+ goto out;
+ }
p = base_stuff + i;
while (p->name) {
if (filldir(dirent, p->name, p->len, filp->f_pos,
fake_ino(pid, p->type), p->mode >> 12) < 0)
- return 0;
+ goto out;
filp->f_pos++;
p++;
}
}
- return 1;
+
+ ret = 1;
+out:
+ unlock_kernel();
+ return ret;
}
/* building an inode */
diff -ur linux-2.5.10/fs/proc/generic.c linux-2.5.10-dirty/fs/proc/generic.c
--- linux-2.5.10/fs/proc/generic.c Wed Apr 24 00:15:23 2002
+++ linux-2.5.10-dirty/fs/proc/generic.c Wed Apr 24 15:50:15 2002
@@ -304,16 +304,21 @@
unsigned int ino;
int i;
struct inode *inode = filp->f_dentry->d_inode;
+ int ret = 0;
+
+ lock_kernel();
ino = inode->i_ino;
de = PDE(inode);
- if (!de)
- return -EINVAL;
+ if (!de) {
+ ret = -EINVAL;
+ goto out;
+ }
i = filp->f_pos;
switch (i) {
case 0:
if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
- return 0;
+ goto out;
i++;
filp->f_pos++;
/* fall through */
@@ -321,7 +326,7 @@
if (filldir(dirent, "..", 2, i,
parent_ino(filp->f_dentry),
DT_DIR) < 0)
- return 0;
+ goto out;
i++;
filp->f_pos++;
/* fall through */
@@ -329,8 +334,10 @@
de = de->subdir;
i -= 2;
for (;;) {
- if (!de)
- return 1;
+ if (!de) {
+ ret = 1;
+ goto out;
+ }
if (!i)
break;
de = de->next;
@@ -340,12 +347,14 @@
do {
if (filldir(dirent, de->name, de->namelen, filp->f_pos,
de->low_ino, de->mode >> 12) < 0)
- return 0;
+ goto out;
filp->f_pos++;
de = de->next;
} while (de);
}
- return 1;
+ ret = 1;
+out: unlock_kernel();
+ return ret;
}
/*
diff -ur linux-2.5.10/fs/proc/root.c linux-2.5.10-dirty/fs/proc/root.c
--- linux-2.5.10/fs/proc/root.c Wed Apr 24 00:15:21 2002
+++ linux-2.5.10-dirty/fs/proc/root.c Wed Apr 24 15:50:15 2002
@@ -98,15 +98,22 @@
void * dirent, filldir_t filldir)
{
unsigned int nr = filp->f_pos;
+ int ret;
+
+ lock_kernel();
if (nr < FIRST_PROCESS_ENTRY) {
int error = proc_readdir(filp, dirent, filldir);
- if (error <= 0)
+ if (error <= 0) {
+ unlock_kernel();
return error;
+ }
filp->f_pos = FIRST_PROCESS_ENTRY;
}
- return proc_pid_readdir(filp, dirent, filldir);
+ ret = proc_pid_readdir(filp, dirent, filldir);
+ unlock_kernel();
+ return ret;
}
/*
diff -ur linux-2.5.10/fs/qnx4/dir.c linux-2.5.10-dirty/fs/qnx4/dir.c
--- linux-2.5.10/fs/qnx4/dir.c Wed Apr 24 00:15:20 2002
+++ linux-2.5.10-dirty/fs/qnx4/dir.c Wed Apr 24 15:50:15 2002
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/qnx4_fs.h>
#include <linux/stat.h>
+#include <linux/smp_lock.h>
static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
@@ -33,6 +34,8 @@
QNX4DEBUG(("qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
QNX4DEBUG(("filp->f_pos = %ld\n", (long) filp->f_pos));
+ lock_kernel();
+
while (filp->f_pos < inode->i_size) {
blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS );
bh = sb_bread(inode->i_sb, blknum);
@@ -63,7 +66,7 @@
}
if (filldir(dirent, de->di_fname, size, filp->f_pos, ino, DT_UNKNOWN) < 0) {
brelse(bh);
- return 0;
+ goto out;
}
}
}
@@ -74,6 +77,8 @@
}
UPDATE_ATIME(inode);
+out:
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/readdir.c linux-2.5.10-dirty/fs/readdir.c
--- linux-2.5.10/fs/readdir.c Wed Apr 24 00:15:18 2002
+++ linux-2.5.10-dirty/fs/readdir.c Wed Apr 24 15:50:15 2002
@@ -23,9 +23,7 @@
down(&inode->i_sem);
res = -ENOENT;
if (!IS_DEADDIR(inode)) {
- lock_kernel();
res = file->f_op->readdir(file, buf, filler);
- unlock_kernel();
}
up(&inode->i_sem);
out:
diff -ur linux-2.5.10/fs/reiserfs/dir.c linux-2.5.10-dirty/fs/reiserfs/dir.c
--- linux-2.5.10/fs/reiserfs/dir.c Wed Apr 24 00:15:20 2002
+++ linux-2.5.10-dirty/fs/reiserfs/dir.c Wed Apr 24 15:50:15 2002
@@ -47,7 +47,9 @@
loff_t next_pos;
char small_buf[32] ; /* avoid kmalloc if we can */
struct reiserfs_dir_entry de;
+ int ret = 0;
+ lock_kernel();
reiserfs_check_lock_depth("readdir") ;
@@ -66,7 +68,8 @@
if (search_res == IO_ERROR) {
// FIXME: we could just skip part of directory which could
// not be read
- return -EIO;
+ ret = -EIO;
+ goto out;
}
entry_num = de.de_entry_num;
bh = de.de_bh;
@@ -118,7 +121,8 @@
local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
if (!local_buf) {
pathrelse (&path_to_entry);
- return -ENOMEM ;
+ ret = -ENOMEM ;
+ goto out;
}
if (item_moved (&tmp_ih, &path_to_entry)) {
reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
@@ -181,7 +185,9 @@
pathrelse (&path_to_entry);
reiserfs_check_path(&path_to_entry) ;
UPDATE_ATIME(inode) ;
- return 0;
+ out:
+ unlock_kernel();
+ return ret;
}
/* compose directory item containing "." and ".." entries (entries are
diff -ur linux-2.5.10/fs/romfs/inode.c linux-2.5.10-dirty/fs/romfs/inode.c
--- linux-2.5.10/fs/romfs/inode.c Wed Apr 24 00:15:21 2002
+++ linux-2.5.10-dirty/fs/romfs/inode.c Wed Apr 24 15:50:15 2002
@@ -273,13 +273,15 @@
int stored = 0;
char fsname[ROMFS_MAXFN]; /* XXX dynamic? */
+ lock_kernel();
+
maxoff = i->i_sb->u.romfs_sb.s_maxsize;
offset = filp->f_pos;
if (!offset) {
offset = i->i_ino & ROMFH_MASK;
if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)
- return stored;
+ goto out;
offset = ntohl(ri.spec) & ROMFH_MASK;
}
@@ -288,17 +290,17 @@
if (!offset || offset >= maxoff) {
offset = maxoff;
filp->f_pos = offset;
- return stored;
+ goto out;
}
filp->f_pos = offset;
/* Fetch inode info */
if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)
- return stored;
+ goto out;
j = romfs_strnlen(i, offset+ROMFH_SIZE, sizeof(fsname)-1);
if (j < 0)
- return stored;
+ goto out;
fsname[j]=0;
romfs_copyfrom(i, fsname, offset+ROMFH_SIZE, j);
@@ -309,11 +311,14 @@
ino = ntohl(ri.spec);
if (filldir(dirent, fsname, j, offset, ino,
romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0) {
- return stored;
+ goto out;
}
stored++;
offset = nextfh & ROMFH_MASK;
}
+out:
+ unlock_kernel();
+ return stored;
}
static struct dentry *
diff -ur linux-2.5.10/fs/smbfs/dir.c linux-2.5.10-dirty/fs/smbfs/dir.c
--- linux-2.5.10/fs/smbfs/dir.c Wed Apr 24 00:15:17 2002
+++ linux-2.5.10-dirty/fs/smbfs/dir.c Wed Apr 24 15:50:15 2002
@@ -75,6 +75,9 @@
DENTRY_PATH(dentry), (int) filp->f_pos);
result = 0;
+
+ lock_kernel();
+
switch ((unsigned int) filp->f_pos) {
case 0:
if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
@@ -207,6 +210,7 @@
page_cache_release(ctl.page);
}
out:
+ unlock_kernel();
return result;
}
diff -ur linux-2.5.10/fs/smbfs/proc.c linux-2.5.10-dirty/fs/smbfs/proc.c
--- linux-2.5.10/fs/smbfs/proc.c Wed Apr 24 00:15:11 2002
+++ linux-2.5.10-dirty/fs/smbfs/proc.c Wed Apr 24 15:50:15 2002
@@ -17,6 +17,7 @@
#include <linux/dcache.h>
#include <linux/dirent.h>
#include <linux/nls.h>
+#include <linux/smp_lock.h>
#include <linux/smb_fs.h>
#include <linux/smbno.h>
@@ -1906,6 +1907,8 @@
VERBOSE("%s/%s\n", DENTRY_PATH(dir));
+ lock_kernel();
+
smb_lock_server(server);
first = 1;
@@ -2012,6 +2015,7 @@
unlock_return:
smb_unlock_server(server);
+ unlock_kernel();
return result;
}
@@ -2172,6 +2176,8 @@
len: 1,
};
+ lock_kernel();
+
/*
* use info level 1 for older servers that don't do 260
*/
@@ -2357,6 +2363,7 @@
unlock_return:
smb_unlock_server(server);
+ unlock_kernel();
return result;
}
diff -ur linux-2.5.10/fs/sysv/dir.c linux-2.5.10-dirty/fs/sysv/dir.c
--- linux-2.5.10/fs/sysv/dir.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/sysv/dir.c Wed Apr 24 15:54:03 2002
@@ -16,6 +16,7 @@
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
static int sysv_readdir(struct file *, void *, filldir_t);
@@ -79,6 +80,8 @@
unsigned long n = pos >> PAGE_CACHE_SHIFT;
unsigned long npages = dir_pages(inode);
+ lock_kernel();
+
pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1);
if (pos >= inode->i_size)
goto done;
@@ -116,6 +119,7 @@
done:
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode);
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/udf/dir.c linux-2.5.10-dirty/fs/udf/dir.c
--- linux-2.5.10/fs/udf/dir.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/udf/dir.c Wed Apr 24 15:50:15 2002
@@ -35,6 +35,7 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include "udf_i.h"
#include "udf_sb.h"
@@ -83,15 +84,20 @@
struct inode *dir = filp->f_dentry->d_inode;
int result;
+ lock_kernel();
+
if ( filp->f_pos == 0 )
{
- if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0)
+ if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) {
+ unlock_kernel();
return 0;
+ }
filp->f_pos ++;
}
result = do_udf_readdir(dir, filp, filldir, dirent);
UPDATE_ATIME(dir);
+ unlock_kernel();
return result;
}
diff -ur linux-2.5.10/fs/ufs/dir.c linux-2.5.10-dirty/fs/ufs/dir.c
--- linux-2.5.10/fs/ufs/dir.c Wed Apr 24 00:15:14 2002
+++ linux-2.5.10-dirty/fs/ufs/dir.c Wed Apr 24 15:50:15 2002
@@ -17,6 +17,7 @@
#include <linux/locks.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
+#include <linux/smp_lock.h>
#include "swab.h"
#include "util.h"
@@ -62,6 +63,8 @@
int de_reclen;
unsigned flags;
+ lock_kernel();
+
sb = inode->i_sb;
flags = sb->u.ufs_sb.s_flags;
@@ -117,6 +120,7 @@
(sb->s_blocksize - 1)) +
sb->s_blocksize;
brelse(bh);
+ unlock_kernel();
return stored;
}
if (!ufs_check_dir_entry ("ufs_readdir", inode, de,
@@ -127,6 +131,7 @@
(sb->s_blocksize - 1)) +
1;
brelse (bh);
+ unlock_kernel();
return stored;
}
offset += fs16_to_cpu(sb, de->d_reclen);
@@ -161,6 +166,7 @@
brelse (bh);
}
UPDATE_ATIME(inode);
+ unlock_kernel();
return 0;
}
diff -ur linux-2.5.10/fs/umsdos/dir.c linux-2.5.10-dirty/fs/umsdos/dir.c
--- linux-2.5.10/fs/umsdos/dir.c Wed Apr 24 00:15:18 2002
+++ linux-2.5.10-dirty/fs/umsdos/dir.c Wed Apr 24 15:50:15 2002
@@ -17,6 +17,7 @@
#include <linux/umsdos_fs.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
#define UMSDOS_SPECIAL_DIRFPOS 3
extern struct dentry *saved_root;
@@ -302,6 +303,8 @@
int ret = 0, count = 0;
struct UMSDOS_DIR_ONCE bufk;
+ lock_kernel();
+
bufk.dirbuf = dirbuf;
bufk.filldir = filldir;
bufk.stop = 0;
@@ -317,6 +320,7 @@
break;
count += bufk.count;
}
+ unlock_kernel();
Printk (("UMSDOS_readdir out %d count %d pos %Ld\n",
ret, count, filp->f_pos));
return count ? : ret;
diff -ur linux-2.5.10/fs/umsdos/rdir.c linux-2.5.10-dirty/fs/umsdos/rdir.c
--- linux-2.5.10/fs/umsdos/rdir.c Wed Apr 24 00:15:12 2002
+++ linux-2.5.10-dirty/fs/umsdos/rdir.c Wed Apr 24 15:50:15 2002
@@ -15,6 +15,7 @@
#include <linux/limits.h>
#include <linux/umsdos_fs.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -63,11 +64,15 @@
{
struct inode *dir = filp->f_dentry->d_inode;
struct RDIR_FILLDIR bufk;
+ int ret;
+ lock_kernel();
bufk.filldir = filldir;
bufk.dirbuf = dirbuf;
bufk.real_root = pseudo_root && (dir == saved_root->d_inode);
- return fat_readdir (filp, &bufk, rdir_filldir);
+ ret = fat_readdir (filp, &bufk, rdir_filldir);
+ unlock_kernel();
+ return ret;
}
reply other threads:[~2002-04-24 23:24 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3CC73E6E.9090405@us.ibm.com \
--to=haveblue@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.