]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Shift BKL into ->statfs()
authorPaul Menage <pmenage@ensim.com>
Fri, 5 Jul 2002 04:11:23 +0000 (21:11 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 5 Jul 2002 04:11:23 +0000 (21:11 -0700)
This patch removes BKL protection from the invocation of the
super_operations ->statfs() method, and shifts it into the filesystems
where necessary. Any out-of-tree filesystems may need to take the BKL in
their statfs() methods if they were relying on it for synchronisation.

All ->statfs() implementations have been modified to take the BKL,
except for those that don't reference any external mutable data or that
already have their own locking.

Additionally, capifs is changed to use simple_statfs rather than its
own home-grown version.

The BKL change has been flagged at the end of
Documentation/filesystems/porting, along with the recent change to
->permission BKL usage.

14 files changed:
Documentation/filesystems/Locking
Documentation/filesystems/porting
drivers/isdn/capi/capifs.c
fs/coda/inode.c
fs/ext3/super.c
fs/freevxfs/vxfs_super.c
fs/hpfs/super.c
fs/jffs/inode-v23.c
fs/nfs/inode.c
fs/open.c
fs/qnx4/inode.c
fs/smbfs/inode.c
fs/udf/super.c
fs/ufs/super.c

index c894fcceb99664b4a614e3d231dc47ec552fc69f..9ed995b75fbff0cf07275b6bab2de5f8c494218d 100644 (file)
@@ -108,7 +108,7 @@ delete_inode:       no
 clear_inode:   no      
 put_super:     yes     yes     maybe           (see below)
 write_super:   no      yes     maybe           (see below)
-statfs:                yes     no      no
+statfs:                no      no      no
 remount_fs:    yes     yes     maybe           (see below)
 umount_begin:  yes     no      maybe           (see below)
 
index 85281b6f4ff0266f307af94c70c0b65492c40806..8d8d0b9b3d64c3a5ac4b0c216ee836c9b002b0ec 100644 (file)
@@ -81,7 +81,7 @@ can relax your locking.
 [mandatory]
 
 ->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod(), ->mkdir(),
-->rmdir(), ->link(), ->lseek(), ->symlink(), ->rename(), ->permission()
+->rmdir(), ->link(), ->lseek(), ->symlink(), ->rename()
 and ->readdir() are called without BKL now.  Grab it on entry, drop upon return
 - that will guarantee the same locking you used to have.  If your method or its
 parts do not need BKL - better yet, now you can shift lock_kernel() and
@@ -228,3 +228,19 @@ anything from oops to silent memory corruption.
        Use bdev_read_only(bdev) instead of is_read_only(kdev).  The latter
 is still alive, but only because of the mess in drivers/s390/block/dasd.c.
 As soon as it gets fixed is_read_only() will die.
+
+---
+[mandatory]
+
+->permission() is called without BKL now. Grab it on entry, drop upon
+return - that will guarantee the same locking you used to have.  If
+your method or its parts do not need BKL - better yet, now you can
+shift lock_kernel() and unlock_kernel() so that they would protect
+exactly what needs to be protected.
+
+---
+[mandatory]
+
+->statfs() is now called without BKL held.  BKL should have been
+shifted into individual fs sb_op functions where it's not clear that
+it's safe to remove it.  If you don't need it, remove it.
index 5021b597997db12cfb61e95235c7f07193a46acd..baf4b52dfe61eadee7ddab869c6085c43c9b7e19 100644 (file)
@@ -221,11 +221,9 @@ static void capifs_put_super(struct super_block *sb)
        kfree(sbi);
 }
 
-static int capifs_statfs(struct super_block *sb, struct statfs *buf);
-
 static struct super_operations capifs_sops = {
        put_super:      capifs_put_super,
-       statfs:         capifs_statfs,
+       statfs:         simple_statfs,
 };
 
 static int capifs_parse_options(char *options, struct capifs_sb_info *sbi)
@@ -354,19 +352,6 @@ fail:
        return -EINVAL;
 }
 
