]> git.hungrycats.org Git - linux/commitdiff
[PATCH] shift BKL out of vfs_readdir
authorDave Hansen <haveblue@us.ibm.com>
Tue, 30 Apr 2002 07:00:53 +0000 (00:00 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 30 Apr 2002 07:00:53 +0000 (00:00 -0700)
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.

43 files changed:
Documentation/filesystems/Locking
drivers/isdn/capi/capifs.c
fs/adfs/dir.c
fs/affs/dir.c
fs/autofs/root.c
fs/bad_inode.c
fs/bfs/dir.c
fs/cramfs/inode.c
fs/devpts/root.c
fs/efs/dir.c
fs/ext2/dir.c
fs/ext3/dir.c
fs/fat/dir.c
fs/freevxfs/vxfs_lookup.c
fs/hfs/dir_cap.c
fs/hfs/dir_dbl.c
fs/hfs/dir_nat.c
fs/hpfs/dir.c
fs/isofs/dir.c
fs/jffs/inode-v23.c
fs/jffs2/dir.c
fs/jfs/jfs_dtree.c
fs/libfs.c
fs/minix/dir.c
fs/ncpfs/dir.c
fs/nfs/dir.c
fs/nfs/nfs3proc.c
fs/nfs/proc.c
fs/openpromfs/inode.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/root.c
fs/qnx4/dir.c
fs/readdir.c
fs/reiserfs/dir.c
fs/romfs/inode.c
fs/smbfs/dir.c
fs/smbfs/proc.c
fs/sysv/dir.c
fs/udf/dir.c
fs/ufs/dir.c
fs/umsdos/dir.c
fs/umsdos/rdir.c

index a4f00200bda2d1a29eff2056a4f6700bb9a4f8ca..c7c8abb88739e3da2ea357a99c455959de197095 100644 (file)
@@ -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
index 1974ff61c5ebdabec40bf42012045f98631180c3..f0c79911456fd789c7ecf676bcdfcf3f7fe94d09 100644 (file)
@@ -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;
 }
 
index fdc55ae209da3498c107af0b67c2ef8c1e2e190d..e50456ba1e69625bec4f5a35c8a06355fd65b55e 100644 (file)
@@ -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 @@ free_out:
        ops->free(&dir);
 
 out:
+       unlock_kernel();
        return ret;
 }
 
index aa69197ba0ab28cf40d3a0e107cbe7833285350f..b6c3090eea79439842127666f9f7ab9a2be30e06 100644 (file)
@@ -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 @@ readdir_out:
        affs_brelse(dir_bh);
        affs_brelse(fh_bh);
        affs_unlock_dir(inode);
+       unlock_kernel();
        pr_debug("AFFS: readdir()=%d\n", stored);
        return res;
 }
index 1a6882c23dcdf54148261cba2363c06cab6aa63b..b2e8e374207f4f0b104fc98edef514047f283efd 100644 (file)
@@ -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;
 }
 
index dd4835c0f45ed3d77894f43f68b862c515b92a70..ce59d5fdb3d66a8bfe4a7c0abefe03f56370bf5d 100644 (file)
@@ -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
index eed5d411e4d7e7007b66516e32c1795c9e1a89fa..c36aff10c3c26c5205e262159f9802614c8d1022 100644 (file)
@@ -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;       
 }
 
index b363263644eaef339bb7273338fb07898122fd6f..c9a6374289cd18fd0a910aec68647b45dd7509a0 100644 (file)
@@ -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;
 }
 
index 1899fd777773dcff626a2d118594023277598c45..44e7bd7e3baaf2069af573cc4fd75c04c1a4e5da 100644 (file)
@@ -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;
 }
 
index cc7df77a034adf533ed483849e06126f0fd9d288..43a7d00bfa0d4c746bdf6ad37067a0d4ca4f68cf 100644 (file)
@@ -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;
 }
 
index 8d355d3ddef437ea30c163eec89be31b6136d4d5..abce0f410b4c1fd1234926a6a73f623919a4624b 100644 (file)
@@ -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 @@ done:
        filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
        filp->f_version = inode->i_version;
        UPDATE_ATIME(inode);
