Commit ec3630a1 authored by Dave Hansen's avatar Dave Hansen Committed by Linus Torvalds

[PATCH] shift BKL out of vfs_readdir

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.
parent 934ddeab
...@@ -254,7 +254,7 @@ locking rules: ...@@ -254,7 +254,7 @@ locking rules:
llseek: yes (see below) llseek: yes (see below)
read: no read: no
write: no write: no
readdir: yes (see below) readdir: no
poll: no poll: no
ioctl: yes (see below) ioctl: yes (see below)
mmap: no mmap: no
......
...@@ -97,18 +97,20 @@ static int capifs_root_readdir(struct file *filp, void *dirent, filldir_t filldi ...@@ -97,18 +97,20 @@ static int capifs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
off_t nr; off_t nr;
char numbuf[32]; char numbuf[32];
lock_kernel();
nr = filp->f_pos; nr = filp->f_pos;
switch(nr) switch(nr)
{ {
case 0: case 0:
if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
filp->f_pos = ++nr; filp->f_pos = ++nr;
/* fall through */ /* fall through */
case 1: case 1:
if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
filp->f_pos = ++nr; filp->f_pos = ++nr;
/* fall through */ /* fall through */
default: default:
...@@ -120,13 +122,15 @@ static int capifs_root_readdir(struct file *filp, void *dirent, filldir_t filldi ...@@ -120,13 +122,15 @@ static int capifs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
if (np->type) *p++ = np->type; if (np->type) *p++ = np->type;
sprintf(p, "%u", np->num); sprintf(p, "%u", np->num);
if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_UNKNOWN) < 0 ) if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_UNKNOWN) < 0 )
return 0; goto out;
} }
filp->f_pos = ++nr; filp->f_pos = ++nr;
} }
break; break;
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -36,6 +36,8 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -36,6 +36,8 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct adfs_dir dir; struct adfs_dir dir;
int ret = 0; int ret = 0;
lock_kernel();
if (filp->f_pos >> 32) if (filp->f_pos >> 32)
goto out; goto out;
...@@ -77,6 +79,7 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -77,6 +79,7 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
ops->free(&dir); ops->free(&dir);
out: out:
unlock_kernel();
return ret; return ret;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/amigaffs.h> #include <linux/amigaffs.h>
#include <linux/smp_lock.h>
static int affs_readdir(struct file *, void *, filldir_t); static int affs_readdir(struct file *, void *, filldir_t);
...@@ -63,6 +64,8 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -63,6 +64,8 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int stored; int stored;
int res; int res;
lock_kernel();
pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)filp->f_pos); pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)filp->f_pos);
stored = 0; stored = 0;
...@@ -158,6 +161,7 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -158,6 +161,7 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
affs_brelse(dir_bh); affs_brelse(dir_bh);
affs_brelse(fh_bh); affs_brelse(fh_bh);
affs_unlock_dir(inode); affs_unlock_dir(inode);
unlock_kernel();
pr_debug("AFFS: readdir()=%d\n", stored); pr_debug("AFFS: readdir()=%d\n", stored);
return res; return res;
} }
...@@ -47,6 +47,8 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi ...@@ -47,6 +47,8 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
struct inode * inode = filp->f_dentry->d_inode; struct inode * inode = filp->f_dentry->d_inode;
off_t onr, nr; off_t onr, nr;
lock_kernel();
sbi = autofs_sbi(inode->i_sb); sbi = autofs_sbi(inode->i_sb);
dirhash = &sbi->dirhash; dirhash = &sbi->dirhash;
nr = filp->f_pos; nr = filp->f_pos;
...@@ -55,25 +57,27 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi ...@@ -55,25 +57,27 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
{ {
case 0: case 0:
if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
filp->f_pos = ++nr; filp->f_pos = ++nr;
/* fall through */ /* fall through */
case 1: case 1:
if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
filp->f_pos = ++nr; filp->f_pos = ++nr;
/* fall through */ /* fall through */
default: default:
while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent) ) { while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent) ) {
if ( !ent->dentry || d_mountpoint(ent->dentry) ) { if ( !ent->dentry || d_mountpoint(ent->dentry) ) {
if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0) if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0)
return 0; goto out;
filp->f_pos = nr; filp->f_pos = nr;
} }
} }
break; break;
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/smp_lock.h>
/* /*
* The follow_link operation is special: it must behave as a no-op * The follow_link operation is special: it must behave as a no-op
......
...@@ -32,9 +32,12 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) ...@@ -32,9 +32,12 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
unsigned int offset; unsigned int offset;
int block; int block;
lock_kernel();
if (f->f_pos & (BFS_DIRENT_SIZE-1)) { if (f->f_pos & (BFS_DIRENT_SIZE-1)) {
printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos, printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos,
dir->i_sb->s_id, dir->i_ino); dir->i_sb->s_id, dir->i_ino);
unlock_kernel();
return -EBADF; return -EBADF;
} }
...@@ -52,6 +55,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) ...@@ -52,6 +55,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
int size = strnlen(de->name, BFS_NAMELEN); int size = strnlen(de->name, BFS_NAMELEN);
if (filldir(dirent, de->name, size, f->f_pos, de->ino, DT_UNKNOWN) < 0) { if (filldir(dirent, de->name, size, f->f_pos, de->ino, DT_UNKNOWN) < 0) {
brelse(bh); brelse(bh);
unlock_kernel();
return 0; return 0;
} }
} }
...@@ -62,6 +66,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) ...@@ -62,6 +66,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
} }
UPDATE_ATIME(dir); UPDATE_ATIME(dir);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -293,6 +293,8 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -293,6 +293,8 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (offset & 3) if (offset & 3)
return -EINVAL; return -EINVAL;
lock_kernel();
copied = 0; copied = 0;
while (offset < inode->i_size) { while (offset < inode->i_size) {
struct cramfs_inode *de; struct cramfs_inode *de;
...@@ -313,8 +315,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -313,8 +315,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
namelen = de->namelen << 2; namelen = de->namelen << 2;
nextoffset = offset + sizeof(*de) + namelen; nextoffset = offset + sizeof(*de) + namelen;
for (;;) { for (;;) {
if (!namelen) if (!namelen) {
unlock_kernel();
return -EIO; return -EIO;
}
if (name[namelen-1]) if (name[namelen-1])
break; break;
namelen--; namelen--;
...@@ -327,6 +331,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -327,6 +331,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
filp->f_pos = offset; filp->f_pos = offset;
copied++; copied++;
} }
unlock_kernel();
return 0; return 0;
} }
......
...@@ -48,18 +48,20 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi ...@@ -48,18 +48,20 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi
off_t nr; off_t nr;
char numbuf[16]; char numbuf[16];
lock_kernel();
nr = filp->f_pos; nr = filp->f_pos;
switch(nr) switch(nr)
{ {
case 0: case 0:
if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
filp->f_pos = ++nr; filp->f_pos = ++nr;
/* fall through */ /* fall through */
case 1: case 1:
if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
filp->f_pos = ++nr; filp->f_pos = ++nr;
/* fall through */ /* fall through */
default: default:
...@@ -68,13 +70,15 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi ...@@ -68,13 +70,15 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi
if ( sbi->inodes[ptynr] ) { if ( sbi->inodes[ptynr] ) {
genptsname(numbuf, ptynr); genptsname(numbuf, ptynr);
if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 ) if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 )
return 0; goto out;
} }
filp->f_pos = ++nr; filp->f_pos = ++nr;
} }
break; break;
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
#include <linux/efs_fs.h> #include <linux/efs_fs.h>
#include <linux/smp_lock.h>
static int efs_readdir(struct file *, void *, filldir_t); static int efs_readdir(struct file *, void *, filldir_t);
...@@ -31,6 +32,8 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { ...@@ -31,6 +32,8 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
if (inode->i_size & (EFS_DIRBSIZE-1)) if (inode->i_size & (EFS_DIRBSIZE-1))
printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n"); 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 */ /* work out where this entry can be found */
block = filp->f_pos >> EFS_DIRBSIZE_BITS; block = filp->f_pos >> EFS_DIRBSIZE_BITS;
...@@ -91,7 +94,7 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { ...@@ -91,7 +94,7 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
} }
brelse(bh); brelse(bh);
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot; filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
return 0; goto out;
} }
slot++; slot++;
} }
...@@ -102,6 +105,8 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { ...@@ -102,6 +105,8 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
} }
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot; filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
out:
unlock_kernel();
return 0; return 0;
} }
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "ext2.h" #include "ext2.h"
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
typedef struct ext2_dir_entry_2 ext2_dirent; typedef struct ext2_dir_entry_2 ext2_dirent;
...@@ -258,6 +259,8 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) ...@@ -258,6 +259,8 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
int need_revalidate = (filp->f_version != inode->i_version); int need_revalidate = (filp->f_version != inode->i_version);
int ret = 0; int ret = 0;
lock_kernel();
if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
goto done; goto done;
...@@ -310,6 +313,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) ...@@ -310,6 +313,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
filp->f_version = inode->i_version; filp->f_version = inode->i_version;
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/jbd.h> #include <linux/jbd.h>
#include <linux/ext3_fs.h> #include <linux/ext3_fs.h>
#include <linux/smp_lock.h>
static unsigned char ext3_filetype_table[] = { static unsigned char ext3_filetype_table[] = {
DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
...@@ -30,7 +31,7 @@ static int ext3_readdir(struct file *, void *, filldir_t); ...@@ -30,7 +31,7 @@ static int ext3_readdir(struct file *, void *, filldir_t);
struct file_operations ext3_dir_operations = { struct file_operations ext3_dir_operations = {
read: generic_read_dir, read: generic_read_dir,
readdir: ext3_readdir, /* BKL held */ readdir: ext3_readdir, /* we take BKL. needed?*/
ioctl: ext3_ioctl, /* BKL held */ ioctl: ext3_ioctl, /* BKL held */
fsync: ext3_sync_file, /* BKL held */ fsync: ext3_sync_file, /* BKL held */
}; };
...@@ -77,6 +78,8 @@ static int ext3_readdir(struct file * filp, ...@@ -77,6 +78,8 @@ static int ext3_readdir(struct file * filp,
int err; int err;
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
lock_kernel();
sb = inode->i_sb; sb = inode->i_sb;
stored = 0; stored = 0;
...@@ -150,6 +153,7 @@ static int ext3_readdir(struct file * filp, ...@@ -150,6 +153,7 @@ static int ext3_readdir(struct file * filp,
filp->f_pos = (filp->f_pos | filp->f_pos = (filp->f_pos |
(sb->s_blocksize - 1)) + 1; (sb->s_blocksize - 1)) + 1;
brelse (bh); brelse (bh);
unlock_kernel();
return stored; return stored;
} }
offset += le16_to_cpu(de->rec_len); offset += le16_to_cpu(de->rec_len);
...@@ -186,5 +190,6 @@ static int ext3_readdir(struct file * filp, ...@@ -186,5 +190,6 @@ static int ext3_readdir(struct file * filp,
brelse (bh); brelse (bh);
} }
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
unlock_kernel();
return 0; return 0;
} }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/msdos_fs.h> #include <linux/msdos_fs.h>
#include <linux/dirent.h> #include <linux/dirent.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -363,13 +364,16 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, ...@@ -363,13 +364,16 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname; unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname;
int ino, inum, chi, chl, i, i2, j, last, last_u, dotoffset = 0; int ino, inum, chi, chl, i, i2, j, last, last_u, dotoffset = 0;
loff_t cpos; loff_t cpos;
int ret = 0;
lock_kernel();
cpos = filp->f_pos; cpos = filp->f_pos;
/* Fake . and .. for the root directory. */ /* Fake . and .. for the root directory. */
if (inode->i_ino == MSDOS_ROOT_INO) { if (inode->i_ino == MSDOS_ROOT_INO) {
while (cpos < 2) { while (cpos < 2) {
if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0) if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0)
return 0; goto out;
cpos++; cpos++;
filp->f_pos++; filp->f_pos++;
} }
...@@ -379,8 +383,10 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, ...@@ -379,8 +383,10 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
cpos = 0; cpos = 0;
} }
} }
if (cpos & (sizeof(struct msdos_dir_entry)-1)) if (cpos & (sizeof(struct msdos_dir_entry)-1)) {
return -ENOENT; ret = -ENOENT;
goto out;
}
bh = NULL; bh = NULL;
GetNew: GetNew:
...@@ -414,7 +420,8 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, ...@@ -414,7 +420,8 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
if (!unicode) { if (!unicode) {
filp->f_pos = cpos; filp->f_pos = cpos;
fat_brelse(sb, bh); fat_brelse(sb, bh);
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
} }
ParseLong: ParseLong:
...@@ -580,7 +587,9 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, ...@@ -580,7 +587,9 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
if (unicode) { if (unicode) {
free_page((unsigned long) unicode); free_page((unsigned long) unicode);
} }
return 0; out:
unlock_kernel();
return ret;
} }
int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
......
...@@ -262,8 +262,10 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler) ...@@ -262,8 +262,10 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
pos = fp->f_pos - 2; pos = fp->f_pos - 2;
if (pos > VXFS_DIRROUND(ip->i_size)) if (pos > VXFS_DIRROUND(ip->i_size)) {
unlock_kernel();
return 0; return 0;
}
npages = dir_pages(ip); npages = dir_pages(ip);
nblocks = dir_blocks(ip); nblocks = dir_blocks(ip);
...@@ -322,5 +324,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler) ...@@ -322,5 +324,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
done: done:
fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2; fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
out: out:
unlock_kernel();
return 0; return 0;
} }
...@@ -188,6 +188,8 @@ static int cap_readdir(struct file * filp, ...@@ -188,6 +188,8 @@ static int cap_readdir(struct file * filp,
struct hfs_cat_entry *entry; struct hfs_cat_entry *entry;
struct inode *dir = filp->f_dentry->d_inode; struct inode *dir = filp->f_dentry->d_inode;
lock_kernel();
entry = HFS_I(dir)->entry; entry = HFS_I(dir)->entry;
type = HFS_ITYPE(dir->i_ino); type = HFS_ITYPE(dir->i_ino);
skip_dirs = (type == HFS_CAP_RDIR); skip_dirs = (type == HFS_CAP_RDIR);
...@@ -195,7 +197,7 @@ static int cap_readdir(struct file * filp, ...@@ -195,7 +197,7 @@ static int cap_readdir(struct file * filp,
if (filp->f_pos == 0) { if (filp->f_pos == 0) {
/* Entry 0 is for "." */ /* Entry 0 is for "." */
if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, DT_DIR)) { if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, DT_DIR)) {
return 0; goto out;
} }
filp->f_pos = 1; filp->f_pos = 1;
} }
...@@ -212,7 +214,7 @@ static int cap_readdir(struct file * filp, ...@@ -212,7 +214,7 @@ static int cap_readdir(struct file * filp,
if (filldir(dirent, DOT_DOT->Name, if (filldir(dirent, DOT_DOT->Name,
DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) { DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) {
return 0; goto out;
} }
filp->f_pos = 2; filp->f_pos = 2;
} }
...@@ -223,11 +225,11 @@ static int cap_readdir(struct file * filp, ...@@ -223,11 +225,11 @@ static int cap_readdir(struct file * filp,
if (hfs_cat_open(entry, &brec) || if (hfs_cat_open(entry, &brec) ||
hfs_cat_next(entry, &brec, filp->f_pos - 2, &cnid, &type)) { hfs_cat_next(entry, &brec, filp->f_pos - 2, &cnid, &type)) {
return 0; goto out;
} }
while (filp->f_pos < (dir->i_size - 3)) { while (filp->f_pos < (dir->i_size - 3)) {
if (hfs_cat_next(entry, &brec, 1, &cnid, &type)) { if (hfs_cat_next(entry, &brec, 1, &cnid, &type)) {
return 0; goto out;
} }
if (!skip_dirs || (type != HFS_CDR_DIR)) { if (!skip_dirs || (type != HFS_CDR_DIR)) {
ino_t ino; ino_t ino;
...@@ -240,7 +242,7 @@ static int cap_readdir(struct file * filp, ...@@ -240,7 +242,7 @@ static int cap_readdir(struct file * filp,
if (filldir(dirent, tmp_name, len, if (filldir(dirent, tmp_name, len,
filp->f_pos, ino, DT_UNKNOWN)) { filp->f_pos, ino, DT_UNKNOWN)) {
hfs_cat_close(entry, &brec); hfs_cat_close(entry, &brec);
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
...@@ -256,7 +258,7 @@ static int cap_readdir(struct file * filp, ...@@ -256,7 +258,7 @@ static int cap_readdir(struct file * filp,
DOT_ROOTINFO_LEN, filp->f_pos, DOT_ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_FNDR, ntohl(entry->cnid) | HFS_CAP_FNDR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
...@@ -269,7 +271,7 @@ static int cap_readdir(struct file * filp, ...@@ -269,7 +271,7 @@ static int cap_readdir(struct file * filp,
DOT_FINDERINFO_LEN, filp->f_pos, DOT_FINDERINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_FDIR, ntohl(entry->cnid) | HFS_CAP_FDIR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
...@@ -282,12 +284,14 @@ static int cap_readdir(struct file * filp, ...@@ -282,12 +284,14 @@ static int cap_readdir(struct file * filp,
DOT_RESOURCE_LEN, filp->f_pos, DOT_RESOURCE_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_CAP_RDIR, ntohl(entry->cnid) | HFS_CAP_RDIR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -182,13 +182,15 @@ static int dbl_readdir(struct file * filp, ...@@ -182,13 +182,15 @@ static int dbl_readdir(struct file * filp,
struct hfs_cat_entry *entry; struct hfs_cat_entry *entry;
struct inode *dir = filp->f_dentry->d_inode; struct inode *dir = filp->f_dentry->d_inode;
lock_kernel();
entry = HFS_I(dir)->entry; entry = HFS_I(dir)->entry;
if (filp->f_pos == 0) { if (filp->f_pos == 0) {
/* Entry 0 is for "." */ /* Entry 0 is for "." */
if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino,
DT_DIR)) { DT_DIR)) {
return 0; goto out;
} }
filp->f_pos = 1; filp->f_pos = 1;
} }
...@@ -197,7 +199,7 @@ static int dbl_readdir(struct file * filp, ...@@ -197,7 +199,7 @@ static int dbl_readdir(struct file * filp,
/* Entry 1 is for ".." */ /* Entry 1 is for ".." */
if (filldir(dirent, DOT_DOT->Name, DOT_DOT_LEN, 1, if (filldir(dirent, DOT_DOT->Name, DOT_DOT_LEN, 1,
hfs_get_hl(entry->key.ParID), DT_DIR)) { hfs_get_hl(entry->key.ParID), DT_DIR)) {
return 0; goto out;
} }
filp->f_pos = 2; filp->f_pos = 2;
} }
...@@ -209,7 +211,7 @@ static int dbl_readdir(struct file * filp, ...@@ -209,7 +211,7 @@ static int dbl_readdir(struct file * filp,
if (hfs_cat_open(entry, &brec) || if (hfs_cat_open(entry, &brec) ||
hfs_cat_next(entry, &brec, (filp->f_pos - 1) >> 1, hfs_cat_next(entry, &brec, (filp->f_pos - 1) >> 1,
&cnid, &type)) { &cnid, &type)) {
return 0; goto out;
} }
while (filp->f_pos < (dir->i_size - 1)) { while (filp->f_pos < (dir->i_size - 1)) {
...@@ -226,7 +228,7 @@ static int dbl_readdir(struct file * filp, ...@@ -226,7 +228,7 @@ static int dbl_readdir(struct file * filp,
} else { } else {
if (hfs_cat_next(entry, &brec, 1, if (hfs_cat_next(entry, &brec, 1,
&cnid, &type)) { &cnid, &type)) {
return 0; goto out;
} }
ino = ntohl(cnid); ino = ntohl(cnid);
len = hfs_namein(dir, tmp_name, len = hfs_namein(dir, tmp_name,
...@@ -236,7 +238,7 @@ static int dbl_readdir(struct file * filp, ...@@ -236,7 +238,7 @@ static int dbl_readdir(struct file * filp,
if (filldir(dirent, tmp_name, len, filp->f_pos, ino, if (filldir(dirent, tmp_name, len, filp->f_pos, ino,
DT_UNKNOWN)) { DT_UNKNOWN)) {
hfs_cat_close(entry, &brec); hfs_cat_close(entry, &brec);
return 0; goto out;
} }
++filp->f_pos; ++filp->f_pos;
} }
...@@ -250,12 +252,14 @@ static int dbl_readdir(struct file * filp, ...@@ -250,12 +252,14 @@ static int dbl_readdir(struct file * filp,
PCNT_ROOTINFO_LEN, filp->f_pos, PCNT_ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_DBL_HDR, ntohl(entry->cnid) | HFS_DBL_HDR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -188,6 +188,8 @@ static int nat_readdir(struct file * filp, ...@@ -188,6 +188,8 @@ static int nat_readdir(struct file * filp,
struct hfs_cat_entry *entry; struct hfs_cat_entry *entry;
struct inode *dir = filp->f_dentry->d_inode; struct inode *dir = filp->f_dentry->d_inode;
lock_kernel();
entry = HFS_I(dir)->entry; entry = HFS_I(dir)->entry;
type = HFS_ITYPE(dir->i_ino); type = HFS_ITYPE(dir->i_ino);
skip_dirs = (type == HFS_NAT_HDIR); skip_dirs = (type == HFS_NAT_HDIR);
...@@ -196,7 +198,7 @@ static int nat_readdir(struct file * filp, ...@@ -196,7 +198,7 @@ static int nat_readdir(struct file * filp,
/* Entry 0 is for "." */ /* Entry 0 is for "." */
if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino,
DT_DIR)) { DT_DIR)) {
return 0; goto out;
} }
filp->f_pos = 1; filp->f_pos = 1;
} }
...@@ -213,7 +215,7 @@ static int nat_readdir(struct file * filp, ...@@ -213,7 +215,7 @@ static int nat_readdir(struct file * filp,
if (filldir(dirent, DOT_DOT->Name, if (filldir(dirent, DOT_DOT->Name,
DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) { DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) {
return 0; goto out;
} }
filp->f_pos = 2; filp->f_pos = 2;
} }
...@@ -224,11 +226,11 @@ static int nat_readdir(struct file * filp, ...@@ -224,11 +226,11 @@ static int nat_readdir(struct file * filp,
if (hfs_cat_open(entry, &brec) || if (hfs_cat_open(entry, &brec) ||
hfs_cat_next(entry, &brec, filp->f_pos - 2, &cnid, &type)) { hfs_cat_next(entry, &brec, filp->f_pos - 2, &cnid, &type)) {
return 0; goto out;
} }
while (filp->f_pos < (dir->i_size - 2)) { while (filp->f_pos < (dir->i_size - 2)) {
if (hfs_cat_next(entry, &brec, 1, &cnid, &type)) { if (hfs_cat_next(entry, &brec, 1, &cnid, &type)) {
return 0; goto out;
} }
if (!skip_dirs || (type != HFS_CDR_DIR)) { if (!skip_dirs || (type != HFS_CDR_DIR)) {
ino_t ino; ino_t ino;
...@@ -241,7 +243,7 @@ static int nat_readdir(struct file * filp, ...@@ -241,7 +243,7 @@ static int nat_readdir(struct file * filp,
if (filldir(dirent, tmp_name, len, if (filldir(dirent, tmp_name, len,
filp->f_pos, ino, DT_UNKNOWN)) { filp->f_pos, ino, DT_UNKNOWN)) {
hfs_cat_close(entry, &brec); hfs_cat_close(entry, &brec);
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
...@@ -256,7 +258,7 @@ static int nat_readdir(struct file * filp, ...@@ -256,7 +258,7 @@ static int nat_readdir(struct file * filp,
DOT_APPLEDOUBLE_LEN, filp->f_pos, DOT_APPLEDOUBLE_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDIR, ntohl(entry->cnid) | HFS_NAT_HDIR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} else if (type == HFS_NAT_HDIR) { } else if (type == HFS_NAT_HDIR) {
/* In .AppleDouble entry 2 is for ".Parent" */ /* In .AppleDouble entry 2 is for ".Parent" */
...@@ -264,7 +266,7 @@ static int nat_readdir(struct file * filp, ...@@ -264,7 +266,7 @@ static int nat_readdir(struct file * filp,
DOT_PARENT_LEN, filp->f_pos, DOT_PARENT_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDR, ntohl(entry->cnid) | HFS_NAT_HDR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
...@@ -278,12 +280,14 @@ static int nat_readdir(struct file * filp, ...@@ -278,12 +280,14 @@ static int nat_readdir(struct file * filp,
ROOTINFO_LEN, filp->f_pos, ROOTINFO_LEN, filp->f_pos,
ntohl(entry->cnid) | HFS_NAT_HDR, ntohl(entry->cnid) | HFS_NAT_HDR,
DT_UNKNOWN)) { DT_UNKNOWN)) {
return 0; goto out;
} }
} }
++filp->f_pos; ++filp->f_pos;
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -62,19 +62,26 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -62,19 +62,26 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
long old_pos; long old_pos;
char *tempname; char *tempname;
int c1, c2 = 0; int c1, c2 = 0;
int ret = 0;
if (inode->i_sb->s_hpfs_chk) { if (inode->i_sb->s_hpfs_chk) {
if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
return -EFSERROR; ret = -EFSERROR;
if (hpfs_chk_sectors(inode->i_sb, hpfs_inode->i_dno, 4, "dir_dnode")) goto out;
return -EFSERROR; }
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) { if (inode->i_sb->s_hpfs_chk >= 2) {
struct buffer_head *bh; struct buffer_head *bh;
struct fnode *fno; struct fnode *fno;
int e = 0; int e = 0;
if (!(fno = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) if (!(fno = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) {
return -EIOERROR; ret = -EIOERROR;
goto out;
}
if (!fno->dirflag) { if (!fno->dirflag) {
e = 1; e = 1;
hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino); hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino);
...@@ -84,14 +91,20 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -84,14 +91,20 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
hpfs_error(inode->i_sb, "corrupted inode: i_dno == %08x, fnode -> dnode == %08x", hpfs_inode->i_dno, fno->u.external[0].disk_secno); 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); brelse(bh);
if (e) return -EFSERROR; if (e) {
ret = -EFSERROR;
goto out;
}
} }
lc = inode->i_sb->s_hpfs_lowercase; lc = inode->i_sb->s_hpfs_lowercase;
if (filp->f_pos == 12) { /* diff -r requires this (note, that diff -r */ 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) */ 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); hpfs_lock_inode(inode);
...@@ -103,28 +116,29 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -103,28 +116,29 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (inode->i_sb->s_hpfs_chk) if (inode->i_sb->s_hpfs_chk)
if (hpfs_stop_cycles(inode->i_sb, filp->f_pos, &c1, &c2, "hpfs_readdir")) { if (hpfs_stop_cycles(inode->i_sb, filp->f_pos, &c1, &c2, "hpfs_readdir")) {
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return -EFSERROR; ret = -EFSERROR;
goto out;
} }
if (filp->f_pos == 12) { if (filp->f_pos == 12) {
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return 0; goto out;
} }
if (filp->f_pos == 3 || filp->f_pos == 4 || filp->f_pos == 5) { if (filp->f_pos == 3 || filp->f_pos == 4 || filp->f_pos == 5) {
printk("HPFS: warning: pos==%d\n",(int)filp->f_pos); printk("HPFS: warning: pos==%d\n",(int)filp->f_pos);
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return 0; goto out;
} }
if (filp->f_pos == 0) { if (filp->f_pos == 0) {
if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) { if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return 0; goto out;
} }
filp->f_pos = 11; filp->f_pos = 11;
} }
if (filp->f_pos == 11) { if (filp->f_pos == 11) {
if (filldir(dirent, "..", 2, filp->f_pos, hpfs_inode->i_parent_dir, DT_DIR) < 0) { if (filldir(dirent, "..", 2, filp->f_pos, hpfs_inode->i_parent_dir, DT_DIR) < 0) {
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return 0; goto out;
} }
filp->f_pos = 1; filp->f_pos = 1;
} }
...@@ -135,12 +149,14 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -135,12 +149,14 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
} }
/*if (filp->f_version != inode->i_version) { /*if (filp->f_version != inode->i_version) {
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return -ENOENT; ret = -ENOENT;
goto out;
}*/ }*/
old_pos = filp->f_pos; old_pos = filp->f_pos;
if (!(de = map_pos_dirent(inode, &filp->f_pos, &qbh))) { if (!(de = map_pos_dirent(inode, &filp->f_pos, &qbh))) {
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return -EIOERROR; ret = -EIOERROR;
goto out;
} }
if (de->first || de->last) { if (de->first || de->last) {
if (inode->i_sb->s_hpfs_chk) { if (inode->i_sb->s_hpfs_chk) {
...@@ -156,11 +172,14 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -156,11 +172,14 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (tempname != (char *)de->name) kfree(tempname); if (tempname != (char *)de->name) kfree(tempname);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
hpfs_unlock_inode(inode); hpfs_unlock_inode(inode);
return 0; goto out;
} }
if (tempname != (char *)de->name) kfree(tempname); if (tempname != (char *)de->name) kfree(tempname);
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
} }
out:
unlock_kernel();
return ret;
} }
/* /*
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -253,6 +254,8 @@ static int isofs_readdir(struct file *filp, ...@@ -253,6 +254,8 @@ static int isofs_readdir(struct file *filp,
struct iso_directory_record * tmpde; struct iso_directory_record * tmpde;
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
lock_kernel();
tmpname = (char *) __get_free_page(GFP_KERNEL); tmpname = (char *) __get_free_page(GFP_KERNEL);
if (!tmpname) if (!tmpname)
return -ENOMEM; return -ENOMEM;
...@@ -261,5 +264,6 @@ static int isofs_readdir(struct file *filp, ...@@ -261,5 +264,6 @@ static int isofs_readdir(struct file *filp,
result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde); result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde);
free_page((unsigned long) tmpname); free_page((unsigned long) tmpname);
unlock_kernel();
return result; return result;
} }
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/smp_lock.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -568,6 +569,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -568,6 +569,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp; struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
int j; int j;
int ddino; int ddino;
lock_kernel();
D3(printk (KERN_NOTICE "readdir(): down biglock\n")); D3(printk (KERN_NOTICE "readdir(): down biglock\n"));
down(&c->fmc->biglock); down(&c->fmc->biglock);
...@@ -577,6 +579,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -577,6 +579,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) { if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n")); D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
unlock_kernel();
return 0; return 0;
} }
filp->f_pos = 1; filp->f_pos = 1;
...@@ -593,6 +596,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -593,6 +596,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) { if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n")); D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
unlock_kernel();
return 0; return 0;
} }
filp->f_pos++; filp->f_pos++;
...@@ -611,6 +615,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -611,6 +615,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
filp->f_pos , f->ino, DT_UNKNOWN) < 0) { filp->f_pos , f->ino, DT_UNKNOWN) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n")); D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
unlock_kernel();
return 0; return 0;
} }
filp->f_pos++; filp->f_pos++;
...@@ -620,6 +625,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -620,6 +625,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
} }
D3(printk (KERN_NOTICE "readdir(): up biglock\n")); D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock); up(&c->fmc->biglock);
unlock_kernel();
return filp->f_pos; return filp->f_pos;
} /* jffs_readdir() */ } /* jffs_readdir() */
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,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);
...@@ -143,6 +144,8 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -143,6 +144,8 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_dentry->d_inode->i_ino)); 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); f = JFFS2_INODE_INFO(inode);
c = JFFS2_SB_INFO(inode->i_sb); c = JFFS2_SB_INFO(inode->i_sb);
...@@ -186,6 +189,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -186,6 +189,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
up(&f->sem); up(&f->sem);
out: out:
filp->f_pos = offset; filp->f_pos = offset;
unlock_kernel();
return 0; return 0;
} }
......
...@@ -102,6 +102,7 @@ ...@@ -102,6 +102,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/smp_lock.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
...@@ -2868,6 +2869,8 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2868,6 +2869,8 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filp->f_pos == DIREND) if (filp->f_pos == DIREND)
return 0; return 0;
lock_kernel();
if (DO_INDEX(ip)) { if (DO_INDEX(ip)) {
/* /*
* persistent index is stored in directory entries. * persistent index is stored in directory entries.
...@@ -2885,12 +2888,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2885,12 +2888,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (dtEmpty(ip)) { if (dtEmpty(ip)) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
repeat: repeat:
rc = get_index(ip, dir_index, &dirtab_slot); rc = get_index(ip, dir_index, &dirtab_slot);
if (rc) { if (rc) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return rc; return rc;
} }
if (dirtab_slot.flag == DIR_INDEX_FREE) { if (dirtab_slot.flag == DIR_INDEX_FREE) {
...@@ -2898,11 +2903,13 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2898,11 +2903,13 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
jERROR(1, ("jfs_readdir detected " jERROR(1, ("jfs_readdir detected "
"infinite loop!\n")); "infinite loop!\n"));
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
dir_index = le32_to_cpu(dirtab_slot.addr2); dir_index = le32_to_cpu(dirtab_slot.addr2);
if (dir_index == -1) { if (dir_index == -1) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
goto repeat; goto repeat;
...@@ -2912,12 +2919,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2912,12 +2919,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
if (rc) { if (rc) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
if (p->header.flag & BT_INTERNAL) { if (p->header.flag & BT_INTERNAL) {
jERROR(1,("jfs_readdir: bad index table\n")); jERROR(1,("jfs_readdir: bad index table\n"));
DT_PUTPAGE(mp); DT_PUTPAGE(mp);
filp->f_pos = -1; filp->f_pos = -1;
unlock_kernel();
return 0; return 0;
} }
} else { } else {
...@@ -2927,27 +2936,34 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2927,27 +2936,34 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
*/ */
filp->f_pos = 0; filp->f_pos = 0;
if (filldir(dirent, ".", 1, 0, ip->i_ino, if (filldir(dirent, ".", 1, 0, ip->i_ino,
DT_DIR)) DT_DIR)) {
unlock_kernel();
return 0; return 0;
} }
}
/* /*
* parent ".." * parent ".."
*/ */
filp->f_pos = 1; filp->f_pos = 1;
if (filldir if (filldir
(dirent, "..", 2, 1, PARENT(ip), DT_DIR)) (dirent, "..", 2, 1, PARENT(ip), DT_DIR)) {
unlock_kernel();
return 0; return 0;
}
/* /*
* Find first entry of left-most leaf * Find first entry of left-most leaf
*/ */
if (dtEmpty(ip)) { if (dtEmpty(ip)) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
if ((rc = dtReadFirst(ip, &btstack))) if ((rc = dtReadFirst(ip, &btstack))) {
unlock_kernel();
return -rc; return -rc;
}
DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
} }
...@@ -2966,8 +2982,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2966,8 +2982,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* build "." entry */ /* build "." entry */
if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino, if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino,
DT_DIR)) DT_DIR)) {
unlock_kernel();
return 0; return 0;
}
dtoffset->index = 1; dtoffset->index = 1;
} }
...@@ -2976,8 +2994,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2976,8 +2994,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* build ".." entry */ /* build ".." entry */
if (filldir(dirent, "..", 2, filp->f_pos, if (filldir(dirent, "..", 2, filp->f_pos,
PARENT(ip), DT_DIR)) PARENT(ip), DT_DIR)) {
unlock_kernel();
return 0; return 0;
}
} else { } else {
jERROR(1, jERROR(1,
("jfs_readdir called with invalid offset!\n")); ("jfs_readdir called with invalid offset!\n"));
...@@ -2988,6 +3008,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2988,6 +3008,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (dtEmpty(ip)) { if (dtEmpty(ip)) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
...@@ -2996,6 +3017,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -2996,6 +3017,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
("jfs_readdir: unexpected rc = %d from dtReadNext\n", ("jfs_readdir: unexpected rc = %d from dtReadNext\n",
rc)); rc));
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
/* get start leaf page and index */ /* get start leaf page and index */
...@@ -3004,6 +3026,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -3004,6 +3026,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* offset beyond directory eof ? */ /* offset beyond directory eof ? */
if (bn < 0) { if (bn < 0) {
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
} }
...@@ -3013,6 +3036,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -3013,6 +3036,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
DT_PUTPAGE(mp); DT_PUTPAGE(mp);
jERROR(1, ("jfs_readdir: kmalloc failed!\n")); jERROR(1, ("jfs_readdir: kmalloc failed!\n"));
filp->f_pos = DIREND; filp->f_pos = DIREND;
unlock_kernel();
return 0; return 0;
} }
while (1) { while (1) {
...@@ -3087,6 +3111,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -3087,6 +3111,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
if (rc) { if (rc) {
kfree(d_name); kfree(d_name);
unlock_kernel();
return -rc; return -rc;
} }
...@@ -3102,7 +3127,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -3102,7 +3127,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
out: out:
kfree(d_name); kfree(d_name);
DT_PUTPAGE(mp); DT_PUTPAGE(mp);
unlock_kernel();
return rc; return rc;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
int simple_statfs(struct super_block *sb, struct statfs *buf) int simple_statfs(struct super_block *sb, struct statfs *buf)
{ {
...@@ -40,6 +41,8 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -40,6 +41,8 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
int i; int i;
struct dentry *dentry = filp->f_dentry; struct dentry *dentry = filp->f_dentry;
lock_kernel();
i = filp->f_pos; i = filp->f_pos;
switch (i) { switch (i) {
case 0: case 0:
...@@ -64,6 +67,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -64,6 +67,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
for (;;) { for (;;) {
if (list == &dentry->d_subdirs) { if (list == &dentry->d_subdirs) {
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
unlock_kernel();
return 0; return 0;
} }
if (!j) if (!j)
...@@ -94,6 +98,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -94,6 +98,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
} }
} }
} }
unlock_kernel();
return 0; return 0;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
*/ */
#include "minix.h" #include "minix.h"
#include <linux/smp_lock.h>
typedef struct minix_dir_entry minix_dirent; typedef struct minix_dir_entry minix_dirent;
...@@ -89,6 +90,8 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -89,6 +90,8 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
struct minix_sb_info *sbi = minix_sb(sb); struct minix_sb_info *sbi = minix_sb(sb);
unsigned chunk_size = sbi->s_dirsize; unsigned chunk_size = sbi->s_dirsize;
lock_kernel();
pos = (pos + chunk_size-1) & ~(chunk_size-1); pos = (pos + chunk_size-1) & ~(chunk_size-1);
if (pos >= inode->i_size) if (pos >= inode->i_size)
goto done; goto done;
...@@ -124,6 +127,7 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -124,6 +127,7 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
done: done:
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -400,6 +400,8 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -400,6 +400,8 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
int result, mtime_valid = 0; int result, mtime_valid = 0;
time_t mtime = 0; time_t mtime = 0;
lock_kernel();
ctl.page = NULL; ctl.page = NULL;
ctl.cache = NULL; ctl.cache = NULL;
...@@ -533,6 +535,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -533,6 +535,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
page_cache_release(ctl.page); page_cache_release(ctl.page);
} }
out: out:
unlock_kernel();
return result; return result;
} }
......
...@@ -355,9 +355,13 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -355,9 +355,13 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct nfs_entry my_entry; struct nfs_entry my_entry;
long res; long res;
lock_kernel();
res = nfs_revalidate(dentry); res = nfs_revalidate(dentry);
if (res < 0) if (res < 0) {
unlock_kernel();
return res; return res;
}
/* /*
* filp->f_pos points to the file offset in the page cache. * filp->f_pos points to the file offset in the page cache.
...@@ -394,6 +398,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -394,6 +398,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
break; break;
} }
} }
unlock_kernel();
if (desc->error < 0) if (desc->error < 0)
return desc->error; return desc->error;
if (res < 0) if (res < 0)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/nfs.h> #include <linux/nfs.h>
#include <linux/nfs3.h> #include <linux/nfs3.h>
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
#include <linux/smp_lock.h>
#define NFSDBG_FACILITY NFSDBG_PROC #define NFSDBG_FACILITY NFSDBG_PROC
...@@ -560,6 +561,8 @@ nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred, ...@@ -560,6 +561,8 @@ nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred,
u32 *verf = NFS_COOKIEVERF(dir); u32 *verf = NFS_COOKIEVERF(dir);
int status; int status;
lock_kernel();
arg.buffer = entry; arg.buffer = entry;
arg.bufsiz = size; arg.bufsiz = size;
arg.verf[0] = verf[0]; arg.verf[0] = verf[0];
...@@ -580,6 +583,7 @@ nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred, ...@@ -580,6 +583,7 @@ nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_refresh_inode(dir, &dir_attr); nfs_refresh_inode(dir, &dir_attr);
dprintk("NFS reply readdir: %d\n", status); dprintk("NFS reply readdir: %d\n", status);
unlock_kernel();
return status; return status;
} }
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/nfs.h> #include <linux/nfs.h>
#include <linux/nfs2.h> #include <linux/nfs2.h>
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
#include <linux/smp_lock.h>
#define NFSDBG_FACILITY NFSDBG_PROC #define NFSDBG_FACILITY NFSDBG_PROC
...@@ -440,6 +441,8 @@ nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred, ...@@ -440,6 +441,8 @@ nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred,
}; };
int status; int status;
lock_kernel();
arg.fh = NFS_FH(dir); arg.fh = NFS_FH(dir);
arg.cookie = cookie; arg.cookie = cookie;
arg.buffer = entry; arg.buffer = entry;
...@@ -451,6 +454,7 @@ nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred, ...@@ -451,6 +454,7 @@ nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
dprintk("NFS reply readdir: %d\n", status); dprintk("NFS reply readdir: %d\n", status);
unlock_kernel();
return status; return status;
} }
......
...@@ -757,11 +757,13 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld ...@@ -757,11 +757,13 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
char *p; char *p;
char buffer2[64]; char buffer2[64];
lock_kernel();
ino = inode->i_ino; ino = inode->i_ino;
i = filp->f_pos; i = filp->f_pos;
switch (i) { switch (i) {
case 0: 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++; i++;
filp->f_pos++; filp->f_pos++;
/* fall thru */ /* fall thru */
...@@ -769,7 +771,7 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld ...@@ -769,7 +771,7 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
if (filldir(dirent, "..", 2, i, if (filldir(dirent, "..", 2, i,
(NODE(ino).parent == 0xffff) ? (NODE(ino).parent == 0xffff) ?
OPENPROM_ROOT_INO : NODE2INO(NODE(ino).parent), DT_DIR) < 0) OPENPROM_ROOT_INO : NODE2INO(NODE(ino).parent), DT_DIR) < 0)
return 0; goto out;
i++; i++;
filp->f_pos++; filp->f_pos++;
/* fall thru */ /* fall thru */
...@@ -782,17 +784,17 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld ...@@ -782,17 +784,17 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
} }
while (node != 0xffff) { while (node != 0xffff) {
if (prom_getname (nodes[node].node, buffer, 128) < 0) if (prom_getname (nodes[node].node, buffer, 128) < 0)
return 0; goto out;
if (filldir(dirent, buffer, strlen(buffer), if (filldir(dirent, buffer, strlen(buffer),
filp->f_pos, NODE2INO(node), DT_DIR) < 0) filp->f_pos, NODE2INO(node), DT_DIR) < 0)
return 0; goto out;
filp->f_pos++; filp->f_pos++;
node = nodes[node].next; node = nodes[node].next;
} }
j = NODEP2INO(NODE(ino).first_prop); j = NODEP2INO(NODE(ino).first_prop);
if (!i) { if (!i) {
if (filldir(dirent, ".node", 5, filp->f_pos, j, DT_REG) < 0) if (filldir(dirent, ".node", 5, filp->f_pos, j, DT_REG) < 0)
return 0; goto out;
filp->f_pos++; filp->f_pos++;
} else } else
i--; i--;
...@@ -802,7 +804,7 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld ...@@ -802,7 +804,7 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
if (alias_names [i]) { if (alias_names [i]) {
if (filldir (dirent, alias_names [i], if (filldir (dirent, alias_names [i],
strlen (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++; filp->f_pos++;
} }
} }
...@@ -815,12 +817,14 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld ...@@ -815,12 +817,14 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
else { else {
if (filldir(dirent, p, strlen(p), if (filldir(dirent, p, strlen(p),
filp->f_pos, j, DT_REG) < 0) filp->f_pos, j, DT_REG) < 0)
return 0; goto out;
filp->f_pos++; filp->f_pos++;
} }
} }
} }
} }
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/namespace.h> #include <linux/namespace.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/smp_lock.h>
/* /*
* For hysterical raisins we keep the same inumbers as in the old procfs. * For hysterical raisins we keep the same inumbers as in the old procfs.
...@@ -571,6 +572,8 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen) ...@@ -571,6 +572,8 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
struct dentry *de; struct dentry *de;
struct vfsmount *mnt = NULL; struct vfsmount *mnt = NULL;
lock_kernel();
if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
goto out; goto out;
error = proc_check_root(inode); error = proc_check_root(inode);
...@@ -585,6 +588,7 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen) ...@@ -585,6 +588,7 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
dput(de); dput(de);
mntput(mnt); mntput(mnt);
out: out:
unlock_kernel();
return error; return error;
} }
...@@ -665,38 +669,49 @@ static int proc_base_readdir(struct file * filp, ...@@ -665,38 +669,49 @@ static int proc_base_readdir(struct file * filp,
int pid; int pid;
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
struct pid_entry *p; struct pid_entry *p;
int ret = 0;
lock_kernel();
pid = proc_task(inode)->pid; pid = proc_task(inode)->pid;
if (!pid) if (!pid) {
return -ENOENT; ret = -ENOENT;
goto out;
}
i = filp->f_pos; i = filp->f_pos;
switch (i) { switch (i) {
case 0: case 0:
if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0)
return 0; goto out;
i++; i++;
filp->f_pos++; filp->f_pos++;
/* fall through */ /* fall through */
case 1: case 1:
if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0) if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0)
return 0; goto out;
i++; i++;
filp->f_pos++; filp->f_pos++;
/* fall through */ /* fall through */
default: default:
i -= 2; i -= 2;
if (i>=sizeof(base_stuff)/sizeof(base_stuff[0])) if (i>=sizeof(base_stuff)/sizeof(base_stuff[0])) {
return 1; ret = 1;
goto out;
}
p = base_stuff + i; p = base_stuff + i;
while (p->name) { while (p->name) {
if (filldir(dirent, p->name, p->len, filp->f_pos, if (filldir(dirent, p->name, p->len, filp->f_pos,
fake_ino(pid, p->type), p->mode >> 12) < 0) fake_ino(pid, p->type), p->mode >> 12) < 0)
return 0; goto out;
filp->f_pos++; filp->f_pos++;
p++; p++;
} }
} }
return 1;
ret = 1;
out:
unlock_kernel();
return ret;
} }
/* building an inode */ /* building an inode */
......
...@@ -304,16 +304,21 @@ int proc_readdir(struct file * filp, ...@@ -304,16 +304,21 @@ int proc_readdir(struct file * filp,
unsigned int ino; unsigned int ino;
int i; int i;
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
int ret = 0;
lock_kernel();
ino = inode->i_ino; ino = inode->i_ino;
de = PDE(inode); de = PDE(inode);
if (!de) if (!de) {
return -EINVAL; ret = -EINVAL;
goto out;
}
i = filp->f_pos; i = filp->f_pos;
switch (i) { switch (i) {
case 0: case 0:
if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
return 0; goto out;
i++; i++;
filp->f_pos++; filp->f_pos++;
/* fall through */ /* fall through */
...@@ -321,7 +326,7 @@ int proc_readdir(struct file * filp, ...@@ -321,7 +326,7 @@ int proc_readdir(struct file * filp,
if (filldir(dirent, "..", 2, i, if (filldir(dirent, "..", 2, i,
parent_ino(filp->f_dentry), parent_ino(filp->f_dentry),
DT_DIR) < 0) DT_DIR) < 0)
return 0; goto out;
i++; i++;
filp->f_pos++; filp->f_pos++;
/* fall through */ /* fall through */
...@@ -329,8 +334,10 @@ int proc_readdir(struct file * filp, ...@@ -329,8 +334,10 @@ int proc_readdir(struct file * filp,
de = de->subdir; de = de->subdir;
i -= 2; i -= 2;
for (;;) { for (;;) {
if (!de) if (!de) {
return 1; ret = 1;
goto out;
}
if (!i) if (!i)
break; break;
de = de->next; de = de->next;
...@@ -340,12 +347,14 @@ int proc_readdir(struct file * filp, ...@@ -340,12 +347,14 @@ int proc_readdir(struct file * filp,
do { do {
if (filldir(dirent, de->name, de->namelen, filp->f_pos, if (filldir(dirent, de->name, de->namelen, filp->f_pos,
de->low_ino, de->mode >> 12) < 0) de->low_ino, de->mode >> 12) < 0)
return 0; goto out;
filp->f_pos++; filp->f_pos++;
de = de->next; de = de->next;
} while (de); } while (de);
} }
return 1; ret = 1;
out: unlock_kernel();
return ret;
} }
/* /*
......
...@@ -98,15 +98,22 @@ static int proc_root_readdir(struct file * filp, ...@@ -98,15 +98,22 @@ static int proc_root_readdir(struct file * filp,
void * dirent, filldir_t filldir) void * dirent, filldir_t filldir)
{ {
unsigned int nr = filp->f_pos; unsigned int nr = filp->f_pos;
int ret;
lock_kernel();
if (nr < FIRST_PROCESS_ENTRY) { if (nr < FIRST_PROCESS_ENTRY) {
int error = proc_readdir(filp, dirent, filldir); int error = proc_readdir(filp, dirent, filldir);
if (error <= 0) if (error <= 0) {
unlock_kernel();
return error; return error;
}
filp->f_pos = FIRST_PROCESS_ENTRY; filp->f_pos = FIRST_PROCESS_ENTRY;
} }
return proc_pid_readdir(filp, dirent, filldir); ret = proc_pid_readdir(filp, dirent, filldir);
unlock_kernel();
return ret;
} }
/* /*
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/qnx4_fs.h> #include <linux/qnx4_fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/smp_lock.h>
static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
...@@ -33,6 +34,8 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -33,6 +34,8 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
QNX4DEBUG(("qnx4_readdir:i_size = %ld\n", (long) inode->i_size)); QNX4DEBUG(("qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
QNX4DEBUG(("filp->f_pos = %ld\n", (long) filp->f_pos)); QNX4DEBUG(("filp->f_pos = %ld\n", (long) filp->f_pos));
lock_kernel();
while (filp->f_pos < inode->i_size) { while (filp->f_pos < inode->i_size) {
blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS ); blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS );
bh = sb_bread(inode->i_sb, blknum); bh = sb_bread(inode->i_sb, blknum);
...@@ -63,7 +66,7 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -63,7 +66,7 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
} }
if (filldir(dirent, de->di_fname, size, filp->f_pos, ino, DT_UNKNOWN) < 0) { if (filldir(dirent, de->di_fname, size, filp->f_pos, ino, DT_UNKNOWN) < 0) {
brelse(bh); brelse(bh);
return 0; goto out;
} }
} }
} }
...@@ -74,6 +77,8 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -74,6 +77,8 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
} }
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
out:
unlock_kernel();
return 0; return 0;
} }
......
...@@ -23,9 +23,7 @@ int vfs_readdir(struct file *file, filldir_t filler, void *buf) ...@@ -23,9 +23,7 @@ int vfs_readdir(struct file *file, filldir_t filler, void *buf)
down(&inode->i_sem); down(&inode->i_sem);
res = -ENOENT; res = -ENOENT;
if (!IS_DEADDIR(inode)) { if (!IS_DEADDIR(inode)) {
lock_kernel();
res = file->f_op->readdir(file, buf, filler); res = file->f_op->readdir(file, buf, filler);
unlock_kernel();
} }
up(&inode->i_sem); up(&inode->i_sem);
out: out:
......
...@@ -47,7 +47,9 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -47,7 +47,9 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
loff_t next_pos; loff_t next_pos;
char small_buf[32] ; /* avoid kmalloc if we can */ char small_buf[32] ; /* avoid kmalloc if we can */
struct reiserfs_dir_entry de; struct reiserfs_dir_entry de;
int ret = 0;
lock_kernel();
reiserfs_check_lock_depth("readdir") ; reiserfs_check_lock_depth("readdir") ;
...@@ -66,7 +68,8 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -66,7 +68,8 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
if (search_res == IO_ERROR) { if (search_res == IO_ERROR) {
// FIXME: we could just skip part of directory which could // FIXME: we could just skip part of directory which could
// not be read // not be read
return -EIO; ret = -EIO;
goto out;
} }
entry_num = de.de_entry_num; entry_num = de.de_entry_num;
bh = de.de_bh; bh = de.de_bh;
...@@ -118,7 +121,8 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -118,7 +121,8 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ; local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
if (!local_buf) { if (!local_buf) {
pathrelse (&path_to_entry); pathrelse (&path_to_entry);
return -ENOMEM ; ret = -ENOMEM ;
goto out;
} }
if (item_moved (&tmp_ih, &path_to_entry)) { if (item_moved (&tmp_ih, &path_to_entry)) {
reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ; reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
...@@ -181,7 +185,9 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -181,7 +185,9 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
pathrelse (&path_to_entry); pathrelse (&path_to_entry);
reiserfs_check_path(&path_to_entry) ; reiserfs_check_path(&path_to_entry) ;
UPDATE_ATIME(inode) ; UPDATE_ATIME(inode) ;
return 0; out:
unlock_kernel();
return ret;
} }
/* compose directory item containing "." and ".." entries (entries are /* compose directory item containing "." and ".." entries (entries are
......
...@@ -273,13 +273,15 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -273,13 +273,15 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int stored = 0; int stored = 0;
char fsname[ROMFS_MAXFN]; /* XXX dynamic? */ char fsname[ROMFS_MAXFN]; /* XXX dynamic? */
lock_kernel();
maxoff = i->i_sb->u.romfs_sb.s_maxsize; maxoff = i->i_sb->u.romfs_sb.s_maxsize;
offset = filp->f_pos; offset = filp->f_pos;
if (!offset) { if (!offset) {
offset = i->i_ino & ROMFH_MASK; offset = i->i_ino & ROMFH_MASK;
if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0) if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)
return stored; goto out;
offset = ntohl(ri.spec) & ROMFH_MASK; offset = ntohl(ri.spec) & ROMFH_MASK;
} }
...@@ -288,17 +290,17 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -288,17 +290,17 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (!offset || offset >= maxoff) { if (!offset || offset >= maxoff) {
offset = maxoff; offset = maxoff;
filp->f_pos = offset; filp->f_pos = offset;
return stored; goto out;
} }
filp->f_pos = offset; filp->f_pos = offset;
/* Fetch inode info */ /* Fetch inode info */
if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0) if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)
return stored; goto out;
j = romfs_strnlen(i, offset+ROMFH_SIZE, sizeof(fsname)-1); j = romfs_strnlen(i, offset+ROMFH_SIZE, sizeof(fsname)-1);
if (j < 0) if (j < 0)
return stored; goto out;
fsname[j]=0; fsname[j]=0;
romfs_copyfrom(i, fsname, offset+ROMFH_SIZE, j); romfs_copyfrom(i, fsname, offset+ROMFH_SIZE, j);
...@@ -309,11 +311,14 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -309,11 +311,14 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
ino = ntohl(ri.spec); ino = ntohl(ri.spec);
if (filldir(dirent, fsname, j, offset, ino, if (filldir(dirent, fsname, j, offset, ino,
romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0) { romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0) {
return stored; goto out;
} }
stored++; stored++;
offset = nextfh & ROMFH_MASK; offset = nextfh & ROMFH_MASK;
} }
out:
unlock_kernel();
return stored;
} }
static struct dentry * static struct dentry *
......
...@@ -75,6 +75,9 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -75,6 +75,9 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
DENTRY_PATH(dentry), (int) filp->f_pos); DENTRY_PATH(dentry), (int) filp->f_pos);
result = 0; result = 0;
lock_kernel();
switch ((unsigned int) filp->f_pos) { switch ((unsigned int) filp->f_pos) {
case 0: case 0:
if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
...@@ -207,6 +210,7 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -207,6 +210,7 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
page_cache_release(ctl.page); page_cache_release(ctl.page);
} }
out: out:
unlock_kernel();
return result; return result;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/dirent.h> #include <linux/dirent.h>
#include <linux/nls.h> #include <linux/nls.h>
#include <linux/smp_lock.h>
#include <linux/smb_fs.h> #include <linux/smb_fs.h>
#include <linux/smbno.h> #include <linux/smbno.h>
...@@ -1906,6 +1907,8 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, ...@@ -1906,6 +1907,8 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
VERBOSE("%s/%s\n", DENTRY_PATH(dir)); VERBOSE("%s/%s\n", DENTRY_PATH(dir));
lock_kernel();
smb_lock_server(server); smb_lock_server(server);
first = 1; first = 1;
...@@ -2012,6 +2015,7 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, ...@@ -2012,6 +2015,7 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
unlock_return: unlock_return:
smb_unlock_server(server); smb_unlock_server(server);
unlock_kernel();
return result; return result;
} }
...@@ -2172,6 +2176,8 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, ...@@ -2172,6 +2176,8 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
len: 1, len: 1,
}; };
lock_kernel();
/* /*
* use info level 1 for older servers that don't do 260 * use info level 1 for older servers that don't do 260
*/ */
...@@ -2357,6 +2363,7 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, ...@@ -2357,6 +2363,7 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
unlock_return: unlock_return:
smb_unlock_server(server); smb_unlock_server(server);
unlock_kernel();
return result; return result;
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,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 int sysv_readdir(struct file *, void *, filldir_t); static int sysv_readdir(struct file *, void *, filldir_t);
...@@ -76,6 +77,8 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -76,6 +77,8 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
unsigned long n = pos >> PAGE_CACHE_SHIFT; unsigned long n = pos >> PAGE_CACHE_SHIFT;
unsigned long npages = dir_pages(inode); unsigned long npages = dir_pages(inode);
lock_kernel();
pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1);
if (pos >= inode->i_size) if (pos >= inode->i_size)
goto done; goto done;
...@@ -113,6 +116,7 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -113,6 +116,7 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
done: done:
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
...@@ -83,15 +84,20 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -83,15 +84,20 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct inode *dir = filp->f_dentry->d_inode; struct inode *dir = filp->f_dentry->d_inode;
int result; int result;
lock_kernel();
if ( filp->f_pos == 0 ) 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; return 0;
}
filp->f_pos ++; filp->f_pos ++;
} }
result = do_udf_readdir(dir, filp, filldir, dirent); result = do_udf_readdir(dir, filp, filldir, dirent);
UPDATE_ATIME(dir); UPDATE_ATIME(dir);
unlock_kernel();
return result; return result;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/ufs_fs.h> #include <linux/ufs_fs.h>
#include <linux/smp_lock.h>
#include "swab.h" #include "swab.h"
#include "util.h" #include "util.h"
...@@ -62,6 +63,8 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) ...@@ -62,6 +63,8 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
int de_reclen; int de_reclen;
unsigned flags; unsigned flags;
lock_kernel();
sb = inode->i_sb; sb = inode->i_sb;
flags = sb->u.ufs_sb.s_flags; flags = sb->u.ufs_sb.s_flags;
...@@ -117,6 +120,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) ...@@ -117,6 +120,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
(sb->s_blocksize - 1)) + (sb->s_blocksize - 1)) +
sb->s_blocksize; sb->s_blocksize;
brelse(bh); brelse(bh);
unlock_kernel();
return stored; return stored;
} }
if (!ufs_check_dir_entry ("ufs_readdir", inode, de, if (!ufs_check_dir_entry ("ufs_readdir", inode, de,
...@@ -127,6 +131,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) ...@@ -127,6 +131,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
(sb->s_blocksize - 1)) + (sb->s_blocksize - 1)) +
1; 1;
brelse (bh); brelse (bh);
unlock_kernel();
return stored; return stored;
} }
offset += fs16_to_cpu(sb, de->d_reclen); offset += fs16_to_cpu(sb, de->d_reclen);
...@@ -161,6 +166,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir) ...@@ -161,6 +166,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
brelse (bh); brelse (bh);
} }
UPDATE_ATIME(inode); UPDATE_ATIME(inode);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/umsdos_fs.h> #include <linux/umsdos_fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
#define UMSDOS_SPECIAL_DIRFPOS 3 #define UMSDOS_SPECIAL_DIRFPOS 3
extern struct dentry *saved_root; extern struct dentry *saved_root;
...@@ -302,6 +303,8 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir) ...@@ -302,6 +303,8 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
int ret = 0, count = 0; int ret = 0, count = 0;
struct UMSDOS_DIR_ONCE bufk; struct UMSDOS_DIR_ONCE bufk;
lock_kernel();
bufk.dirbuf = dirbuf; bufk.dirbuf = dirbuf;
bufk.filldir = filldir; bufk.filldir = filldir;
bufk.stop = 0; bufk.stop = 0;
...@@ -317,6 +320,7 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir) ...@@ -317,6 +320,7 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
break; break;
count += bufk.count; count += bufk.count;
} }
unlock_kernel();
Printk (("UMSDOS_readdir out %d count %d pos %Ld\n", Printk (("UMSDOS_readdir out %d count %d pos %Ld\n",
ret, count, filp->f_pos)); ret, count, filp->f_pos));
return count ? : ret; return count ? : ret;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/limits.h> #include <linux/limits.h>
#include <linux/umsdos_fs.h> #include <linux/umsdos_fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -63,11 +64,15 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir) ...@@ -63,11 +64,15 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
{ {
struct inode *dir = filp->f_dentry->d_inode; struct inode *dir = filp->f_dentry->d_inode;
struct RDIR_FILLDIR bufk; struct RDIR_FILLDIR bufk;
int ret;
lock_kernel();
bufk.filldir = filldir; bufk.filldir = filldir;
bufk.dirbuf = dirbuf; bufk.dirbuf = dirbuf;
bufk.real_root = pseudo_root && (dir == saved_root->d_inode); 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;
} }
......
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