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:
llseek: yes (see below)
read: no
write: no
readdir: yes (see below)
readdir: no
poll: no
ioctl: yes (see below)
mmap: no
......
......@@ -97,18 +97,20 @@ static int capifs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
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 @@ static int capifs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
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;
}
......
......@@ -36,6 +36,8 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct adfs_dir dir;
int ret = 0;
lock_kernel();
if (filp->f_pos >> 32)
goto out;
......@@ -77,6 +79,7 @@ adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
ops->free(&dir);
out:
unlock_kernel();
return ret;
}
......
......@@ -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 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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_readdir(struct file *filp, void *dirent, filldir_t filldir)
affs_brelse(dir_bh);
affs_brelse(fh_bh);
affs_unlock_dir(inode);
unlock_kernel();
pr_debug("AFFS: readdir()=%d\n", stored);
return res;
}
......@@ -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;
off_t onr, nr;
lock_kernel();
sbi = autofs_sbi(inode->i_sb);
dirhash = &sbi->dirhash;
nr = filp->f_pos;
......@@ -55,25 +57,27 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
{
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;
}
......
......@@ -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
......
......@@ -32,9 +32,12 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
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 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
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 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
}
UPDATE_ATIME(dir);
unlock_kernel();
return 0;
}
......
......@@ -293,6 +293,8 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (offset & 3)
return -EINVAL;
lock_kernel();
copied = 0;
while (offset < inode->i_size) {
struct cramfs_inode *de;
......@@ -313,8 +315,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
filp->f_pos = offset;
copied++;
}
unlock_kernel();
return 0;
}
......
......@@ -48,18 +48,20 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi
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 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi
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;
}
......
......@@ -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 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
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 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
}
brelse(bh);
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
return 0;
goto out;
}
slot++;
}
......@@ -102,6 +105,8 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) {
}
filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
out:
unlock_kernel();
return 0;
}
......@@ -23,6 +23,7 @@
#include "ext2.h"
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
......@@ -258,6 +259,8 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
int need_revalidate = (filp->f_version != inode->i_version);
int ret = 0;
lock_kernel();
if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
goto done;
......@@ -310,6 +313,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
filp->f_version = inode->i_version;
UPDATE_ATIME(inode);
unlock_kernel();
return 0;
}
......
......@@ -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 @@ static int ext3_readdir(struct file *, void *, filldir_t);
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 @@ static int ext3_readdir(struct file * filp,
int err;
struct inode *inode = filp->f_dentry->d_inode;
lock_kernel();
sb = inode->i_sb;
stored = 0;
......@@ -150,6 +153,7 @@ static int ext3_readdir(struct file * filp,
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 @@ static int ext3_readdir(struct file * filp,
brelse (bh);
}
UPDATE_ATIME(inode);
unlock_kernel();
return 0;
}
......@@ -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 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
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 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
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 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
if (!unicode) {
filp->f_pos = cpos;
fat_brelse(sb, bh);
return -ENOMEM;
ret = -ENOMEM;
goto out;
}
}
ParseLong:
......@@ -580,7 +587,9 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
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)
......
......@@ -262,8 +262,10 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
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 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
done:
fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
out:
unlock_kernel();
return 0;
}
......@@ -188,6 +188,8 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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 @@ static int cap_readdir(struct file * filp,
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;
}
......
......@@ -182,13 +182,15 @@ static int dbl_readdir(struct file * filp,
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 @@ static int dbl_readdir(struct file * filp,
/* 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 @@ static int dbl_readdir(struct file * filp,
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 @@ static int dbl_readdir(struct file * filp,
} 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 @@ static int dbl_readdir(struct file * filp,
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 @@ static int dbl_readdir(struct file * filp,
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;
}
......
......@@ -188,6 +188,8 @@ static int nat_readdir(struct file * filp,
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 @@ static int nat_readdir(struct file * filp,
/* 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 @@ static int nat_readdir(struct file * filp,
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 @@ static int nat_readdir(struct file * filp,
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 @@ static int nat_readdir(struct file * filp,
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 @@ static int nat_readdir(struct file * filp,
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 @@ static int nat_readdir(struct file * filp,
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 @@ static int nat_readdir(struct file * filp,
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;
}
......
......@@ -62,19 +62,26 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ 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);
}
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 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
/*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 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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;
}
/*
......
......@@ -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 @@ static int isofs_readdir(struct file *filp,
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 @@ static int isofs_readdir(struct file *filp,
result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde);
free_page((unsigned long) tmpname);
unlock_kernel();
return result;
}
......@@ -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 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
up(&c->fmc->biglock);
unlock_kernel();
return filp->f_pos;
} /* jffs_readdir() */
......
......@@ -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 @@ 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));
lock_kernel();
f = JFFS2_INODE_INFO(inode);
c = JFFS2_SB_INFO(inode->i_sb);
......@@ -186,6 +189,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
up(&f->sem);
out:
filp->f_pos = offset;
unlock_kernel();
return 0;
}
......
......@@ -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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filp->f_pos == DIREND)
return 0;
lock_kernel();
if (DO_INDEX(ip)) {
/*
* persistent index is stored in directory entries.
......@@ -2885,12 +2888,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
*/
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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* 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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* 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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (dtEmpty(ip)) {
filp->f_pos = DIREND;
unlock_kernel();
return 0;
}
......@@ -2996,6 +3017,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
("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 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* offset beyond directory eof ? */
if (bn < 0) {
filp->f_pos = DIREND;
unlock_kernel();
return 0;
}
}
......@@ -3013,6 +3036,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
DT_PUTPAGE(mp);
jERROR(1, ("jfs_readdir: kmalloc failed!\n"));
filp->f_pos = DIREND;
unlock_kernel();
return 0;
}
while (1) {
......@@ -3087,6 +3111,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
if (rc) {
kfree(d_name);
unlock_kernel();
return -rc;
}
......@@ -3102,7 +3127,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
out:
kfree(d_name);
DT_PUTPAGE(mp);
unlock_kernel();
return rc;
}
......
......@@ -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 dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
int i;
struct dentry *dentry = filp->f_dentry;
lock_kernel();
i = filp->f_pos;
switch (i) {
case 0:
......@@ -64,6 +67,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
for (;;) {
if (list == &dentry->d_subdirs) {
spin_unlock(&dcache_lock);
unlock_kernel();
return 0;
}
if (!j)
......@@ -94,6 +98,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
}
}
}
unlock_kernel();
return 0;
}
......
......@@ -7,6 +7,7 @@
*/
#include "minix.h"
#include <linux/smp_lock.h>
typedef struct minix_dir_entry minix_dirent;
......@@ -89,6 +90,8 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
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;
......@@ -124,6 +127,7 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
done:
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode);
unlock_kernel();
return 0;
}
......
......@@ -400,6 +400,8 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
int result, mtime_valid = 0;
time_t mtime = 0;
lock_kernel();
ctl.page = NULL;
ctl.cache = NULL;
......@@ -533,6 +535,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
page_cache_release(ctl.page);
}
out:
unlock_kernel();
return result;
}
......
......@@ -355,9 +355,13 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
break;
}
}
unlock_kernel();
if (desc->error < 0)
return desc->error;
if (res < 0)
......
......@@ -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 @@ nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred,
u32 *verf = NFS_COOKIEVERF(dir);
int status;
lock_kernel();
arg.buffer = entry;
arg.bufsiz = size;
arg.verf[0] = verf[0];
......@@ -580,6 +583,7 @@ nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred,
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;
}
......
......@@ -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 @@ nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred,
};
int status;
lock_kernel();
arg.fh = NFS_FH(dir);
arg.cookie = cookie;
arg.buffer = entry;
......@@ -451,6 +454,7 @@ nfs_proc_readdir(struct inode *dir, struct rpc_cred *cred,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
dprintk("NFS reply readdir: %d\n", status);
unlock_kernel();
return status;
}
......
......@@ -757,11 +757,13 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
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 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
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 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
}
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 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
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 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
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;
}
......
......@@ -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 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
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 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
dput(de);
mntput(mnt);
out:
unlock_kernel();
return error;
}
......@@ -665,38 +669,49 @@ static int proc_base_readdir(struct file * filp,
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 */
......
......@@ -304,16 +304,21 @@ int proc_readdir(struct file * filp,
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 @@ int proc_readdir(struct file * filp,
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 @@ int proc_readdir(struct file * filp,
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 @@ int proc_readdir(struct file * filp,
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;
}
/*
......
......@@ -98,15 +98,22 @@ static int proc_root_readdir(struct file * filp,
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;
}
/*
......
......@@ -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 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ 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) {
brelse(bh);
return 0;
goto out;
}
}
}
......@@ -74,6 +77,8 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
UPDATE_ATIME(inode);
out:
unlock_kernel();
return 0;
}
......
......@@ -23,9 +23,7 @@ int vfs_readdir(struct file *file, filldir_t filler, void *buf)
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:
......
......@@ -47,7 +47,9 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
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 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
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 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
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 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
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
......
......@@ -273,13 +273,15 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 *
......
......@@ -75,6 +75,9 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
page_cache_release(ctl.page);
}
out:
unlock_kernel();
return result;
}
......
......@@ -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 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
VERBOSE("%s/%s\n", DENTRY_PATH(dir));
lock_kernel();
smb_lock_server(server);
first = 1;
......@@ -2012,6 +2015,7 @@ smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
unlock_return:
smb_unlock_server(server);
unlock_kernel();
return result;
}
......@@ -2172,6 +2176,8 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
len: 1,
};
lock_kernel();
/*
* 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,
unlock_return:
smb_unlock_server(server);
unlock_kernel();
return result;
}
......
......@@ -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);
......@@ -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 npages = dir_pages(inode);
lock_kernel();
pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1);
if (pos >= inode->i_size)
goto done;
......@@ -113,6 +116,7 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
done:
filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode);
unlock_kernel();
return 0;
}
......
......@@ -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 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
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;
}
......
......@@ -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 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
int de_reclen;
unsigned flags;
lock_kernel();
sb = inode->i_sb;
flags = sb->u.ufs_sb.s_flags;
......@@ -117,6 +120,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
(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 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
(sb->s_blocksize - 1)) +
1;
brelse (bh);
unlock_kernel();
return stored;
}
offset += fs16_to_cpu(sb, de->d_reclen);
......@@ -161,6 +166,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
brelse (bh);
}
UPDATE_ATIME(inode);
unlock_kernel();
return 0;
}
......
......@@ -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 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
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 @@ static int UMSDOS_readdir (struct file *filp, void *dirbuf, filldir_t filldir)
break;
count += bufk.count;
}
unlock_kernel();
Printk (("UMSDOS_readdir out %d count %d pos %Ld\n",
ret, count, filp->f_pos));
return count ? : ret;
......
......@@ -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 @@ static int UMSDOS_rreaddir (struct file *filp, void *dirbuf, filldir_t filldir)
{
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;
}
......
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