+       unlock_kernel();
        return 0;
 }
 
index 20841818f819c987fb6fd440ea2ba72e9c74796d..d0db5deffab936c93e3687237d135506f4b903ba 100644 (file)
@@ -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 @@ revalidate:
                                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 @@ revalidate:
                brelse (bh);
        }
        UPDATE_ATIME(inode);
+       unlock_kernel();
        return 0;
 }
index 0beae388f1568eee3569c75309dec5f83a5bb479..8b6f86ccc8620765c0f953e19b56125ac5358bdd 100644 (file)
@@ -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 @@ GetNew:
                        if (!unicode) {
                                filp->f_pos = cpos;
                                fat_brelse(sb, bh);
-                               return -ENOMEM;
+                               ret = -ENOMEM;
+                               goto out;
                        }
                }
 ParseLong:
@@ -580,7 +587,9 @@ FillFailed:
        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)
index f9aab253dde88c67663340fe54fe4e3ee1b487d3..1f2c91676ee7e9b6eb28caba245eeb758724e67f 100644 (file)
@@ -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;
 }
index 989496a94fc7d5ad0eca53f8345084ec790f3954..1771ba3be1f203ff3a79f08448052a2d9ba3769a 100644 (file)
@@ -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;
 }
 
index d52b4aadc2a4cccc8c3053df24e516146a066add..d0014929f6ee6dc59ae2bc509ebee8a6feb5aac6 100644 (file)
@@ -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;
 }
 
index f74d7bda40c5ccf94ab52e042a74d2996e37ab7b..cdf1d2f4cbe1287e42f7f2c97f0be088d0f6c6e9 100644 (file)
@@ -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;
 }
 
index 74343040f37ccb0d020c45f8d782454c17359bfc..0b80bdf40fa542300b11c7935f1e3c2f88a8d812 100644 (file)
@@ -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;
 }
 
 /*
index bef27095249efdc06098f81bdac701427a583603..19a643b650e665a4cc043f68a1a34fa3fbedf552 100644 (file)
@@ -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;
 }
index 05c8a549fc541dc92292c0d2f3f0bee686e54d33..3e11c2dd55b8e28b8edbe46c4972a19d3b0bc78f 100644 (file)
@@ -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()  */
 
index b2247de55d749afde8cb0364c055a80163353ccf..ce902d68cfbd374c858a2c54fd45ce72dbf43883 100644 (file)
@@ -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;
 }
 
index 9b2f07de5915902e2a26e3c5eded125627777906..9742962de44fa8246ccf36b4b656623eb2b7bc50 100644 (file)
 
 #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 @@ skip_one:
                DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
                if (rc) {
                        kfree(d_name);
+                       unlock_kernel();
                        return -rc;
                }
 
@@ -3102,7 +3127,7 @@ skip_one:
       out:
        kfree(d_name);
        DT_PUTPAGE(mp);
-
+       unlock_kernel();
        return rc;
 }
 
index e7a0a25b3e464fa06f78d9f8dc9fe6f7a8f75365..70daadc19f89e68216775fe50f207e23ad47d5c4 100644 (file)
@@ -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;
 }
 
index 19b5c6211253fd5b9e37d428dd57336afb234bb5..4cab6c48069a9a7a898e3d782b6ee4e7b752a934 100644 (file)
@@ -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;
 }
 
index cfaade2f5ffc41d0a0f598e856a22e1fdc869590..32ec4f105c24b2061625b2f0244c924356188761 100644 (file)
@@ -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 @@ finished:
                page_cache_release(ctl.page);
        }
 out:
+       unlock_kernel();
        return result;
 }
 
index 0ead2158d6475cc397b1908c40e1a26b2033fc8b..e4fb5ffd1defe9187a559c1ebc74e8cd2941cb4d 100644 (file)
@@ -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)
index 49e461bed873b1e0530eeba1afb6f07669cd29dc..14ead0ebce22420e61ab0be0c49dd4c558d01a3b 100644 (file)
@@ -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;
 }
 
