hpfs: remove the BKL
authorArnd Bergmann <arnd@arndb.de>
Sat, 22 Jan 2011 19:26:12 +0000 (20:26 +0100)
committerArnd Bergmann <arnd@arndb.de>
Wed, 2 Mar 2011 21:27:36 +0000 (22:27 +0100)
This removes the BKL in hpfs in a rather awful
way, by making the code only work on uniprocessor
systems without kernel preemption, as suggested
by Andi Kleen.

The HPFS code probably has close to zero remaining
users on current kernels, all archeological uses of
the file system can probably be done with the significant
restrictions.

The hpfs_lock/hpfs_unlock functions are left in the
code, sincen Mikulas has indicated that he is still
interested in fixing it in a better way.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Andi Kleen <ak@linux.intel.com>
Cc: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: linux-fsdevel@vger.kernel.org
fs/hpfs/Kconfig
fs/hpfs/dir.c
fs/hpfs/file.c
fs/hpfs/hpfs_fn.h
fs/hpfs/inode.c
fs/hpfs/namei.c
fs/hpfs/super.c

index 63b6f56323187256685dbaf669398fd186b4ef4b..0c39dc3ef7d71473a0a951612fd54e82a63cf3a2 100644 (file)
@@ -1,7 +1,7 @@
 config HPFS_FS
        tristate "OS/2 HPFS file system support"
        depends on BLOCK
-       depends on BKL # nontrivial to fix
+       depends on BROKEN || !PREEMPT
        help
          OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
          is the file system used for organizing files on OS/2 hard disk
index d32f63a569f7f27f8958ea2b2f859e8322e337ee..b3d7c0ddb60971e2cb4217afb0bf22d4683c2988 100644 (file)
@@ -6,16 +6,15 @@
  *  directory VFS functions
  */
 
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include "hpfs_fn.h"
 
 static int hpfs_dir_release(struct inode *inode, struct file *filp)
 {
-       lock_kernel();
+       hpfs_lock(inode->i_sb);
        hpfs_del_pos(inode, &filp->f_pos);
        /*hpfs_write_if_changed(inode);*/
-       unlock_kernel();
+       hpfs_unlock(inode->i_sb);
        return 0;
 }
 
@@ -30,7 +29,7 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence)
        struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
        struct super_block *s = i->i_sb;
 
-       lock_kernel();
+       hpfs_lock(s);
 
        /*printk("dir lseek\n");*/
        if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
@@ -43,12 +42,12 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence)
        }
        mutex_unlock(&i->i_mutex);
 ok:
-       unlock_kernel();
+       hpfs_unlock(s);
        return filp->f_pos = new_off;
 fail:
        mutex_unlock(&i->i_mutex);
        /*printk("illegal lseek: %016llx\n", new_off);*/
-       unlock_kernel();
+       hpfs_unlock(s);
        return -ESPIPE;
 }
 
@@ -64,7 +63,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        int c1, c2 = 0;
        int ret = 0;
 
-       lock_kernel();
+       hpfs_lock(inode->i_sb);
 
        if (hpfs_sb(inode->i_sb)->sb_chk) {
                if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
@@ -167,7 +166,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                hpfs_brelse4(&qbh);
        }
 out:
-       unlock_kernel();
+       hpfs_unlock(inode->i_sb);
        return ret;
 }
 
@@ -197,10 +196,10 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
        struct inode *result = NULL;
        struct hpfs_inode_info *hpfs_result;
 
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        if ((err = hpfs_chk_name(name, &len))) {
                if (err == -ENAMETOOLONG) {
-                       unlock_kernel();
+                       hpfs_unlock(dir->i_sb);
                        return ERR_PTR(-ENAMETOOLONG);
                }
                goto end_add;
@@ -298,7 +297,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
 
        end:
        end_add:
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        d_add(dentry, result);
        return NULL;
 
@@ -311,7 +310,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct name
        
        /*bail:*/
 
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return ERR_PTR(-ENOENT);
 }
 