-static int capifs_statfs(struct super_block *sb, struct statfs *buf)
-{
-       buf->f_type = CAPIFS_SUPER_MAGIC;
-       buf->f_bsize = 1024;
-       buf->f_blocks = 0;
-       buf->f_bfree = 0;
-       buf->f_bavail = 0;
-       buf->f_files = 0;
-       buf->f_ffree = 0;
-       buf->f_namelen = NAME_MAX;
-       return 0;
-}
-
 static struct inode *capifs_new_inode(struct super_block *sb)
 {
        struct inode *inode = new_inode(sb);
index a354c9fd4574984f20c6ec5c4f9b73adffe8b387..a5d332064abe0a2b7e20658fe5a1f0c39c15db73 100644 (file)
@@ -281,9 +281,13 @@ struct inode_operations coda_file_inode_operations = {
 static int coda_statfs(struct super_block *sb, struct statfs *buf)
 {
        int error;
+       
+       lock_kernel();
 
        error = venus_statfs(sb, buf);
 
+       unlock_kernel();
+
        if (error) {
                /* fake something like AFS does */
                buf->f_blocks = 9000000;
index 6e166d31137b577fb3fb3dc4bf53f6569133c125..6c4c923388428142325f904037484345325804d6 100644 (file)
@@ -504,7 +504,7 @@ static struct super_operations ext3_sops = {
        write_super:    ext3_write_super,       /* BKL not held. We take it. Needed? */
        write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */
        unlockfs:       ext3_unlockfs,          /* BKL not held.  We take it */
-       statfs:         ext3_statfs,            /* BKL held */
+       statfs:         ext3_statfs,            /* BKL not held. */
        remount_fs:     ext3_remount,           /* BKL held */
 };
 
index d937b64926e3787fcf560e05155ec34aeeb5730a..45886178fda3f529bce6ef94558b46c4198bcaef 100644 (file)
@@ -98,7 +98,7 @@ vxfs_put_super(struct super_block *sbp)
  *   Zero.
  *
  * Locking:
- *   We are under bkl and @sbp->s_lock.
+ *   No locks held.
  *
  * Notes:
  *   This is everything but complete...
index 1d906d3535bb161f1e8e7372f93b0823e6df8153..b8306f5f5db9a9aa1e53f572c941e13ab774c16f 100644 (file)
@@ -134,6 +134,8 @@ static unsigned count_bitmaps(struct super_block *s)
 
 int hpfs_statfs(struct super_block *s, struct statfs *buf)
 {
+       lock_kernel();
+
        /*if (s->s_hpfs_n_free == -1) {*/
                s->s_hpfs_n_free = count_bitmaps(s);
                s->s_hpfs_n_free_dnodes = hpfs_count_one_bitmap(s, s->s_hpfs_dmap);
@@ -146,6 +148,9 @@ int hpfs_statfs(struct super_block *s, struct statfs *buf)
        buf->f_files = s->s_hpfs_dirband_size / 4;
        buf->f_ffree = s->s_hpfs_n_free_dnodes;
        buf->f_namelen = 254;
+
+       unlock_kernel();
+
        return 0;
 }
 
index e71bcbfc3caab67dc1daa75cdf2a57d191cf51d2..ad179ff4bbdcb6c44369ad58f30a5034d4b39857 100644 (file)
@@ -383,7 +383,11 @@ int
 jffs_statfs(struct super_block *sb, struct statfs *buf)
 {
        struct jffs_control *c = (struct jffs_control *) sb->u.generic_sbp;
-       struct jffs_fmcontrol *fmc = c->fmc;
+       struct jffs_fmcontrol *fmc;
+
+       lock_kernel();
+
+       fmc = c->fmc;
 
        D2(printk("jffs_statfs()\n"));
 
@@ -401,6 +405,9 @@ jffs_statfs(struct super_block *sb, struct statfs *buf)
        buf->f_ffree = buf->f_bfree;
        /* buf->f_fsid = 0; */
        buf->f_namelen = JFFS_MAX_NAME_LEN;
+
+       unlock_kernel();
+
        return 0;
 }
 
index 211f62a027a1409bd9e18e888d0cf787f29adc07..d643d954017735d49fbc6de1d233045082bd8dea 100644 (file)
@@ -474,6 +474,8 @@ nfs_statfs(struct super_block *sb, struct statfs *buf)
        struct nfs_fsinfo res;
        int error;
 
+       lock_kernel();
+
        error = server->rpc_ops->statfs(server, NFS_FH(sb->s_root->d_inode), &res);
        buf->f_type = NFS_SUPER_MAGIC;
        if (error < 0)
@@ -491,11 +493,17 @@ nfs_statfs(struct super_block *sb, struct statfs *buf)
        if (res.namelen == 0 || res.namelen > server->namelen)
                res.namelen = server->namelen;
        buf->f_namelen = res.namelen;
+
+ out:
+       unlock_kernel();
+
        return 0;
+
  out_err:
-       printk("nfs_statfs: statfs error = %d\n", -error);
+       printk(KERN_WARNING "nfs_statfs: statfs error = %d\n", -error);
        buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;
-       return 0;
+       goto out;
+
 }
 
 static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
index 1586159468a5640496b1ba92dcbaf78e376c59ff..cfedaf9df70c1d7f9e6a57dc143b992863c1982a 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -30,9 +30,7 @@ int vfs_statfs(struct super_block *sb, struct statfs *buf)
                retval = -ENOSYS;
                if (sb->s_op && sb->s_op->statfs) {
                        memset(buf, 0, sizeof(struct statfs));
-                       lock_kernel();
                        retval = sb->s_op->statfs(sb, buf);
-                       unlock_kernel();
                }
        }
        return retval;
index 407948c4ad5be23e5a135eddbb4b1777dad0f8af..f69f312c8afbec514e378cf148a3859ff353e53a 100644 (file)
@@ -281,6 +281,8 @@ unsigned long qnx4_block_map( struct inode *inode, long iblock )
 
 static int qnx4_statfs(struct super_block *sb, struct statfs *buf)
 {
+       lock_kernel();
+
        buf->f_type    = sb->s_magic;
        buf->f_bsize   = sb->s_blocksize;
        buf->f_blocks  = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size) * 8;
@@ -288,6 +290,8 @@ static int qnx4_statfs(struct super_block *sb, struct statfs *buf)
        buf->f_bavail  = buf->f_bfree;
        buf->f_namelen = QNX4_NAME_MAX;
 
+       unlock_kernel();
+
        return 0;
 }
 
index c0b5997f0b7dbf90da4c27fc0d173f243e383c19..62cccea2fe2a089143f1b24e05295e98c5477a16 100644 (file)
@@ -604,7 +604,13 @@ out_no_server:
 static int
 smb_statfs(struct super_block *sb, struct statfs *buf)
 {
-       int result = smb_proc_dskattr(sb, buf);
+       int result;
+       
+       lock_kernel();
+
+       result = smb_proc_dskattr(sb, buf);
+
+       unlock_kernel();
 
        buf->f_type = SMB_SUPER_MAGIC;
        buf->f_namelen = SMB_MAXPATHLEN;
index 1b1680ecfa030532ceba65356627917df6273372..783890fffe9b1c5d52584dfd6fbb0e2a56375103 100644 (file)
@@ -1726,6 +1726,8 @@ udf_put_super(struct super_block *sb)
 static int
 udf_statfs(struct super_block *sb, struct statfs *buf)
 {
+       lock_kernel();
+
        buf->f_type = UDF_SUPER_MAGIC;
        buf->f_bsize = sb->s_blocksize;
        buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
@@ -1738,6 +1740,8 @@ udf_statfs(struct super_block *sb, struct statfs *buf)
        /* __kernel_fsid_t f_fsid */
        buf->f_namelen = UDF_NAME_LEN;
 
+       unlock_kernel();
+
        return 0;
 }
 
index 7a19f2c4fbf37fc0465c97e7300a0f54eed95618..a046374ab085f39d07b6604b92b0d232fc519402 100644 (file)
@@ -959,6 +959,8 @@ int ufs_statfs (struct super_block * sb, struct statfs * buf)
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
 
+       lock_kernel();
+
        uspi = sb->u.ufs_sb.s_uspi;
        usb1 = ubh_get_usb_first (USPI_UBH);
        
@@ -972,6 +974,9 @@ int ufs_statfs (struct super_block * sb, struct statfs * buf)
        buf->f_files = uspi->s_ncg * uspi->s_ipg;
        buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
        buf->f_namelen = UFS_MAXNAMLEN;
+
+       unlock_kernel();
+
        return 0;
 }