index de67a8c49a113321b226adbd40305e5c7c878813..832b7c11e95cd93a1d101fb7ea2e159258979323 100644 (file)
@@ -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;
 }
 
index ec30c469a26ae1f0d4b5d272f25e522aba089be7..c9ee76ba5d063cc12c9056b9005c368a62e5cb27 100644 (file)
@@ -756,12 +756,14 @@ static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filld
        u16 node;
        char *p;
        char buffer2[64];
+
+       lock_kernel();
        
        ino = inode->i_ino;
        i = filp->f_pos;
        switch (i) {
        case 0:
-               if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) return 0;
+               if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) goto out;
                i++;
                filp->f_pos++;
                /* fall thru */
@@ -769,7 +771,7 @@ 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;
 }
 
index 52f09667163a1dfc46d40e4b106bb6e38b82e28c..4e839bd9eade26b0e5ac252fcd180da262dbe188 100644 (file)
@@ -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 */
index f492f2c581c5a79624bd83cf0f96d73fb53ad467..c91a858686b3c3cc5cdbb3ce7232cc0ae4726754 100644 (file)
@@ -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;     
 }
 
 /*
index f905a8522f5b1ef409ee337fb105f07161193f71..02c0583c452bcdf3729c3fdc4394db582eec99d0 100644 (file)
@@ -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;
 }
 
 /*
index 5eea1e3d1315d897ae65340680f9a6fb40eae2bd..d96418deaecbfa9666de4c17ca54fccd38a0c875 100644 (file)
@@ -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;
 }
 
index 48e116af0cec156555ca46830e49aac191d3005b..83789f6431f220f327ba527360d53276cf3adf40 100644 (file)
@@ -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:
index 311caba86ddbe4b304bc76f534c2f6648d95d88f..fbbe5eaaee325b6344be18633574452c7e560597 100644 (file)
@@ -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
index 369e2cfd50a19d2b73e091ff3d76a355e6fc51a4..25d55c453f931b9a0a655798cc97e4f686a4082e 100644 (file)
@@ -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 *
index 3c1385af23e0d13321a880c1a2bff352ffbba77e..6a34c53e54f90a4d1289a9087f097f11a3c78ad7 100644 (file)
@@ -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 @@ finished:
                page_cache_release(ctl.page);
        }
 out:
+       unlock_kernel();
        return result;
 }
 
index 7758d9d3829eb8f68e98412a75b307e2692f04e6..f7f065a6f7aaef209d73e6533cec6eede0304f95 100644 (file)
@@ -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;
 }
 
index ee7265650600b5d69734214e4c4715cf58d6894b..9475455186594964480a0cce6dd7537b4fde6b87 100644 (file)
@@ -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;
 }
 
index 41fa6534c88cff4ef9286c8bc825032fb6dcbf15..4d86dcfdd810dcd08809925d5ef88769316d9b2b 100644 (file)
@@ -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;
 }
 
index 1171261073c6e21fe3051b66c92a73af95e5af45..9bbd31501b7230f2bde5a77591af3ae6c172634b 100644 (file)
@@ -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 @@ revalidate:
                                              (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 @@ revalidate:
                                              (sb->s_blocksize - 1)) +
                                               1;
                                brelse (bh);
+                               unlock_kernel();
                                return stored;
                        }
                        offset += fs16_to_cpu(sb, de->d_reclen);
@@ -161,6 +166,7 @@ revalidate:
                brelse (bh);
        }
        UPDATE_ATIME(inode);
+       unlock_kernel();
        return 0;
 }
 
index 5e926d653756873a1441d671fc0bb09b3e6077c1..6f4974bcfcc29f124f59e6e465912abe2467786f 100644 (file)
@@ -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;
index edd41d95a55442d2312bda3ada5a3d2bff544271..ae315294c6af2eb7fb3da24c07a60943fc4611c5 100644 (file)
@@ -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;
 }