index c0340887c7ea619efceba79852159003f3286620..2dbae20450f8f7953109d781b0faff8a933354c5 100644 (file)
@@ -6,16 +6,15 @@
  *  file VFS functions
  */
 
-#include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
 #define BLOCKS(size) (((size) + 511) >> 9)
 
 static int hpfs_file_release(struct inode *inode, struct file *file)
 {
-       lock_kernel();
+       hpfs_lock(inode->i_sb);
        hpfs_write_if_changed(inode);
-       unlock_kernel();
+       hpfs_unlock(inode->i_sb);
        return 0;
 }
 
@@ -49,14 +48,14 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno)
 static void hpfs_truncate(struct inode *i)
 {
        if (IS_IMMUTABLE(i)) return /*-EPERM*/;
-       lock_kernel();
+       hpfs_lock(i->i_sb);
        hpfs_i(i)->i_n_secs = 0;
        i->i_blocks = 1 + ((i->i_size + 511) >> 9);
        hpfs_i(i)->mmu_private = i->i_size;
        hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
        hpfs_write_inode(i);
        hpfs_i(i)->i_n_secs = 0;
-       unlock_kernel();
+       hpfs_unlock(i->i_sb);
 }
 
 static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
index 1c43dbea55e8b6511cc8615d4edcd9ce3c0897e9..c15adbca07ff1a433fbf8ec9d2ac03fb34d057c5 100644 (file)
@@ -342,3 +342,25 @@ static inline time32_t gmt_to_local(struct super_block *s, time_t t)
        extern struct timezone sys_tz;
        return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
 }
+
+/*
+ * Locking:
+ *
+ * hpfs_lock() is a leftover from the big kernel lock.
+ * Right now, these functions are empty and only left
+ * for documentation purposes. The file system no longer
+ * works on SMP systems, so the lock is not needed
+ * any more.
+ *
+ * If someone is interested in making it work again, this
+ * would be the place to start by adding a per-superblock
+ * mutex and fixing all the bugs and performance issues
+ * caused by that.
+ */
+static inline void hpfs_lock(struct super_block *s)
+{
+}
+
+static inline void hpfs_unlock(struct super_block *s)
+{
+}
index 1ae35baa539e7da46105dd8f75eb019dd1ddf11e..87f1f787e7677efdd7a17a4e9a8ed2f71c397606 100644 (file)
@@ -6,7 +6,6 @@
  *  inode VFS functions
  */
 
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include "hpfs_fn.h"
 
@@ -267,7 +266,7 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error = -EINVAL;
 
-       lock_kernel();
+       hpfs_lock(inode->i_sb);
        if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root)
                goto out_unlock;
        if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
@@ -290,7 +289,7 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
        hpfs_write_inode(inode);
 
  out_unlock:
-       unlock_kernel();
+       hpfs_unlock(inode->i_sb);
        return error;
 }
 
@@ -307,8 +306,8 @@ void hpfs_evict_inode(struct inode *inode)
        truncate_inode_pages(&inode->i_data, 0);
        end_writeback(inode);
        if (!inode->i_nlink) {
-               lock_kernel();
+               hpfs_lock(inode->i_sb);
                hpfs_remove_fnode(inode->i_sb, inode->i_ino);
-               unlock_kernel();
+               hpfs_unlock(inode->i_sb);
        }
 }
index f4ad9e31ddc438a38896b19b68e051ab811336c2..d5f8c8a190233dc8cd066b065868aca822989128 100644 (file)
@@ -6,7 +6,6 @@
  *  adding & removing files & directories
  */
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
 static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
@@ -25,7 +24,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        struct hpfs_dirent dee;
        int err;
        if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        err = -ENOSPC;
        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
        if (!fnode)
@@ -103,7 +102,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        }
        d_instantiate(dentry, result);
        mutex_unlock(&hpfs_i(dir)->i_mutex);
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return 0;
 bail3:
        mutex_unlock(&hpfs_i(dir)->i_mutex);
@@ -115,7 +114,7 @@ bail1:
        brelse(bh);
        hpfs_free_sectors(dir->i_sb, fno, 1);
 bail:
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return err;
 }
 
@@ -132,7 +131,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
        int err;
        if ((err = hpfs_chk_name(name, &len)))
                return err==-ENOENT ? -EINVAL : err;
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        err = -ENOSPC;
        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
        if (!fnode)
@@ -195,7 +194,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
        }
        d_instantiate(dentry, result);
        mutex_unlock(&hpfs_i(dir)->i_mutex);
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return 0;
 
 bail2:
@@ -205,7 +204,7 @@ bail1:
        brelse(bh);
        hpfs_free_sectors(dir->i_sb, fno, 1);
 bail:
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return err;
 }
 
@@ -224,7 +223,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
        if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
        if (!new_valid_dev(rdev))
                return -EINVAL;
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        err = -ENOSPC;
        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
        if (!fnode)
@@ -274,7 +273,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
        d_instantiate(dentry, result);
        mutex_unlock(&hpfs_i(dir)->i_mutex);
        brelse(bh);
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return 0;
 bail2:
        mutex_unlock(&hpfs_i(dir)->i_mutex);
@@ -283,7 +282,7 @@ bail1:
        brelse(bh);
        hpfs_free_sectors(dir->i_sb, fno, 1);
 bail:
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return err;
 }
 
@@ -299,9 +298,9 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
        struct inode *result;
        int err;
        if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
-               unlock_kernel();
+               hpfs_unlock(dir->i_sb);
                return -EPERM;
        }
        err = -ENOSPC;
@@ -354,7 +353,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
        hpfs_write_inode_nolock(result);
        d_instantiate(dentry, result);
        mutex_unlock(&hpfs_i(dir)->i_mutex);
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return 0;
 bail2:
        mutex_unlock(&hpfs_i(dir)->i_mutex);
@@ -363,7 +362,7 @@ bail1:
        brelse(bh);
        hpfs_free_sectors(dir->i_sb, fno, 1);
 bail:
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return err;
 }
 
@@ -380,7 +379,7 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
        int rep = 0;
        int err;
 
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        hpfs_adjust_length(name, &len);
 again:
        mutex_lock(&hpfs_i(inode)->i_parent_mutex);
@@ -416,7 +415,7 @@ again:
                dentry_unhash(dentry);
                if (!d_unhashed(dentry)) {
                        dput(dentry);
-                       unlock_kernel();
+                       hpfs_unlock(dir->i_sb);
                        return -ENOSPC;
                }
                if (generic_permission(inode, MAY_WRITE, 0, NULL) ||
@@ -435,7 +434,7 @@ again:
                        if (!err)
                                goto again;
                }
-               unlock_kernel();
+               hpfs_unlock(dir->i_sb);
                return -ENOSPC;
        default:
                drop_nlink(inode);
@@ -448,7 +447,7 @@ out1:
 out:
        mutex_unlock(&hpfs_i(dir)->i_mutex);
        mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return err;
 }
 
@@ -466,7 +465,7 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
        int r;
 
        hpfs_adjust_length(name, &len);
-       lock_kernel();
+       hpfs_lock(dir->i_sb);
        mutex_lock(&hpfs_i(inode)->i_parent_mutex);
        mutex_lock(&hpfs_i(dir)->i_mutex);
        err = -ENOENT;
@@ -508,7 +507,7 @@ out1:
 out:
        mutex_unlock(&hpfs_i(dir)->i_mutex);
        mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
-       unlock_kernel();
+       hpfs_unlock(dir->i_sb);
        return err;
 }
 
@@ -521,21 +520,21 @@ static int hpfs_symlink_readpage(struct file *file, struct page *page)
        int err;
 
        err = -EIO;
-       lock_kernel();
+       hpfs_lock(i->i_sb);
        if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
                goto fail;
        err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
        brelse(bh);
        if (err)
                goto fail;
-       unlock_kernel();
+       hpfs_unlock(i->i_sb);
        SetPageUptodate(page);
        kunmap(page);
        unlock_page(page);
        return 0;
 
 fail:
-       unlock_kernel();
+       hpfs_unlock(i->i_sb);
        SetPageError(page);
        kunmap(page);
        unlock_page(page);
@@ -567,7 +566,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        err = 0;
        hpfs_adjust_length(old_name, &old_len);
 
-       lock_kernel();
+       hpfs_lock(i->i_sb);
        /* order doesn't matter, due to VFS exclusion */
        mutex_lock(&hpfs_i(i)->i_parent_mutex);
        if (new_inode)
@@ -659,7 +658,7 @@ end1:
        mutex_unlock(&hpfs_i(i)->i_parent_mutex);
        if (new_inode)
                mutex_unlock(&hpfs_i(new_inode)->i_parent_mutex);
-       unlock_kernel();
+       hpfs_unlock(i->i_sb);
        return err;
 }
 
index b30426b1fc978edf5ce15b204e4ab087a9967edb..c89b40808587925c616c4c20cc5e6ee5b6932aa0 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/statfs.h>
 #include <linux/magic.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
 
@@ -103,15 +102,11 @@ static void hpfs_put_super(struct super_block *s)
 {
        struct hpfs_sb_info *sbi = hpfs_sb(s);
 
-       lock_kernel();
-
        kfree(sbi->sb_cp_table);
        kfree(sbi->sb_bmp_dir);
        unmark_dirty(s);
        s->s_fs_info = NULL;
        kfree(sbi);
-
-       unlock_kernel();
 }
 
 unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
@@ -143,7 +138,7 @@ static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct super_block *s = dentry->d_sb;
        struct hpfs_sb_info *sbi = hpfs_sb(s);
        u64 id = huge_encode_dev(s->s_bdev->bd_dev);
-       lock_kernel();
+       hpfs_lock(s);
 
        /*if (sbi->sb_n_free == -1) {*/
                sbi->sb_n_free = count_bitmaps(s);
@@ -160,7 +155,7 @@ static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_fsid.val[1] = (u32)(id >> 32);
        buf->f_namelen = 254;
 
-       unlock_kernel();
+       hpfs_unlock(s);
 
        return 0;
 }
@@ -406,7 +401,7 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
        
        *flags |= MS_NOATIME;
        
-       lock_kernel();
+       hpfs_lock(s);
        lock_super(s);
        uid = sbi->sb_uid; gid = sbi->sb_gid;
        umask = 0777 & ~sbi->sb_mode;
@@ -441,12 +436,12 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
        replace_mount_options(s, new_opts);
 
        unlock_super(s);
-       unlock_kernel();
+       hpfs_unlock(s);
        return 0;
 
 out_err:
        unlock_super(s);
-       unlock_kernel();
+       hpfs_unlock(s);
        kfree(new_opts);
        return -EINVAL;
 }
@@ -484,13 +479,15 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
 
        int o;
 
-       lock_kernel();
+       if (num_possible_cpus() > 1) {
+               printk(KERN_ERR "HPFS is not SMP safe\n");
+               return -EINVAL;
+       }
 
        save_mount_options(s, options);
 
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi) {
-               unlock_kernel();
                return -ENOMEM;
        }
        s->s_fs_info = sbi;
@@ -677,7 +674,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
                        root->i_blocks = 5;
                hpfs_brelse4(&qbh);
        }
-       unlock_kernel();
        return 0;
 
 bail4: brelse(bh2);
@@ -689,7 +685,6 @@ bail0:
        kfree(sbi->sb_cp_table);
        s->s_fs_info = NULL;
        kfree(sbi);
-       unlock_kernel();
        return -EINVAL;
 }