Merge branch 'vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Oct 2010 17:52:01 +0000 (10:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Oct 2010 17:52:01 +0000 (10:52 -0700)
* 'vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl: (30 commits)
  BKL: remove BKL from freevxfs
  BKL: remove BKL from qnx4
  autofs4: Only declare function when CONFIG_COMPAT is defined
  autofs: Only declare function when CONFIG_COMPAT is defined
  ncpfs: Lock socket in ncpfs while setting its callbacks
  fs/locks.c: prepare for BKL removal
  BKL: Remove BKL from ncpfs
  BKL: Remove BKL from OCFS2
  BKL: Remove BKL from squashfs
  BKL: Remove BKL from jffs2
  BKL: Remove BKL from ecryptfs
  BKL: Remove BKL from afs
  BKL: Remove BKL from USB gadgetfs
  BKL: Remove BKL from autofs4
  BKL: Remove BKL from isofs
  BKL: Remove BKL from fat
  BKL: Remove BKL from ext2 filesystem
  BKL: Remove BKL from do_new_mount()
  BKL: Remove BKL from cgroup
  BKL: Remove BKL from NTFS
  ...

59 files changed:
drivers/usb/gadget/inode.c
fs/adfs/super.c
fs/affs/super.c
fs/afs/flock.c
fs/afs/super.c
fs/autofs/root.c
fs/autofs4/root.c
fs/bfs/inode.c
fs/cifs/cifsfs.c
fs/coda/inode.c
fs/ecryptfs/file.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/super.c
fs/fat/inode.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/freevxfs/vxfs_lookup.c
fs/freevxfs/vxfs_super.c
fs/gfs2/file.c
fs/hfs/super.c
fs/hpfs/super.c
fs/isofs/dir.c
fs/isofs/inode.c
fs/isofs/isofs.h
fs/isofs/namei.c
fs/isofs/rock.c
fs/jffs2/fs.c
fs/jffs2/super.c
fs/jfs/super.c
fs/locks.c
fs/namespace.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/inode.c
fs/ncpfs/ioctl.c
fs/ncpfs/ncplib_kernel.c
fs/ncpfs/ncplib_kernel.h
fs/ncpfs/ncpsign_kernel.c
fs/ncpfs/sock.c
fs/nfs/delegation.c
fs/nfs/nfs4state.c
fs/nfsd/nfs4state.c
fs/nilfs2/ioctl.c
fs/nilfs2/super.c
fs/ntfs/super.c
fs/ocfs2/stack_user.c
fs/ocfs2/super.c
fs/qnx4/dir.c
fs/qnx4/inode.c
fs/qnx4/namei.c
fs/smbfs/inode.c
fs/squashfs/super.c
fs/udf/super.c
fs/ufs/super.c
include/linux/fs.h
include/linux/ncp_fs.h
include/linux/ncp_fs_sb.h
kernel/cgroup.c

index fc35406fc80c3e72562bbb96068f99e462663842..3f1d771c8be584c28c54d356e8238de954626c32 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 
 #include <linux/device.h>
 #include <linux/moduleparam.h>
index 4a3af7075c1d09058347ef532edc8c3105a9f9d5..d9803f73236f543fca9764cbe453414f6fe22286 100644 (file)
@@ -352,11 +352,15 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
        struct adfs_sb_info *asb;
        struct inode *root;
 
+       lock_kernel();
+
        sb->s_flags |= MS_NODIRATIME;
 
        asb = kzalloc(sizeof(*asb), GFP_KERNEL);
-       if (!asb)
+       if (!asb) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        sb->s_fs_info = asb;
 
        /* set default options */
@@ -474,6 +478,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
                goto error;
        } else
                sb->s_root->d_op = &adfs_dentry_operations;
+       unlock_kernel();
        return 0;
 
 error_free_bh:
@@ -481,6 +486,7 @@ error_free_bh:
 error:
        sb->s_fs_info = NULL;
        kfree(asb);
+       unlock_kernel();
        return -EINVAL;
 }
 
index 9581ea94d5a146e95ba9533d1a7ac3aba2b83804..fa4fbe1e238a344bbe35207e635461f07ac81691 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/parser.h>
 #include <linux/magic.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include "affs.h"
 
@@ -46,8 +45,6 @@ affs_put_super(struct super_block *sb)
        struct affs_sb_info *sbi = AFFS_SB(sb);
        pr_debug("AFFS: put_super()\n");
 
-       lock_kernel();
-
        if (!(sb->s_flags & MS_RDONLY) && sb->s_dirt)
                affs_commit_super(sb, 1, 1);
 
@@ -56,8 +53,6 @@ affs_put_super(struct super_block *sb)
        affs_brelse(sbi->s_root_bh);
        kfree(sbi);
        sb->s_fs_info = NULL;
-
-       unlock_kernel();
 }
 
 static void
@@ -302,6 +297,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
        sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
        if (!sbi)
                return -ENOMEM;
+
        sb->s_fs_info = sbi;
        mutex_init(&sbi->s_bmlock);
        spin_lock_init(&sbi->symlink_lock);
@@ -527,7 +523,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
                kfree(new_opts);
                return -EINVAL;
        }
-       lock_kernel();
+
        replace_mount_options(sb, new_opts);
 
        sbi->s_flags = mount_flags;
@@ -543,17 +539,15 @@ affs_remount(struct super_block *sb, int *flags, char *data)
        memcpy(sbi->s_volume, volume, 32);
        spin_unlock(&sbi->symlink_lock);
 
-       if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
-               unlock_kernel();
+       if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
-       }
+
        if (*flags & MS_RDONLY) {
                affs_write_super(sb);
                affs_free_bitmap(sb);
        } else
                res = affs_init_bitmap(sb, flags);
 
-       unlock_kernel();
        return res;
 }
 
index 0931bc1325ebd26fe38b9b6cd515d82d6d3fc618..757d664575dde8eff7659f471fce43692e992f06 100644 (file)
@@ -9,7 +9,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/smp_lock.h>
 #include "internal.h"
 
 #define AFS_LOCK_GRANTED       0
@@ -274,7 +273,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)
 
        type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE;
 
-       lock_kernel();
+       lock_flocks();
 
        /* make sure we've got a callback on this file and that our view of the
         * data version is up to date */
@@ -421,7 +420,7 @@ given_lock:
        afs_vnode_fetch_status(vnode, NULL, key);
 
 error:
-       unlock_kernel();
+       unlock_flocks();
        _leave(" = %d", ret);
        return ret;
 
index 77e1e5a61154c6796d80d709ed31722017d90e18..eacf76d98ae02345d00d62f22f5ab4893a0452e6 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mount.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/parser.h>
@@ -453,12 +452,8 @@ static void afs_put_super(struct super_block *sb)
 
        _enter("");
 
-       lock_kernel();
-
        afs_put_volume(as->volume);
 
-       unlock_kernel();
-
        _leave("");
 }
 
index 11b1ea786d006472cc93cd0f33e6f787445ef569..0c4ca81aeaebb43e5d34b53626d1b886507cff86 100644 (file)
@@ -27,7 +27,9 @@ static int autofs_root_unlink(struct inode *,struct dentry *);
 static int autofs_root_rmdir(struct inode *,struct dentry *);
 static int autofs_root_mkdir(struct inode *,struct dentry *,int);
 static long autofs_root_ioctl(struct file *,unsigned int,unsigned long);
+#ifdef CONFIG_COMPAT
 static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);
+#endif
 
 const struct file_operations autofs_root_operations = {
        .llseek         = generic_file_llseek,
index cb1bd38dc08cb10c47650e1e08c2a8fe13730ab2..d5c1401f00310979b117f9eaaecc0e026fd11c93 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/param.h>
 #include <linux/time.h>
 #include <linux/compat.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
 
 #include "autofs_i.h"
 
@@ -28,7 +28,9 @@ static int autofs4_dir_unlink(struct inode *,struct dentry *);
 static int autofs4_dir_rmdir(struct inode *,struct dentry *);
 static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
 static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long);
+#ifdef CONFIG_COMPAT
 static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
+#endif
 static int autofs4_dir_open(struct inode *inode, struct file *file);
 static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
 static void *autofs4_follow_link(struct dentry *, struct nameidata *);
@@ -978,15 +980,17 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp,
        }
 }
 
+static DEFINE_MUTEX(autofs4_ioctl_mutex);
+
 static long autofs4_root_ioctl(struct file *filp,
                               unsigned int cmd, unsigned long arg)
 {
        long ret;
        struct inode *inode = filp->f_dentry->d_inode;
 
-       lock_kernel();
+       mutex_lock(&autofs4_ioctl_mutex);
        ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
-       unlock_kernel();
+       mutex_unlock(&autofs4_ioctl_mutex);
 
        return ret;
 }
@@ -998,13 +1002,13 @@ static long autofs4_root_compat_ioctl(struct file *filp,
        struct inode *inode = filp->f_path.dentry->d_inode;
        int ret;
 
-       lock_kernel();
+       mutex_lock(&autofs4_ioctl_mutex);
        if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
                ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
        else
                ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
                        (unsigned long)compat_ptr(arg));
-       unlock_kernel();
+       mutex_unlock(&autofs4_ioctl_mutex);
 
        return ret;
 }
index c4daf0f5fc021e9b98fa2521b96ee28ea67c9b4c..883e77acd5a8cd8e0c3598cb62e5993e82725d97 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
 #include <linux/writeback.h>
@@ -215,14 +214,10 @@ static void bfs_put_super(struct super_block *s)
        if (!info)
                return;
 
-       lock_kernel();
-
        mutex_destroy(&info->bfs_lock);
        kfree(info->si_imap);
        kfree(info);
        s->s_fs_info = NULL;
-
-       unlock_kernel();
 }
 
 static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
index b7431afdd76d57fb17ef70385428dd5c132020f2..50208c15309a7321b15e0d0adc417c34e1994143 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
-#include <linux/smp_lock.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #define DECLARE_GLOBALS_HERE
@@ -200,8 +199,6 @@ cifs_put_super(struct super_block *sb)
                return;
        }
 
-       lock_kernel();
-
        rc = cifs_umount(sb, cifs_sb);
        if (rc)
                cERROR(1, "cifs_umount failed with return code %d", rc);
@@ -215,8 +212,6 @@ cifs_put_super(struct super_block *sb)
        unload_nls(cifs_sb->local_nls);
        bdi_destroy(&cifs_sb->bdi);
        kfree(cifs_sb);
-
-       unlock_kernel();
 }
 
 static int
@@ -514,7 +509,9 @@ cifs_get_sb(struct file_system_type *fs_type,
            int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
        int rc;
-       struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
+       struct super_block *sb;
+
+       sb = sget(fs_type, NULL, set_anon_super, NULL);
 
        cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
 
@@ -565,8 +562,8 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
 
 static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
 {
-       /* note that this is called by vfs setlease with the BKL held
-          although I doubt that BKL is needed here in cifs */
+       /* note that this is called by vfs setlease with lock_flocks held
+          to protect *lease from going away */
        struct inode *inode = file->f_path.dentry->d_inode;
 
        if (!(S_ISREG(inode->i_mode)))
index 6526e6f21ecfb22f23a5b19efb5b9d82287cef49..bfe8179b1295e76ea4433fce9d2533e240eed840 100644 (file)
@@ -148,6 +148,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
        int error;
        int idx;
 
+       lock_kernel();
+
        idx = get_device_index((struct coda_mount_data *) data);
 
        /* Ignore errors in data, for backward compatibility */
@@ -159,11 +161,13 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
        vc = &coda_comms[idx];
        if (!vc->vc_inuse) {
                printk("coda_read_super: No pseudo device\n");
+               unlock_kernel();
                return -EINVAL;
        }
 
         if ( vc->vc_sb ) {
                printk("coda_read_super: Device already mounted\n");
+               unlock_kernel();
                return -EBUSY;
        }
 
@@ -202,7 +206,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_root = d_alloc_root(root);
        if (!sb->s_root)
                goto error;
-        return 0;
+       unlock_kernel();
+       return 0;
 
  error:
        bdi_destroy(&vc->bdi);
@@ -212,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
        if (vc)
                vc->vc_sb = NULL;
 
+       unlock_kernel();
        return -EINVAL;
 }
 
index 622c95140802c33d18713e16eb29b7f23c498104..2b9a644b7583e2019a59c110bc84e2c3aaf1fb02 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/security.h>
 #include <linux/compat.h>
 #include <linux/fs_stack.h>
-#include <linux/smp_lock.h>
 #include "ecryptfs_kernel.h"
 
 /**
@@ -284,11 +283,9 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
        int rc = 0;
        struct file *lower_file = NULL;
 
-       lock_kernel();
        lower_file = ecryptfs_file_to_lower(file);
        if (lower_file->f_op && lower_file->f_op->fasync)
                rc = lower_file->f_op->fasync(fd, lower_file, flag);
-       unlock_kernel();
        return rc;
 }
 
index 1ec602673ea8d37c3ddd72c7016ca1783ca8cf74..85df87d0f7b70a01dde7b39826f6d9abbeb08799 100644 (file)
@@ -747,15 +747,16 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
        __le32 features;
        int err;
 
+       err = -ENOMEM;
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi)
-               return -ENOMEM;
+               goto failed_unlock;
 
        sbi->s_blockgroup_lock =
                kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
        if (!sbi->s_blockgroup_lock) {
                kfree(sbi);
-               return -ENOMEM;
+               goto failed_unlock;
        }
        sb->s_fs_info = sbi;
        sbi->s_sb_block = sb_block;
@@ -1107,6 +1108,7 @@ failed_sbi:
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
+failed_unlock:
        return ret;
 }
 
index a367dd04428070cde6fbf7c70bbd64754ce498db..37776800910670e2a675e4fd11378f3d8eb35446 100644 (file)
@@ -411,9 +411,6 @@ static void ext3_put_super (struct super_block * sb)
        int i, err;
 
        dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
-
-       lock_kernel();
-
        ext3_xattr_put_super(sb);
        err = journal_destroy(sbi->s_journal);
        sbi->s_journal = NULL;
@@ -462,8 +459,6 @@ static void ext3_put_super (struct super_block * sb)
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
-
-       unlock_kernel();
 }
 
 static struct kmem_cache *ext3_inode_cachep;
@@ -1627,8 +1622,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_resgid = EXT3_DEF_RESGID;
        sbi->s_sb_block = sb_block;
 
-       unlock_kernel();
-
        blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
        if (!blocksize) {
                ext3_msg(sb, KERN_ERR, "error: unable to set blocksize");
@@ -2025,7 +2018,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
                "writeback");
 
-       lock_kernel();
        return 0;
 
 cantfind_ext3:
@@ -2055,7 +2047,6 @@ out_fail:
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
-       lock_kernel();
        return ret;
 }
 
@@ -2538,8 +2529,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
        int i;
 #endif
 
-       lock_kernel();
-
        /* Store the original options */
        lock_super(sb);
        old_sb_flags = sb->s_flags;
@@ -2648,7 +2637,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
                        kfree(old_opts.s_qf_names[i]);
 #endif
        unlock_super(sb);
-       unlock_kernel();
 
        if (enable_quota)
                dquot_resume(sb, -1);
@@ -2669,7 +2657,6 @@ restore_opts:
        }
 #endif
        unlock_super(sb);
-       unlock_kernel();
        return err;
 }
 
index 7f47c366bf1576fbbdf3cbe6441fc04afd9ca198..8ecc1e590303841b0c5f13d07568082230acdf4d 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/parser.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/exportfs.h>
 #include <linux/vfs.h>
@@ -708,7 +707,6 @@ static void ext4_put_super(struct super_block *sb)
        destroy_workqueue(sbi->dio_unwritten_wq);
 
        lock_super(sb);
-       lock_kernel();
        if (sb->s_dirt)
                ext4_commit_super(sb, 1);
 
@@ -775,7 +773,6 @@ static void ext4_put_super(struct super_block *sb)
         * Now that we are completely done shutting down the
         * superblock, we need to actually destroy the kobject.
         */
-       unlock_kernel();
        unlock_super(sb);
        kobject_put(&sbi->s_kobj);
        wait_for_completion(&sbi->s_kobj_unregister);
@@ -2588,8 +2585,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                sbi->s_sectors_written_start =
                        part_stat_read(sb->s_bdev->bd_part, sectors[1]);
 
-       unlock_kernel();
-
        /* Cleanup superblock name */
        for (cp = sb->s_id; (cp = strchr(cp, '/'));)
                *cp = '!';
@@ -3164,7 +3159,6 @@ no_journal:
        if (es->s_error_count)
                mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */
 
-       lock_kernel();
        kfree(orig_data);
        return 0;
 
@@ -3211,7 +3205,6 @@ out_fail:
        sb->s_fs_info = NULL;
        kfree(sbi->s_blockgroup_lock);
        kfree(sbi);
-       lock_kernel();
 out_free_orig:
        kfree(orig_data);
        return ret;
@@ -3720,8 +3713,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 #endif
        char *orig_data = kstrdup(data, GFP_KERNEL);
 
-       lock_kernel();
-
        /* Store the original options */
        lock_super(sb);
        old_sb_flags = sb->s_flags;
@@ -3856,7 +3847,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                        kfree(old_opts.s_qf_names[i]);
 #endif
        unlock_super(sb);
-       unlock_kernel();
        if (enable_quota)
                dquot_resume(sb, -1);
 
@@ -3882,7 +3872,6 @@ restore_opts:
        }
 #endif
        unlock_super(sb);
-       unlock_kernel();
        kfree(orig_data);
        return err;
 }
index 830058057d333d547effdbc969d8a9d89464854f..ad6998a92c30d4a90336bcb295743ffb9547ec3f 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/seq_file.h>
 #include <linux/pagemap.h>
 #include <linux/mpage.h>
@@ -489,8 +488,6 @@ static void fat_put_super(struct super_block *sb)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
 
-       lock_kernel();
-
        if (sb->s_dirt)
                fat_write_super(sb);
 
@@ -504,8 +501,6 @@ static void fat_put_super(struct super_block *sb)
 
        sb->s_fs_info = NULL;
        kfree(sbi);
-
-       unlock_kernel();
 }
 
 static struct kmem_cache *fat_inode_cachep;
index bbc94ae4fd77150203435058b79e46a03bfb40bc..bbca5c186ae7654d69025a2cbb214c1fc1f96a3d 100644 (file)
@@ -662,12 +662,16 @@ static int msdos_fill_super(struct super_block *sb, void *data, int silent)
 {
        int res;
 
+       lock_super(sb);
        res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0);
-       if (res)
+       if (res) {
+               unlock_super(sb);
                return res;
+       }
 
        sb->s_flags |= MS_NOATIME;
        sb->s_root->d_op = &msdos_dentry_operations;
+       unlock_super(sb);
        return 0;
 }
 
index 6fcc7e71fbaaf0c8f1d21b3cf50fab86d67f50ee..6f0f6c9a0152263d61081e436641fb9a0300db6c 100644 (file)
@@ -1055,15 +1055,19 @@ static int vfat_fill_super(struct super_block *sb, void *data, int silent)
 {
        int res;
 
+       lock_super(sb);
        res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1);
-       if (res)
+       if (res) {
+               unlock_super(sb);
                return res;
+       }
 
        if (MSDOS_SB(sb)->options.name_check != 's')
                sb->s_root->d_op = &vfat_ci_dentry_ops;
        else
                sb->s_root->d_op = &vfat_dentry_ops;
 
+       unlock_super(sb);
        return 0;
 }
 
index 0ec7bb2c95c6afd035a9484b0a39347f9f8f61c1..6c5131d592f0ae2fbeba8b4c2d227c603bb544c3 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/highmem.h>
 #include <linux/kernel.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 
 #include "vxfs.h"
 #include "vxfs_dir.h"
@@ -212,16 +211,12 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd)
        if (dp->d_name.len > VXFS_NAMELEN)
                return ERR_PTR(-ENAMETOOLONG);
                                 
-       lock_kernel();
        ino = vxfs_inode_by_name(dip, dp);
        if (ino) {
                ip = vxfs_iget(dip->i_sb, ino);
-               if (IS_ERR(ip)) {
-                       unlock_kernel();
+               if (IS_ERR(ip))
                        return ERR_CAST(ip);
-               }
        }
-       unlock_kernel();
        d_add(dp, ip);
        return NULL;
 }
@@ -248,8 +243,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
        u_long                  page, npages, block, pblocks, nblocks, offset;
        loff_t                  pos;
 
-       lock_kernel();
-
        switch ((long)fp->f_pos) {
        case 0:
                if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 0)
@@ -265,10 +258,8 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
 
        pos = fp->f_pos - 2;
        
-       if (pos > VXFS_DIRROUND(ip->i_size)) {
-               unlock_kernel();
+       if (pos > VXFS_DIRROUND(ip->i_size))
                return 0;
-       }
 
        npages = dir_pages(ip);
        nblocks = dir_blocks(ip);
@@ -327,6 +318,5 @@ 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 dc0c041e85cbcd5c14b04c0e5b09eda611605aef..71b0148b878415795d984528c02679d45ee218e4 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/stat.h>
 #include <linux/vfs.h>
 #include <linux/mount.h>
@@ -81,16 +80,12 @@ vxfs_put_super(struct super_block *sbp)
 {
        struct vxfs_sb_info     *infp = VXFS_SBI(sbp);
 
-       lock_kernel();
-
        vxfs_put_fake_inode(infp->vsi_fship);
        vxfs_put_fake_inode(infp->vsi_ilist);
        vxfs_put_fake_inode(infp->vsi_stilist);
 
        brelse(infp->vsi_bp);
        kfree(infp);
-
-       unlock_kernel();
 }
 
 /**
@@ -148,7 +143,7 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data)
  *   The superblock on success, else %NULL.
  *
  * Locking:
- *   We are under the bkl and @sbp->s_lock.
+ *   We are under @sbp->s_lock.
  */
 static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 {
index 237ee6a940df23ab0720ed99252657611d0be7ec..a51079bd4af1b7f0f2bf5c57675a1b883f762e9e 100644 (file)
@@ -622,6 +622,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
  * cluster; until we do, disable leases (by just returning -EINVAL),
  * unless the administrator has requested purely local locking.
  *
+ * Locking: called under lock_flocks
+ *
  * Returns: errno
  */
 
index 34235d4bf08bb5921768b1105b37bfff4277cd7a..33254160f650e22da90ff1b0b153df229c81f0df 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/parser.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/vfs.h>
 
 #include "hfs_fs.h"
@@ -79,15 +78,11 @@ static int hfs_sync_fs(struct super_block *sb, int wait)
  */
 static void hfs_put_super(struct super_block *sb)
 {
-       lock_kernel();
-
        if (sb->s_dirt)
                hfs_write_super(sb);
        hfs_mdb_close(sb);
        /* release the MDB's resources */
        hfs_mdb_put(sb);
-
-       unlock_kernel();
 }
 
 /*
@@ -385,6 +380,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
        sbi = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);
        if (!sbi)
                return -ENOMEM;
+
        sb->s_fs_info = sbi;
        INIT_HLIST_HEAD(&sbi->rsrc_inodes);
 
index 2607010be2fe5019b9700926d57c0f272be79f17..c969a1aa163a7cd3fb0b48094edf1ac90f63816c 100644 (file)
@@ -477,11 +477,15 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
 
        int o;
 
+       lock_kernel();
+
        save_mount_options(s, options);
 
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
        s->s_fs_info = sbi;
 
        sbi->sb_bmp_dir = NULL;
@@ -666,6 +670,7 @@ 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);
@@ -677,6 +682,7 @@ bail0:
        kfree(sbi->sb_cp_table);
        s->s_fs_info = NULL;
        kfree(sbi);
+       unlock_kernel();
        return -EINVAL;
 }
 
index e0aca9a0ac68b9f5a75764a570df2c3d0bd81a72..0542b6eedf8060b64103cb86abb9643df499a2cf 100644 (file)
@@ -10,7 +10,6 @@
  *
  *  isofs directory handling functions
  */
-#include <linux/smp_lock.h>
 #include <linux/gfp.h>
 #include "isofs.h"
 
@@ -255,18 +254,19 @@ static int isofs_readdir(struct file *filp,
        char *tmpname;
        struct iso_directory_record *tmpde;
        struct inode *inode = filp->f_path.dentry->d_inode;
+       struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb);
 
        tmpname = (char *)__get_free_page(GFP_KERNEL);
        if (tmpname == NULL)
                return -ENOMEM;
 
-       lock_kernel();
+       mutex_lock(&sbi->s_mutex);
        tmpde = (struct iso_directory_record *) (tmpname+1024);
 
        result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde);
 
        free_page((unsigned long) tmpname);
-       unlock_kernel();
+       mutex_unlock(&sbi->s_mutex);
        return result;
 }
 
index 5a44811b5027ab73958ec6d87757a44dee5ff911..09ff41a752a092431068b991b9e323bbe5276fbd 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/nls.h>
 #include <linux/ctype.h>
-#include <linux/smp_lock.h>
 #include <linux/statfs.h>
 #include <linux/cdrom.h>
 #include <linux/parser.h>
@@ -44,11 +43,7 @@ static void isofs_put_super(struct super_block *sb)
        struct isofs_sb_info *sbi = ISOFS_SB(sb);
 
 #ifdef CONFIG_JOLIET
-       lock_kernel();
-
        unload_nls(sbi->s_nls_iocharset);
-
-       unlock_kernel();
 #endif
 
        kfree(sbi);
@@ -823,6 +818,7 @@ root_found:
        sbi->s_utf8 = opt.utf8;
        sbi->s_nocompress = opt.nocompress;
        sbi->s_overriderockperm = opt.overriderockperm;
+       mutex_init(&sbi->s_mutex);
        /*
         * It would be incredibly stupid to allow people to mark every file
         * on the disk as suid, so we merely allow them to set the default
@@ -977,8 +973,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
        int section, rv, error;
        struct iso_inode_info *ei = ISOFS_I(inode);
 
-       lock_kernel();
-
        error = -EIO;
        rv = 0;
        if (iblock < 0 || iblock != iblock_s) {
@@ -1054,7 +1048,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
 
        error = 0;
 abort:
-       unlock_kernel();
        return rv != 0 ? rv : error;
 }
 
index 7d33de84f52adec9b647bfc23f883f811f939ca9..2882dc089f87ce60c92e534d5cc6219030e4103f 100644 (file)
@@ -55,6 +55,7 @@ struct isofs_sb_info {
        gid_t s_gid;
        uid_t s_uid;
        struct nls_table *s_nls_iocharset; /* Native language support table */
+       struct mutex s_mutex; /* replaces BKL, please remove if possible */
 };
 
 #define ISOFS_INVALID_MODE ((mode_t) -1)
index ab438beb867cca718bcedf66e0355f09168b8669..0d23abfd428017697c6932d9d5c2f2b003ae43ef 100644 (file)
@@ -6,7 +6,6 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <linux/smp_lock.h>
 #include <linux/gfp.h>
 #include "isofs.h"
 
@@ -168,6 +167,7 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
        int found;
        unsigned long uninitialized_var(block);
        unsigned long uninitialized_var(offset);
+       struct isofs_sb_info *sbi = ISOFS_SB(dir->i_sb);
        struct inode *inode;
        struct page *page;
 
@@ -177,7 +177,7 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
        if (!page)
                return ERR_PTR(-ENOMEM);
 
-       lock_kernel();
+       mutex_lock(&sbi->s_mutex);
        found = isofs_find_entry(dir, dentry,
                                &block, &offset,
                                page_address(page),
@@ -188,10 +188,10 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
        if (found) {
                inode = isofs_iget(dir->i_sb, block, offset);
                if (IS_ERR(inode)) {
-                       unlock_kernel();
+                       mutex_unlock(&sbi->s_mutex);
                        return ERR_CAST(inode);
                }
        }
-       unlock_kernel();
+       mutex_unlock(&sbi->s_mutex);
        return d_splice_alias(inode, dentry);
 }
index 96a685c550fde27420a1e8d2e697ef5c4bc72705..f9cd04db6eab9509958a375a65f3b4d8eb0d6d90 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/slab.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 
 #include "isofs.h"
 #include "rock.h"
@@ -661,6 +660,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
 {
        struct inode *inode = page->mapping->host;
        struct iso_inode_info *ei = ISOFS_I(inode);
+       struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb);
        char *link = kmap(page);
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
        struct buffer_head *bh;
@@ -673,12 +673,12 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
        struct rock_state rs;
        int ret;
 
-       if (!ISOFS_SB(inode->i_sb)->s_rock)
+       if (!sbi->s_rock)
                goto error;
 
        init_rock_state(&rs, inode);
        block = ei->i_iget5_block;
-       lock_kernel();
+       mutex_lock(&sbi->s_mutex);
        bh = sb_bread(inode->i_sb, block);
        if (!bh)
                goto out_noread;
@@ -748,7 +748,7 @@ repeat:
                goto fail;
        brelse(bh);
        *rpnt = '\0';
-       unlock_kernel();
+       mutex_unlock(&sbi->s_mutex);
        SetPageUptodate(page);
        kunmap(page);
        unlock_page(page);
@@ -765,7 +765,7 @@ out_bad_span:
        printk("symlink spans iso9660 blocks\n");
 fail:
        brelse(bh);
-       unlock_kernel();
+       mutex_unlock(&sbi->s_mutex);
 error:
        SetPageError(page);
        kunmap(page);
index 6b2964a19850936dce9648c28669c40f4a1928c8..d9beb06e6fcaf55c7fdc2f46367ce2f280bff859 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/vmalloc.h>
 #include <linux/vfs.h>
 #include <linux/crc32.h>
-#include <linux/smp_lock.h>
 #include "nodelist.h"
 
 static int jffs2_flash_setup(struct jffs2_sb_info *c);
@@ -391,7 +390,6 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
           This also catches the case where it was stopped and this
           is just a remount to restart it.
           Flush the writebuffer, if neccecary, else we loose it */
-       lock_kernel();
        if (!(sb->s_flags & MS_RDONLY)) {
                jffs2_stop_garbage_collect_thread(c);
                mutex_lock(&c->alloc_sem);
@@ -403,8 +401,6 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
                jffs2_start_garbage_collect_thread(c);
 
        *flags |= MS_NOATIME;
-
-       unlock_kernel();
        return 0;
 }
 
index 662bba099501277caff6bd0b0c54abe1aaddf8cf..d1ae5dfc22b97cd04c29fa9c901ac88ba31f0670 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/fs.h>
@@ -146,6 +145,7 @@ static const struct super_operations jffs2_super_operations =
 static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct jffs2_sb_info *c;
+       int ret;
 
        D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():"
                  " New superblock for device %d (\"%s\")\n",
@@ -175,7 +175,8 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
        sb->s_flags |= MS_POSIXACL;
 #endif
-       return jffs2_do_fill_super(sb, data, silent);
+       ret = jffs2_do_fill_super(sb, data, silent);
+       return ret;
 }
 
 static int jffs2_get_sb(struct file_system_type *fs_type,
@@ -192,8 +193,6 @@ static void jffs2_put_super (struct super_block *sb)
 
        D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
 
-       lock_kernel();
-
        if (sb->s_dirt)
                jffs2_write_super(sb);
 
@@ -215,8 +214,6 @@ static void jffs2_put_super (struct super_block *sb)
        if (c->mtd->sync)
                c->mtd->sync(c->mtd);
 
-       unlock_kernel();
-
        D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
 }
 
index ec8c3e4baca3f78d666c33982d7040afcf73628b..68eee2bf629ee4ba6d5d6ad326012aca03d09c4f 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/seq_file.h>
-#include <linux/smp_lock.h>
 
 #include "jfs_incore.h"
 #include "jfs_filsys.h"
@@ -176,8 +175,6 @@ static void jfs_put_super(struct super_block *sb)
 
        dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
 
-       lock_kernel();
-
        rc = jfs_umount(sb);
        if (rc)
                jfs_err("jfs_umount failed with return code %d", rc);
@@ -188,8 +185,6 @@ static void jfs_put_super(struct super_block *sb)
        iput(sbi->direct_inode);
 
        kfree(sbi);
-
-       unlock_kernel();
 }
 
 enum {
@@ -369,19 +364,16 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
        if (!parse_options(data, sb, &newLVSize, &flag)) {
                return -EINVAL;
        }
-       lock_kernel();
+
        if (newLVSize) {
                if (sb->s_flags & MS_RDONLY) {
                        printk(KERN_ERR
                  "JFS: resize requires volume to be mounted read-write\n");
-                       unlock_kernel();
                        return -EROFS;
                }
                rc = jfs_extendfs(sb, newLVSize, 0);
-               if (rc) {
-                       unlock_kernel();
+               if (rc)
                        return rc;
-               }
        }
 
        if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
@@ -397,36 +389,30 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
                /* mark the fs r/w for quota activity */
                sb->s_flags &= ~MS_RDONLY;
 
-               unlock_kernel();
                dquot_resume(sb, -1);
                return ret;
        }
        if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
                rc = dquot_suspend(sb, -1);
                if (rc < 0) {
-                       unlock_kernel();
                        return rc;
                }
                rc = jfs_umount_rw(sb);
                JFS_SBI(sb)->flag = flag;
-               unlock_kernel();
                return rc;
        }
        if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
                if (!(sb->s_flags & MS_RDONLY)) {
                        rc = jfs_umount_rw(sb);
-                       if (rc) {
-                               unlock_kernel();
+                       if (rc)
                                return rc;
-                       }
+
                        JFS_SBI(sb)->flag = flag;
                        ret = jfs_mount_rw(sb, 1);
-                       unlock_kernel();
                        return ret;
                }
        JFS_SBI(sb)->flag = flag;
 
-       unlock_kernel();
        return 0;
 }
 
@@ -446,6 +432,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
        if (!sbi)
                return -ENOMEM;
+
        sb->s_fs_info = sbi;
        sbi->sb = sb;
        sbi->uid = sbi->gid = sbi->umask = -1;
index ab24d49fc04844e93bbedb1cd7c61083cb74e2b8..8b2b6ad56a090b0bd1cb58ef839fd9ecedf536cf 100644 (file)
@@ -143,6 +143,22 @@ int lease_break_time = 45;
 static LIST_HEAD(file_lock_list);
 static LIST_HEAD(blocked_list);
 
+/*
+ * Protects the two list heads above, plus the inode->i_flock list
+ * FIXME: should use a spinlock, once lockd and ceph are ready.
+ */
+void lock_flocks(void)
+{
+       lock_kernel();
+}
+EXPORT_SYMBOL_GPL(lock_flocks);
+
+void unlock_flocks(void)
+{
+       unlock_kernel();
+}
+EXPORT_SYMBOL_GPL(unlock_flocks);
+
 static struct kmem_cache *filelock_cache __read_mostly;
 
 /* Allocate an empty lock structure. */
@@ -511,9 +527,9 @@ static void __locks_delete_block(struct file_lock *waiter)
  */
 static void locks_delete_block(struct file_lock *waiter)
 {
-       lock_kernel();
+       lock_flocks();
        __locks_delete_block(waiter);
-       unlock_kernel();
+       unlock_flocks();
 }
 
 /* Insert waiter into blocker's block list.
@@ -644,7 +660,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
 {
        struct file_lock *cfl;
 
-       lock_kernel();
+       lock_flocks();
        for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
                if (!IS_POSIX(cfl))
                        continue;
@@ -657,7 +673,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
                        fl->fl_pid = pid_vnr(cfl->fl_nspid);
        } else
                fl->fl_type = F_UNLCK;
-       unlock_kernel();
+       unlock_flocks();
        return;
 }
 EXPORT_SYMBOL(posix_test_lock);
@@ -730,18 +746,16 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
        int error = 0;
        int found = 0;
 
-       lock_kernel();
-       if (request->fl_flags & FL_ACCESS)
-               goto find_conflict;
-
-       if (request->fl_type != F_UNLCK) {
-               error = -ENOMEM;
+       if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) {
                new_fl = locks_alloc_lock();
-               if (new_fl == NULL)
-                       goto out;
-               error = 0;
+               if (!new_fl)
+                       return -ENOMEM;
        }
 
+       lock_flocks();
+       if (request->fl_flags & FL_ACCESS)
+               goto find_conflict;
+
        for_each_lock(inode, before) {
                struct file_lock *fl = *before;
                if (IS_POSIX(fl))
@@ -767,8 +781,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
         * If a higher-priority process was blocked on the old file lock,
         * give it the opportunity to lock the file.
         */
-       if (found)
+       if (found) {
+               unlock_flocks();
                cond_resched();
+               lock_flocks();
+       }
 
 find_conflict:
        for_each_lock(inode, before) {
@@ -794,7 +811,7 @@ find_conflict:
        error = 0;
 
 out:
-       unlock_kernel();
+       unlock_flocks();
        if (new_fl)
                locks_free_lock(new_fl);
        return error;
@@ -823,7 +840,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
                new_fl2 = locks_alloc_lock();
        }
 
-       lock_kernel();
+       lock_flocks();
        if (request->fl_type != F_UNLCK) {
                for_each_lock(inode, before) {
                        fl = *before;
@@ -991,7 +1008,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
                locks_wake_up_blocks(left);
        }
  out:
-       unlock_kernel();
+       unlock_flocks();
        /*
         * Free any unused locks.
         */
@@ -1066,14 +1083,14 @@ int locks_mandatory_locked(struct inode *inode)
        /*
         * Search the lock list for this inode for any POSIX locks.
         */
-       lock_kernel();
+       lock_flocks();
        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                if (!IS_POSIX(fl))
                        continue;
                if (fl->fl_owner != owner)
                        break;
        }
-       unlock_kernel();
+       unlock_flocks();
        return fl ? -EAGAIN : 0;
 }
 
@@ -1186,7 +1203,7 @@ int __break_lease(struct inode *inode, unsigned int mode)
 
        new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
 
-       lock_kernel();
+       lock_flocks();
 
        time_out_leases(inode);
 
@@ -1247,8 +1264,10 @@ restart:
                        break_time++;
        }
        locks_insert_block(flock, new_fl);
+       unlock_flocks();
        error = wait_event_interruptible_timeout(new_fl->fl_wait,
                                                !new_fl->fl_next, break_time);
+       lock_flocks();
        __locks_delete_block(new_fl);
        if (error >= 0) {
                if (error == 0)
@@ -1263,7 +1282,7 @@ restart:
        }
 
 out:
-       unlock_kernel();
+       unlock_flocks();
        if (!IS_ERR(new_fl))
                locks_free_lock(new_fl);
        return error;
@@ -1319,7 +1338,7 @@ int fcntl_getlease(struct file *filp)
        struct file_lock *fl;
        int type = F_UNLCK;
 
-       lock_kernel();
+       lock_flocks();
        time_out_leases(filp->f_path.dentry->d_inode);
        for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl);
                        fl = fl->fl_next) {
@@ -1328,7 +1347,7 @@ int fcntl_getlease(struct file *filp)
                        break;
                }
        }
-       unlock_kernel();
+       unlock_flocks();
        return type;
 }
 
@@ -1341,7 +1360,7 @@ int fcntl_getlease(struct file *filp)
  *     The (input) flp->fl_lmops->fl_break function is required
  *     by break_lease().
  *
- *     Called with kernel lock held.
+ *     Called with file_lock_lock held.
  */
 int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
 {
@@ -1436,7 +1455,15 @@ out:
 }
 EXPORT_SYMBOL(generic_setlease);
 
- /**
+static int __vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
+{
+       if (filp->f_op && filp->f_op->setlease)
+               return filp->f_op->setlease(filp, arg, lease);
+       else
+               return generic_setlease(filp, arg, lease);
+}
+
+/**
  *     vfs_setlease        -       sets a lease on an open file
  *     @filp: file pointer
  *     @arg: type of lease to obtain
@@ -1467,12 +1494,9 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
 {
        int error;
 
-       lock_kernel();
-       if (filp->f_op && filp->f_op->setlease)
-               error = filp->f_op->setlease(filp, arg, lease);
-       else
-               error = generic_setlease(filp, arg, lease);
-       unlock_kernel();
+       lock_flocks();
+       error = __vfs_setlease(filp, arg, lease);
+       unlock_flocks();
 
        return error;
 }
@@ -1499,9 +1523,9 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
        if (error)
                return error;
 
-       lock_kernel();
+       lock_flocks();
 
-       error = vfs_setlease(filp, arg, &flp);
+       error = __vfs_setlease(filp, arg, &flp);
        if (error || arg == F_UNLCK)
                goto out_unlock;
 
@@ -1516,7 +1540,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
 
        error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
 out_unlock:
-       unlock_kernel();
+       unlock_flocks();
        return error;
 }
 
@@ -2020,7 +2044,7 @@ void locks_remove_flock(struct file *filp)
                        fl.fl_ops->fl_release_private(&fl);
        }
 
-       lock_kernel();
+       lock_flocks();
        before = &inode->i_flock;
 
        while ((fl = *before) != NULL) {
@@ -2038,7 +2062,7 @@ void locks_remove_flock(struct file *filp)
                }
                before = &fl->fl_next;
        }
-       unlock_kernel();
+       unlock_flocks();
 }
 
 /**
@@ -2053,12 +2077,12 @@ posix_unblock_lock(struct file *filp, struct file_lock *waiter)
 {
        int status = 0;
 
-       lock_kernel();
+       lock_flocks();
        if (waiter->fl_next)
                __locks_delete_block(waiter);
        else
                status = -ENOENT;
-       unlock_kernel();
+       unlock_flocks();
        return status;
 }
 
@@ -2172,7 +2196,7 @@ static int locks_show(struct seq_file *f, void *v)
 
 static void *locks_start(struct seq_file *f, loff_t *pos)
 {
-       lock_kernel();
+       lock_flocks();
        f->private = (void *)1;
        return seq_list_start(&file_lock_list, *pos);
 }
@@ -2184,7 +2208,7 @@ static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
 
 static void locks_stop(struct seq_file *f, void *v)
 {
-       unlock_kernel();
+       unlock_flocks();
 }
 
 static const struct seq_operations locks_seq_operations = {
@@ -2231,7 +2255,7 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
 {
        struct file_lock *fl;
        int result = 1;
-       lock_kernel();
+       lock_flocks();
        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                if (IS_POSIX(fl)) {
                        if (fl->fl_type == F_RDLCK)
@@ -2248,7 +2272,7 @@ int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
                result = 0;
                break;
        }
-       unlock_kernel();
+       unlock_flocks();
        return result;
 }
 
@@ -2271,7 +2295,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
 {
        struct file_lock *fl;
        int result = 1;
-       lock_kernel();
+       lock_flocks();
        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                if (IS_POSIX(fl)) {
                        if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
@@ -2286,7 +2310,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
                result = 0;
                break;
        }
-       unlock_kernel();
+       unlock_flocks();
        return result;
 }
 
index a72eaabfe8f2a58868e96397b320ba819e159884..7ca5182c0bedd547e21531e777175d2058ea2982 100644 (file)
@@ -1744,9 +1744,7 @@ static int do_new_mount(struct path *path, char *type, int flags,
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       lock_kernel();
        mnt = do_kern_mount(type, flags, name, data);
-       unlock_kernel();
        if (IS_ERR(mnt))
                return PTR_ERR(mnt);
 
index 9578cbe0cd589ad00ce590d60172c2433d16688e..aac8832e919e9a56cb95af787af658fb03d8d0d1 100644 (file)
@@ -95,6 +95,34 @@ const struct dentry_operations ncp_root_dentry_operations =
 };
 
 
+#define ncp_namespace(i)       (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
+
+static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
+{
+#ifdef CONFIG_NCPFS_SMALLDOS
+       int ns = ncp_namespace(i);
+
+       if ((ns == NW_NS_DOS)
+#ifdef CONFIG_NCPFS_OS2_NS
+               || ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS))
+#endif /* CONFIG_NCPFS_OS2_NS */
+          )
+               return 0;
+#endif /* CONFIG_NCPFS_SMALLDOS */
+       return 1;
+}
+
+#define ncp_preserve_case(i)   (ncp_namespace(i) != NW_NS_DOS)
+
+static inline int ncp_case_sensitive(struct dentry *dentry)
+{
+#ifdef CONFIG_NCPFS_NFS_NS
+       return ncp_namespace(dentry->d_inode) == NW_NS_NFS;
+#else
+       return 0;
+#endif /* CONFIG_NCPFS_NFS_NS */
+}
+
 /*
  * Note: leave the hash unchanged if the directory
  * is case-sensitive.
@@ -102,13 +130,12 @@ const struct dentry_operations ncp_root_dentry_operations =
 static int 
 ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
 {
-       struct nls_table *t;
-       unsigned long hash;
-       int i;
-
-       t = NCP_IO_TABLE(dentry);
+       if (!ncp_case_sensitive(dentry)) {
+               struct nls_table *t;
+               unsigned long hash;
+               int i;
 
-       if (!ncp_case_sensitive(dentry->d_inode)) {
+               t = NCP_IO_TABLE(dentry);
                hash = init_name_hash();
                for (i=0; i<this->len ; i++)
                        hash = partial_name_hash(ncp_tolower(t, this->name[i]),
@@ -124,7 +151,7 @@ ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
        if (a->len != b->len)
                return 1;
 
-       if (ncp_case_sensitive(dentry->d_inode))
+       if (ncp_case_sensitive(dentry))
                return strncmp(a->name, b->name, a->len);
 
        return ncp_strnicmp(NCP_IO_TABLE(dentry), a->name, b->name, a->len);
@@ -266,7 +293,7 @@ leave_me:;
 
 
 static int
-__ncp_lookup_validate(struct dentry *dentry)
+ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd)
 {
        struct ncp_server *server;
        struct dentry *parent;
@@ -283,9 +310,6 @@ __ncp_lookup_validate(struct dentry *dentry)
 
        server = NCP_SERVER(dir);
 
-       if (!ncp_conn_valid(server))
-               goto finished;
-
        /*
         * Inspired by smbfs:
         * The default validation is based on dentry age:
@@ -304,8 +328,11 @@ __ncp_lookup_validate(struct dentry *dentry)
        if (ncp_is_server_root(dir)) {
                res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
                                 dentry->d_name.len, 1);
-               if (!res)
+               if (!res) {
                        res = ncp_lookup_volume(server, __name, &(finfo.i));
+                       if (!res)
+                               ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
+               }
        } else {
                res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
                                 dentry->d_name.len, !ncp_preserve_case(dir));
@@ -320,13 +347,17 @@ __ncp_lookup_validate(struct dentry *dentry)
         * what we remember, it's not valid any more.
         */
        if (!res) {
-               if (finfo.i.dirEntNum == NCP_FINFO(dentry->d_inode)->dirEntNum) {
+               struct inode *inode = dentry->d_inode;
+
+               mutex_lock(&inode->i_mutex);
+               if (finfo.i.dirEntNum == NCP_FINFO(inode)->dirEntNum) {
                        ncp_new_dentry(dentry);
                        val=1;
                } else
                        DDPRINTK("ncp_lookup_validate: found, but dirEntNum changed\n");
 
-               ncp_update_inode2(dentry->d_inode, &finfo);
+               ncp_update_inode2(inode, &finfo);
+               mutex_unlock(&inode->i_mutex);
        }
 
 finished:
@@ -335,16 +366,6 @@ finished:
        return val;
 }
 
-static int
-ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd)
-{
-       int res;
-       lock_kernel();
-       res = __ncp_lookup_validate(dentry);
-       unlock_kernel();
-       return res;
-}
-
 static struct dentry *
 ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
 {
@@ -411,8 +432,6 @@ 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;
 
@@ -421,6 +440,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
                (int) filp->f_pos);
 
        result = -EIO;
+       /* Do not generate '.' and '..' when server is dead. */
        if (!ncp_conn_valid(server))
                goto out;
 
@@ -532,6 +552,12 @@ read_really:
        ctl.head.end = ctl.fpos - 1;
        ctl.head.eof = ctl.valid;
 finished:
+       if (ctl.page) {
+               kunmap(ctl.page);
+               SetPageUptodate(ctl.page);
+               unlock_page(ctl.page);
+               page_cache_release(ctl.page);
+       }
        if (page) {
                cache->head = ctl.head;
                kunmap(page);
@@ -539,23 +565,17 @@ finished:
                unlock_page(page);
                page_cache_release(page);
        }
-       if (ctl.page) {
-               kunmap(ctl.page);
-               SetPageUptodate(ctl.page);
-               unlock_page(ctl.page);
-               page_cache_release(ctl.page);
-       }
 out:
-       unlock_kernel();
        return result;
 }
 
 static int
 ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-               struct ncp_cache_control *ctrl, struct ncp_entry_info *entry)
+               struct ncp_cache_control *ctrl, struct ncp_entry_info *entry,
+               int inval_childs)
 {
        struct dentry *newdent, *dentry = filp->f_path.dentry;
-       struct inode *newino, *inode = dentry->d_inode;
+       struct inode *dir = dentry->d_inode;
        struct ncp_cache_control ctl = *ctrl;
        struct qstr qname;
        int valid = 0;
@@ -564,9 +584,9 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
        __u8 __name[NCP_MAXPATHLEN + 1];
 
        qname.len = sizeof(__name);
-       if (ncp_vol2io(NCP_SERVER(inode), __name, &qname.len,
+       if (ncp_vol2io(NCP_SERVER(dir), __name, &qname.len,
                        entry->i.entryName, entry->i.nameLen,
-                       !ncp_preserve_entry_case(inode, entry->i.NSCreator)))
+                       !ncp_preserve_entry_case(dir, entry->i.NSCreator)))
                return 1; /* I'm not sure */
 
        qname.name = __name;
@@ -584,22 +604,64 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
                        goto end_advance;
        } else {
                hashed = 1;
-               memcpy((char *) newdent->d_name.name, qname.name,
-                                                       newdent->d_name.len);
+
+               /* If case sensitivity changed for this volume, all entries below this one
+                  should be thrown away.  This entry itself is not affected, as its case
+                  sensitivity is controlled by its own parent. */
+               if (inval_childs)
+                       shrink_dcache_parent(newdent);
+
+               /*
+                * It is not as dangerous as it looks.  NetWare's OS2 namespace is
+                * case preserving yet case insensitive.  So we update dentry's name
+                * as received from server.  We found dentry via d_lookup with our
+                * hash, so we know that hash does not change, and so replacing name
+                * should be reasonably safe.
+                */
+               if (qname.len == newdent->d_name.len &&
+                   memcmp(newdent->d_name.name, qname.name, newdent->d_name.len)) {
+                       struct inode *inode = newdent->d_inode;
+
+                       /*
+                        * Inside ncpfs all uses of d_name are either for debugging,
+                        * or on functions which acquire inode mutex (mknod, creat,
+                        * lookup).  So grab i_mutex here, to be sure.  d_path
+                        * uses dcache_lock when generating path, so we should too.
+                        * And finally d_compare is protected by dentry's d_lock, so
+                        * here we go.
+                        */
+                       if (inode)
+                               mutex_lock(&inode->i_mutex);
+                       spin_lock(&dcache_lock);
+                       spin_lock(&newdent->d_lock);
+                       memcpy((char *) newdent->d_name.name, qname.name,
+                                                               newdent->d_name.len);
+                       spin_unlock(&newdent->d_lock);
+                       spin_unlock(&dcache_lock);
+                       if (inode)
+                               mutex_unlock(&inode->i_mutex);
+               }
        }
 
        if (!newdent->d_inode) {
+               struct inode *inode;
+
                entry->opened = 0;
-               entry->ino = iunique(inode->i_sb, 2);
-               newino = ncp_iget(inode->i_sb, entry);
-               if (newino) {
+               entry->ino = iunique(dir->i_sb, 2);
+               inode = ncp_iget(dir->i_sb, entry);
+               if (inode) {
                        newdent->d_op = &ncp_dentry_operations;
-                       d_instantiate(newdent, newino);
+                       d_instantiate(newdent, inode);
                        if (!hashed)
                                d_rehash(newdent);
                }
-       } else
-               ncp_update_inode2(newdent->d_inode, entry);
+       } else {
+               struct inode *inode = newdent->d_inode;
+
+               mutex_lock(&inode->i_mutex);
+               ncp_update_inode2(inode, entry);
+               mutex_unlock(&inode->i_mutex);
+       }
 
        if (newdent->d_inode) {
                ino = newdent->d_inode->i_ino;
@@ -617,7 +679,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
                ctl.cache = NULL;
                ctl.idx  -= NCP_DIRCACHE_SIZE;
                ctl.ofs  += 1;
-               ctl.page  = grab_cache_page(&inode->i_data, ctl.ofs);
+               ctl.page  = grab_cache_page(&dir->i_data, ctl.ofs);
                if (ctl.page)
                        ctl.cache = kmap(ctl.page);
        }
@@ -633,7 +695,7 @@ end_advance:
                if (!ino)
                        ino = find_inode_number(dentry, &qname);
                if (!ino)
-                       ino = iunique(inode->i_sb, 2);
+                       ino = iunique(dir->i_sb, 2);
                ctl.filled = filldir(dirent, qname.name, qname.len,
                                     filp->f_pos, ino, DT_UNKNOWN);
                if (!ctl.filled)
@@ -660,6 +722,7 @@ ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir,
                        (unsigned long) filp->f_pos);
 
        for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) {
+               int inval_dentry;
 
                if (ncp_get_volume_info_with_number(server, i, &info) != 0)
                        return;
@@ -675,8 +738,9 @@ ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir,
                                info.volume_name);
                        continue;
                }
+               inval_dentry = ncp_update_known_namespace(server, entry.i.volNumber, NULL);
                entry.volume = entry.i.volNumber;
-               if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry))
+               if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry, inval_dentry))
                        return;
        }
 }
@@ -739,7 +803,7 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
                        rpl += onerpl;
                        rpls -= onerpl;
                        entry.volume = entry.i.volNumber;
-                       if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry))
+                       if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry, 0))
                                break;
                }
        } while (more);
@@ -775,17 +839,19 @@ int ncp_conn_logged_in(struct super_block *sb)
                if (dent) {
                        struct inode* ino = dent->d_inode;
                        if (ino) {
+                               ncp_update_known_namespace(server, volNumber, NULL);
                                NCP_FINFO(ino)->volNumber = volNumber;
                                NCP_FINFO(ino)->dirEntNum = dirEntNum;
                                NCP_FINFO(ino)->DosDirNum = DosDirNum;
+                               result = 0;
                        } else {
                                DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n");
                        }
                } else {
                        DPRINTK("ncpfs: sb->s_root == NULL!\n");
                }
-       }
-       result = 0;
+       } else
+               result = 0;
 
 out:
        return result;
@@ -799,7 +865,6 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc
        int error, res, len;
        __u8 __name[NCP_MAXPATHLEN + 1];
 
-       lock_kernel();
        error = -EIO;
        if (!ncp_conn_valid(server))
                goto finished;
@@ -813,6 +878,8 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc
                                 dentry->d_name.len, 1);
                if (!res)
                        res = ncp_lookup_volume(server, __name, &(finfo.i));
+                       if (!res)
+                               ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
        } else {
                res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
                                 dentry->d_name.len, !ncp_preserve_case(dir));
@@ -846,7 +913,6 @@ add_entry:
 
 finished:
        PPRINTK("ncp_lookup: result=%d\n", error);
-       unlock_kernel();
        return ERR_PTR(error);
 }
 
@@ -887,11 +953,6 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
        PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n",
                dentry->d_parent->d_name.name, dentry->d_name.name, mode);
 
-       error = -EIO;
-       lock_kernel();
-       if (!ncp_conn_valid(server))
-               goto out;
-
        ncp_age_dentry(server, dentry);
        len = sizeof(__name);
        error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
@@ -917,6 +978,8 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
                if (result) {
                        if (result == 0x87)
                                error = -ENAMETOOLONG;
+                       else if (result < 0)
+                               error = result;
                        DPRINTK("ncp_create: %s/%s failed\n",
                                dentry->d_parent->d_name.name, dentry->d_name.name);
                        goto out;
@@ -935,7 +998,6 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
 
        error = ncp_instantiate(dir, dentry, &finfo);
 out:
-       unlock_kernel();
        return error;
 }
 
@@ -955,11 +1017,6 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        DPRINTK("ncp_mkdir: making %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
 
-       error = -EIO;
-       lock_kernel();
-       if (!ncp_conn_valid(server))
-               goto out;
-
        ncp_age_dentry(server, dentry);
        len = sizeof(__name);
        error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
@@ -967,12 +1024,11 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        if (error)
                goto out;
 
-       error = -EACCES;
-       if (ncp_open_create_file_or_subdir(server, dir, __name,
+       error = ncp_open_create_file_or_subdir(server, dir, __name,
                                           OC_MODE_CREATE, aDIR,
                                           cpu_to_le16(0xffff),
-                                          &finfo) == 0)
-       {
+                                          &finfo);
+       if (error == 0) {
                if (ncp_is_nfs_extras(server, finfo.volume)) {
                        mode |= S_IFDIR;
                        finfo.i.nfs.mode = mode;
@@ -983,9 +1039,10 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
                                goto out;
                }
                error = ncp_instantiate(dir, dentry, &finfo);
+       } else if (error > 0) {
+               error = -EACCES;
        }
 out:
-       unlock_kernel();
        return error;
 }
 
@@ -998,11 +1055,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
        DPRINTK("ncp_rmdir: removing %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
 
-       error = -EIO;
-       lock_kernel();
-       if (!ncp_conn_valid(server))
-               goto out;
-
        error = -EBUSY;
        if (!d_unhashed(dentry))
                goto out;
@@ -1036,11 +1088,10 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
                        error = -ENOENT;
                        break;
                default:
-                       error = -EACCES;
+                       error = result < 0 ? result : -EACCES;
                        break;
                }
 out:
-       unlock_kernel();
        return error;
 }
 
@@ -1050,15 +1101,10 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry)
        struct ncp_server *server;
        int error;
 
-       lock_kernel();
        server = NCP_SERVER(dir);
        DPRINTK("ncp_unlink: unlinking %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
        
-       error = -EIO;
-       if (!ncp_conn_valid(server))
-               goto out;
-
        /*
         * Check whether to close the file ...
         */
@@ -1097,12 +1143,9 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry)
                        error = -ENOENT;
                        break;
                default:
-                       error = -EACCES;
+                       error = error < 0 ? error : -EACCES;
                        break;
        }
-               
-out:
-       unlock_kernel();
        return error;
 }
 
@@ -1118,11 +1161,6 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
                old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
                new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
 
-       error = -EIO;
-       lock_kernel();
-       if (!ncp_conn_valid(server))
-               goto out;
-
        ncp_age_dentry(server, old_dentry);
        ncp_age_dentry(server, new_dentry);
 
@@ -1161,11 +1199,10 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
                        error = -ENOENT;
                        break;
                default:
-                       error = -EACCES;
+                       error = error < 0 ? error : -EACCES;
                        break;
        }
 out:
-       unlock_kernel();
        return error;
 }
 
index 3639cc5cbdae58d8961308c77caf70f2535db579..6c754f70c5296be3fbe5c323bbb985d7ee326512 100644 (file)
@@ -113,9 +113,6 @@ ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        DPRINTK("ncp_file_read: enter %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
 
-       if (!ncp_conn_valid(NCP_SERVER(inode)))
-               return -EIO;
-
        pos = *ppos;
 
        if ((ssize_t) count < 0) {
@@ -192,13 +189,11 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
 
        DPRINTK("ncp_file_write: enter %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
-       if (!ncp_conn_valid(NCP_SERVER(inode)))
-               return -EIO;
        if ((ssize_t) count < 0)
                return -EINVAL;
        pos = *ppos;
        if (file->f_flags & O_APPEND) {
-               pos = inode->i_size;
+               pos = i_size_read(inode);
        }
 
        if (pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) {
@@ -264,8 +259,11 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
 
        *ppos = pos;
 
-       if (pos > inode->i_size) {
-               inode->i_size = pos;
+       if (pos > i_size_read(inode)) {
+               mutex_lock(&inode->i_mutex);
+               if (pos > i_size_read(inode))
+                       i_size_write(inode, pos);
+               mutex_unlock(&inode->i_mutex);
        }
        DPRINTK("ncp_file_write: exit %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -281,18 +279,9 @@ static int ncp_release(struct inode *inode, struct file *file) {
        return 0;
 }
 
-static loff_t ncp_remote_llseek(struct file *file, loff_t offset, int origin)
-{
-       loff_t ret;
-       lock_kernel();
-       ret = generic_file_llseek_unlocked(file, offset, origin);
-       unlock_kernel();
-       return ret;
-}
-
 const struct file_operations ncp_file_operations =
 {
-       .llseek         = ncp_remote_llseek,
+       .llseek         = generic_file_llseek,
        .read           = ncp_file_read,
        .write          = ncp_file_write,
        .unlocked_ioctl = ncp_ioctl,
index b4de38cf49f5f3a802a112cbd99226e12d49cf38..985fabb26aca44edcacc889af0a8d2c5c47e8f04 100644 (file)
@@ -139,7 +139,7 @@ static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
                inode->i_mode = nwi->nfs.mode;
        }
 
-       inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
+       inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
 
        inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
        inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
@@ -158,18 +158,21 @@ static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
                inode->i_mode = server->m.dir_mode;
                /* for directories dataStreamSize seems to be some
                   Object ID ??? */
-               inode->i_size = NCP_BLOCK_SIZE;
+               i_size_write(inode, NCP_BLOCK_SIZE);
        } else {
+               u32 size;
+
                inode->i_mode = server->m.file_mode;
-               inode->i_size = le32_to_cpu(nwi->dataStreamSize);
+               size = le32_to_cpu(nwi->dataStreamSize);
+               i_size_write(inode, size);
 #ifdef CONFIG_NCPFS_EXTRAS
                if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 
                 && (nwi->attributes & aSHARED)) {
                        switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
                                case aHIDDEN:
                                        if (server->m.flags & NCP_MOUNT_SYMLINKS) {
-                                               if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE)
-                                                && */ (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
+                                               if (/* (size >= NCP_MIN_SYMLINK_SIZE)
+                                                && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
                                                        inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
                                                        NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
                                                        break;
@@ -208,7 +211,7 @@ void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
 }
 
 /*
- * Fill in the inode based on the ncp_entry_info structure.
+ * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
  */
 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
 {
@@ -254,6 +257,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
        if (inode) {
                atomic_set(&NCP_FINFO(inode)->opened, info->opened);
 
+               inode->i_mapping->backing_dev_info = sb->s_bdi;
                inode->i_ino = info->ino;
                ncp_set_attr(inode, info);
                if (S_ISREG(inode->i_mode)) {
@@ -299,10 +303,12 @@ ncp_evict_inode(struct inode *inode)
 
 static void ncp_stop_tasks(struct ncp_server *server) {
        struct sock* sk = server->ncp_sock->sk;
-               
+
+       lock_sock(sk);
        sk->sk_error_report = server->error_report;
        sk->sk_data_ready   = server->data_ready;
        sk->sk_write_space  = server->write_space;
+       release_sock(sk);
        del_timer_sync(&server->timeout_tm);
        flush_scheduled_work();
 }
@@ -565,10 +571,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 /*     server->conn_status = 0;        */
 /*     server->root_dentry = NULL;     */
 /*     server->root_setuped = 0;       */
+       mutex_init(&server->root_setup_lock);
 #ifdef CONFIG_NCPFS_PACKET_SIGNING
 /*     server->sign_wanted = 0;        */
 /*     server->sign_active = 0;        */
 #endif
+       init_rwsem(&server->auth_rwsem);
        server->auth.auth_type = NCP_AUTH_NONE;
 /*     server->auth.object_name_len = 0;       */
 /*     server->auth.object_name = NULL;        */
@@ -593,16 +601,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        server->nls_io = load_nls_default();
 #endif /* CONFIG_NCPFS_NLS */
 
-       server->dentry_ttl = 0; /* no caching */
+       atomic_set(&server->dentry_ttl, 0);     /* no caching */
 
        INIT_LIST_HEAD(&server->tx.requests);
        mutex_init(&server->rcv.creq_mutex);
        server->tx.creq         = NULL;
        server->rcv.creq        = NULL;
-       server->data_ready      = sock->sk->sk_data_ready;
-       server->write_space     = sock->sk->sk_write_space;
-       server->error_report    = sock->sk->sk_error_report;
-       sock->sk->sk_user_data  = server;
 
        init_timer(&server->timeout_tm);
 #undef NCP_PACKET_SIZE
@@ -619,6 +623,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        if (server->rxbuf == NULL)
                goto out_txbuf;
 
+       lock_sock(sock->sk);
+       server->data_ready      = sock->sk->sk_data_ready;
+       server->write_space     = sock->sk->sk_write_space;
+       server->error_report    = sock->sk->sk_error_report;
+       sock->sk->sk_user_data  = server;
        sock->sk->sk_data_ready   = ncp_tcp_data_ready;
        sock->sk->sk_error_report = ncp_tcp_error_report;
        if (sock->type == SOCK_STREAM) {
@@ -634,6 +643,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                server->timeout_tm.data = (unsigned long)server;
                server->timeout_tm.function = ncpdgram_timeout_call;
        }
+       release_sock(sock->sk);
 
        ncp_lock_server(server);
        error = ncp_connect(server);
@@ -658,8 +668,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                goto out_disconnect;
                        }
                }
+               ncp_lock_server(server);
                if (options & 2)
                        server->sign_wanted = 1;
+               ncp_unlock_server(server);
        }
        else 
 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
@@ -720,6 +732,9 @@ out_nls:
        unload_nls(server->nls_io);
        unload_nls(server->nls_vol);
 #endif
+       mutex_destroy(&server->rcv.creq_mutex);
+       mutex_destroy(&server->root_setup_lock);
+       mutex_destroy(&server->mutex);
 out_fput2:
        if (server->info_filp)
                fput(server->info_filp);
@@ -743,8 +758,6 @@ static void ncp_put_super(struct super_block *sb)
 {
        struct ncp_server *server = NCP_SBP(sb);
 
-       lock_kernel();
-
        ncp_lock_server(server);
        ncp_disconnect(server);
        ncp_unlock_server(server);
@@ -756,6 +769,9 @@ static void ncp_put_super(struct super_block *sb)
        unload_nls(server->nls_vol);
        unload_nls(server->nls_io);
 #endif /* CONFIG_NCPFS_NLS */
+       mutex_destroy(&server->rcv.creq_mutex);
+       mutex_destroy(&server->root_setup_lock);
+       mutex_destroy(&server->mutex);
 
        if (server->info_filp)
                fput(server->info_filp);
@@ -771,8 +787,6 @@ static void ncp_put_super(struct super_block *sb)
        vfree(server->packet);
        sb->s_fs_info = NULL;
        kfree(server);
-
-       unlock_kernel();
 }
 
 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -851,10 +865,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 
        result = -EIO;
 
-       lock_kernel();  
-
        server = NCP_SERVER(inode);
-       if ((!server) || !ncp_conn_valid(server))
+       if (!server)    /* How this could happen? */
                goto out;
 
        /* ageing the dentry to force validation */
@@ -981,8 +993,6 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
                result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
                                      inode, info_mask, &info);
                if (result != 0) {
-                       result = -EACCES;
-
                        if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
                                /* NetWare seems not to allow this. I
                                   do not know why. So, just tell the
@@ -1005,7 +1015,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
        mark_inode_dirty(inode);
 
 out:
-       unlock_kernel();
+       if (result > 0)
+               result = -EACCES;
        return result;
 }
 
index 84a8cfc4e38ec533ecaf7b7ad2812fc306a18c3a..c2a1f9a155c3a6e8f82800334337b1b1b0aaa65a 100644 (file)
 #define NCP_PACKET_SIZE_INTERNAL 65536
 
 static int
-ncp_get_fs_info(struct ncp_server * server, struct file *file,
+ncp_get_fs_info(struct ncp_server * server, struct inode *inode,
                struct ncp_fs_info __user *arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
        struct ncp_fs_info info;
 
-       if (file_permission(file, MAY_WRITE) != 0
-           && current_uid() != server->m.mounted_uid)
-               return -EACCES;
-
        if (copy_from_user(&info, arg, sizeof(info)))
                return -EFAULT;
 
@@ -65,16 +60,11 @@ ncp_get_fs_info(struct ncp_server * server, struct file *file,
 }
 
 static int
-ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
+ncp_get_fs_info_v2(struct ncp_server * server, struct inode *inode,
                   struct ncp_fs_info_v2 __user * arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
        struct ncp_fs_info_v2 info2;
 
-       if (file_permission(file, MAY_WRITE) != 0
-           && current_uid() != server->m.mounted_uid)
-               return -EACCES;
-
        if (copy_from_user(&info2, arg, sizeof(info2)))
                return -EFAULT;
 
@@ -136,16 +126,11 @@ struct compat_ncp_privatedata_ioctl
 #define NCP_IOC_SETPRIVATEDATA_32      _IOR('n', 10, struct compat_ncp_privatedata_ioctl)
 
 static int
-ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file,
+ncp_get_compat_fs_info_v2(struct ncp_server * server, struct inode *inode,
                   struct compat_ncp_fs_info_v2 __user * arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
        struct compat_ncp_fs_info_v2 info2;
 
-       if (file_permission(file, MAY_WRITE) != 0
-           && current_uid() != server->m.mounted_uid)
-               return -EACCES;
-
        if (copy_from_user(&info2, arg, sizeof(info2)))
                return -EFAULT;
 
@@ -182,11 +167,8 @@ ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
        struct nls_table *iocharset;
        struct nls_table *oldset_io;
        struct nls_table *oldset_cp;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-       if (server->root_setuped)
-               return -EBUSY;
+       int utf8;
+       int err;
 
        if (copy_from_user(&user, arg, sizeof(user)))
                return -EFAULT;
@@ -206,28 +188,40 @@ ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
        user.iocharset[NCP_IOCSNAME_LEN] = 0;
        if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) {
                iocharset = load_nls_default();
-               NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+               utf8 = 0;
        } else if (!strcmp(user.iocharset, "utf8")) {
                iocharset = load_nls_default();
-               NCP_SET_FLAG(server, NCP_FLAG_UTF8);
+               utf8 = 1;
        } else {
                iocharset = load_nls(user.iocharset);
                if (!iocharset) {
                        unload_nls(codepage);
                        return -EBADRQC;
                }
-               NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+               utf8 = 0;
        }
 
-       oldset_cp = server->nls_vol;
-       server->nls_vol = codepage;
-       oldset_io = server->nls_io;
-       server->nls_io = iocharset;
-
+       mutex_lock(&server->root_setup_lock);
+       if (server->root_setuped) {
+               oldset_cp = codepage;
+               oldset_io = iocharset;
+               err = -EBUSY;
+       } else {
+               if (utf8)
+                       NCP_SET_FLAG(server, NCP_FLAG_UTF8);
+               else
+                       NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+               oldset_cp = server->nls_vol;
+               server->nls_vol = codepage;
+               oldset_io = server->nls_io;
+               server->nls_io = iocharset;
+               err = 0;
+       }
+       mutex_unlock(&server->root_setup_lock);
        unload_nls(oldset_cp);
        unload_nls(oldset_io);
 
-       return 0;
+       return err;
 }
 
 static int
@@ -237,6 +231,7 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
        int len;
 
        memset(&user, 0, sizeof(user));
+       mutex_lock(&server->root_setup_lock);
        if (server->nls_vol && server->nls_vol->charset) {
                len = strlen(server->nls_vol->charset);
                if (len > NCP_IOCSNAME_LEN)
@@ -254,6 +249,7 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
                strncpy(user.iocharset, server->nls_io->charset, len);
                user.iocharset[len] = 0;
        }
+       mutex_unlock(&server->root_setup_lock);
 
        if (copy_to_user(arg, &user, sizeof(user)))
                return -EFAULT;
@@ -261,25 +257,19 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
 }
 #endif /* CONFIG_NCPFS_NLS */
 
-static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg)
 {
-       struct inode *inode = filp->f_dentry->d_inode;
        struct ncp_server *server = NCP_SERVER(inode);
        int result;
        struct ncp_ioctl_request request;
        char* bouncebuffer;
        void __user *argp = (void __user *)arg;
-       uid_t uid = current_uid();
 
        switch (cmd) {
 #ifdef CONFIG_COMPAT
        case NCP_IOC_NCPREQUEST_32:
 #endif
        case NCP_IOC_NCPREQUEST:
-               if (file_permission(filp, MAY_WRITE) != 0
-                   && uid != server->m.mounted_uid)
-                       return -EACCES;
-
 #ifdef CONFIG_COMPAT
                if (cmd == NCP_IOC_NCPREQUEST_32) {
                        struct compat_ncp_ioctl_request request32;
@@ -314,7 +304,7 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                server->current_size = request.size;
                memcpy(server->packet, bouncebuffer, request.size);
 
-               result = ncp_request2(server, request.function, 
+               result = ncp_request2(server, request.function,
                        bouncebuffer, NCP_PACKET_SIZE_INTERNAL);
                if (result < 0)
                        result = -EIO;
@@ -331,69 +321,69 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
        case NCP_IOC_CONN_LOGGED_IN:
 
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EACCES;
                if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE))
                        return -EINVAL;
+               mutex_lock(&server->root_setup_lock);
                if (server->root_setuped)
-                       return -EBUSY;
-               server->root_setuped = 1;
-               return ncp_conn_logged_in(inode->i_sb);
+                       result = -EBUSY;
+               else {
+                       result = ncp_conn_logged_in(inode->i_sb);
+                       if (result == 0)
+                               server->root_setuped = 1;
+               }
+               mutex_unlock(&server->root_setup_lock);
+               return result;
 
        case NCP_IOC_GET_FS_INFO:
-               return ncp_get_fs_info(server, filp, argp);
+               return ncp_get_fs_info(server, inode, argp);
 
        case NCP_IOC_GET_FS_INFO_V2:
-               return ncp_get_fs_info_v2(server, filp, argp);
+               return ncp_get_fs_info_v2(server, inode, argp);
 
 #ifdef CONFIG_COMPAT
        case NCP_IOC_GET_FS_INFO_V2_32:
-               return ncp_get_compat_fs_info_v2(server, filp, argp);
+               return ncp_get_compat_fs_info_v2(server, inode, argp);
 #endif
        /* we have too many combinations of CONFIG_COMPAT,
         * CONFIG_64BIT and CONFIG_UID16, so just handle
         * any of the possible ioctls */
        case NCP_IOC_GETMOUNTUID16:
-       case NCP_IOC_GETMOUNTUID32:
-       case NCP_IOC_GETMOUNTUID64:
-               if (file_permission(filp, MAY_READ) != 0
-                       && uid != server->m.mounted_uid)
-                       return -EACCES;
-
-               if (cmd == NCP_IOC_GETMOUNTUID16) {
+               {
                        u16 uid;
+
                        SET_UID(uid, server->m.mounted_uid);
                        if (put_user(uid, (u16 __user *)argp))
                                return -EFAULT;
-               } else if (cmd == NCP_IOC_GETMOUNTUID32) {
-                       if (put_user(server->m.mounted_uid,
-                                               (u32 __user *)argp))
-                               return -EFAULT;
-               } else {
-                       if (put_user(server->m.mounted_uid,
-                                               (u64 __user *)argp))
-                               return -EFAULT;
+                       return 0;
                }
+       case NCP_IOC_GETMOUNTUID32:
+               if (put_user(server->m.mounted_uid,
+                            (u32 __user *)argp))
+                       return -EFAULT;
+               return 0;
+       case NCP_IOC_GETMOUNTUID64:
+               if (put_user(server->m.mounted_uid,
+                            (u64 __user *)argp))
+                       return -EFAULT;
                return 0;
 
        case NCP_IOC_GETROOT:
                {
                        struct ncp_setroot_ioctl sr;
 
-                       if (file_permission(filp, MAY_READ) != 0
-                           && uid != server->m.mounted_uid)
-                               return -EACCES;
-
+                       result = -EACCES;
+                       mutex_lock(&server->root_setup_lock);
                        if (server->m.mounted_vol[0]) {
                                struct dentry* dentry = inode->i_sb->s_root;
 
                                if (dentry) {
                                        struct inode* s_inode = dentry->d_inode;
-                               
+
                                        if (s_inode) {
                                                sr.volNumber = NCP_FINFO(s_inode)->volNumber;
                                                sr.dirEntNum = NCP_FINFO(s_inode)->dirEntNum;
                                                sr.namespace = server->name_space[sr.volNumber];
+                                               result = 0;
                                        } else
                                                DPRINTK("ncpfs: s_root->d_inode==NULL\n");
                                } else
@@ -402,10 +392,12 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                                sr.volNumber = -1;
                                sr.namespace = 0;
                                sr.dirEntNum = 0;
+                               result = 0;
                        }
-                       if (copy_to_user(argp, &sr, sizeof(sr)))
-                               return -EFAULT;
-                       return 0;
+                       mutex_unlock(&server->root_setup_lock);
+                       if (!result && copy_to_user(argp, &sr, sizeof(sr)))
+                               result = -EFAULT;
+                       return result;
                }
 
        case NCP_IOC_SETROOT:
@@ -416,103 +408,114 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        __le32 dosde;
                        struct dentry* dentry;
 
-                       if (!capable(CAP_SYS_ADMIN))
-                       {
-                               return -EACCES;
-                       }
-                       if (server->root_setuped) return -EBUSY;
                        if (copy_from_user(&sr, argp, sizeof(sr)))
                                return -EFAULT;
-                       if (sr.volNumber < 0) {
-                               server->m.mounted_vol[0] = 0;
-                               vnum = NCP_NUMBER_OF_VOLUMES;
-                               de = 0;
-                               dosde = 0;
-                       } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
-                               return -EINVAL;
-                       } else if (ncp_mount_subdir(server, sr.volNumber,
-                                               sr.namespace, sr.dirEntNum,
-                                               &vnum, &de, &dosde)) {
-                               return -ENOENT;
-                       }
-                       
-                       dentry = inode->i_sb->s_root;
-                       server->root_setuped = 1;
-                       if (dentry) {
-                               struct inode* s_inode = dentry->d_inode;
-                               
-                               if (s_inode) {
-                                       NCP_FINFO(s_inode)->volNumber = vnum;
-                                       NCP_FINFO(s_inode)->dirEntNum = de;
-                                       NCP_FINFO(s_inode)->DosDirNum = dosde;
+                       mutex_lock(&server->root_setup_lock);
+                       if (server->root_setuped)
+                               result = -EBUSY;
+                       else {
+                               if (sr.volNumber < 0) {
+                                       server->m.mounted_vol[0] = 0;
+                                       vnum = NCP_NUMBER_OF_VOLUMES;
+                                       de = 0;
+                                       dosde = 0;
+                                       result = 0;
+                               } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
+                                       result = -EINVAL;
+                               } else if (ncp_mount_subdir(server, sr.volNumber,
+                                                       sr.namespace, sr.dirEntNum,
+                                                       &vnum, &de, &dosde)) {
+                                       result = -ENOENT;
                                } else
-                                       DPRINTK("ncpfs: s_root->d_inode==NULL\n");
-                       } else
-                               DPRINTK("ncpfs: s_root==NULL\n");
+                                       result = 0;
+
+                               if (result == 0) {
+                                       dentry = inode->i_sb->s_root;
+                                       if (dentry) {
+                                               struct inode* s_inode = dentry->d_inode;
+
+                                               if (s_inode) {
+                                                       NCP_FINFO(s_inode)->volNumber = vnum;
+                                                       NCP_FINFO(s_inode)->dirEntNum = de;
+                                                       NCP_FINFO(s_inode)->DosDirNum = dosde;
+                                                       server->root_setuped = 1;
+                                               } else {
+                                                       DPRINTK("ncpfs: s_root->d_inode==NULL\n");
+                                                       result = -EIO;
+                                               }
+                                       } else {
+                                               DPRINTK("ncpfs: s_root==NULL\n");
+                                               result = -EIO;
+                                       }
+                               }
+                               result = 0;
+                       }
+                       mutex_unlock(&server->root_setup_lock);
 
-                       return 0;
+                       return result;
                }
 
-#ifdef CONFIG_NCPFS_PACKET_SIGNING     
+#ifdef CONFIG_NCPFS_PACKET_SIGNING
        case NCP_IOC_SIGN_INIT:
-               if (file_permission(filp, MAY_WRITE) != 0
-                   && uid != server->m.mounted_uid)
-                       return -EACCES;
-
-               if (argp) {
-                       if (server->sign_wanted)
-                       {
-                               struct ncp_sign_init sign;
+               {
+                       struct ncp_sign_init sign;
 
+                       if (argp)
                                if (copy_from_user(&sign, argp, sizeof(sign)))
                                        return -EFAULT;
-                               memcpy(server->sign_root,sign.sign_root,8);
-                               memcpy(server->sign_last,sign.sign_last,16);
-                               server->sign_active = 1;
+                       ncp_lock_server(server);
+                       mutex_lock(&server->rcv.creq_mutex);
+                       if (argp) {
+                               if (server->sign_wanted) {
+                                       memcpy(server->sign_root,sign.sign_root,8);
+                                       memcpy(server->sign_last,sign.sign_last,16);
+                                       server->sign_active = 1;
+                               }
+                               /* ignore when signatures not wanted */
+                       } else {
+                               server->sign_active = 0;
                        }
-                       /* ignore when signatures not wanted */
-               } else {
-                       server->sign_active = 0;
+                       mutex_unlock(&server->rcv.creq_mutex);
+                       ncp_unlock_server(server);
+                       return 0;
                }
-               return 0;               
-               
+
         case NCP_IOC_SIGN_WANTED:
-               if (file_permission(filp, MAY_READ) != 0
-                   && uid != server->m.mounted_uid)
-                       return -EACCES;
-               
-                if (put_user(server->sign_wanted, (int __user *)argp))
-                       return -EFAULT;
-                return 0;
+               {
+                       int state;
+
+                       ncp_lock_server(server);
+                       state = server->sign_wanted;
+                       ncp_unlock_server(server);
+                       if (put_user(state, (int __user *)argp))
+                               return -EFAULT;
+                       return 0;
+               }
 
        case NCP_IOC_SET_SIGN_WANTED:
                {
                        int newstate;
 
-                       if (file_permission(filp, MAY_WRITE) != 0
-                           && uid != server->m.mounted_uid)
-                               return -EACCES;
-
                        /* get only low 8 bits... */
                        if (get_user(newstate, (unsigned char __user *)argp))
                                return -EFAULT;
+                       result = 0;
+                       ncp_lock_server(server);
                        if (server->sign_active) {
                                /* cannot turn signatures OFF when active */
-                               if (!newstate) return -EINVAL;
+                               if (!newstate)
+                                       result = -EINVAL;
                        } else {
                                server->sign_wanted = newstate != 0;
                        }
-                       return 0;
+                       ncp_unlock_server(server);
+                       return result;
                }
 
 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
 
 #ifdef CONFIG_NCPFS_IOCTL_LOCKING
        case NCP_IOC_LOCKUNLOCK:
-               if (file_permission(filp, MAY_WRITE) != 0
-                   && uid != server->m.mounted_uid)
-                       return -EACCES;
-
                {
                        struct ncp_lock_ioctl    rqdata;
 
@@ -541,16 +544,13 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        {
                                return result;
                        }
-                       result = -EIO;
-                       if (!ncp_conn_valid(server))
-                               goto outrel;
                        result = -EISDIR;
                        if (!S_ISREG(inode->i_mode))
                                goto outrel;
                        if (rqdata.cmd == NCP_LOCK_CLEAR)
                        {
                                result = ncp_ClearPhysicalRecord(NCP_SERVER(inode),
-                                                       NCP_FINFO(inode)->file_handle, 
+                                                       NCP_FINFO(inode)->file_handle,
                                                        rqdata.offset,
                                                        rqdata.length);
                                if (result > 0) result = 0;     /* no such lock */
@@ -573,7 +573,7 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                                                        rqdata.timeout);
                                if (result > 0) result = -EAGAIN;
                        }
-outrel:                        
+outrel:
                        ncp_inode_close(inode);
                        return result;
                }
@@ -581,60 +581,62 @@ outrel:
 
 #ifdef CONFIG_COMPAT
        case NCP_IOC_GETOBJECTNAME_32:
-               if (uid != server->m.mounted_uid)
-                       return -EACCES;
                {
                        struct compat_ncp_objectname_ioctl user;
                        size_t outl;
 
                        if (copy_from_user(&user, argp, sizeof(user)))
                                return -EFAULT;
+                       down_read(&server->auth_rwsem);
                        user.auth_type = server->auth.auth_type;
                        outl = user.object_name_len;
                        user.object_name_len = server->auth.object_name_len;
                        if (outl > user.object_name_len)
                                outl = user.object_name_len;
+                       result = 0;
                        if (outl) {
                                if (copy_to_user(compat_ptr(user.object_name),
                                                 server->auth.object_name,
-                                                outl)) return -EFAULT;
+                                                outl))
+                                       result = -EFAULT;
                        }
-                       if (copy_to_user(argp, &user, sizeof(user)))
-                               return -EFAULT;
-                       return 0;
+                       up_read(&server->auth_rwsem);
+                       if (!result && copy_to_user(argp, &user, sizeof(user)))
+                               result = -EFAULT;
+                       return result;
                }
 #endif
 
        case NCP_IOC_GETOBJECTNAME:
-               if (uid != server->m.mounted_uid)
-                       return -EACCES;
                {
                        struct ncp_objectname_ioctl user;
                        size_t outl;
 
                        if (copy_from_user(&user, argp, sizeof(user)))
                                return -EFAULT;
+                       down_read(&server->auth_rwsem);
                        user.auth_type = server->auth.auth_type;
                        outl = user.object_name_len;
                        user.object_name_len = server->auth.object_name_len;
                        if (outl > user.object_name_len)
                                outl = user.object_name_len;
+                       result = 0;
                        if (outl) {
                                if (copy_to_user(user.object_name,
                                                 server->auth.object_name,
-                                                outl)) return -EFAULT;
+                                                outl))
+                                       result = -EFAULT;
                        }
-                       if (copy_to_user(argp, &user, sizeof(user)))
-                               return -EFAULT;
-                       return 0;
+                       up_read(&server->auth_rwsem);
+                       if (!result && copy_to_user(argp, &user, sizeof(user)))
+                               result = -EFAULT;
+                       return result;
                }
 
 #ifdef CONFIG_COMPAT
        case NCP_IOC_SETOBJECTNAME_32:
 #endif
        case NCP_IOC_SETOBJECTNAME:
-               if (uid != server->m.mounted_uid)
-                       return -EACCES;
                {
                        struct ncp_objectname_ioctl user;
                        void* newname;
@@ -666,9 +668,7 @@ outrel:
                        } else {
                                newname = NULL;
                        }
-                       /* enter critical section */
-                       /* maybe that kfree can sleep so do that this way */
-                       /* it is at least more SMP friendly (in future...) */
+                       down_write(&server->auth_rwsem);
                        oldname = server->auth.object_name;
                        oldnamelen = server->auth.object_name_len;
                        oldprivate = server->priv.data;
@@ -678,7 +678,7 @@ outrel:
                        server->auth.object_name = newname;
                        server->priv.len = 0;
                        server->priv.data = NULL;
-                       /* leave critical section */
+                       up_write(&server->auth_rwsem);
                        kfree(oldprivate);
                        kfree(oldname);
                        return 0;
@@ -688,8 +688,6 @@ outrel:
        case NCP_IOC_GETPRIVATEDATA_32:
 #endif
        case NCP_IOC_GETPRIVATEDATA:
-               if (uid != server->m.mounted_uid)
-                       return -EACCES;
                {
                        struct ncp_privatedata_ioctl user;
                        size_t outl;
@@ -706,14 +704,20 @@ outrel:
                        if (copy_from_user(&user, argp, sizeof(user)))
                                return -EFAULT;
 
+                       down_read(&server->auth_rwsem);
                        outl = user.len;
                        user.len = server->priv.len;
                        if (outl > user.len) outl = user.len;
+                       result = 0;
                        if (outl) {
                                if (copy_to_user(user.data,
                                                 server->priv.data,
-                                                outl)) return -EFAULT;
+                                                outl))
+                                       result = -EFAULT;
                        }
+                       up_read(&server->auth_rwsem);
+                       if (result)
+                               return result;
 #ifdef CONFIG_COMPAT
                        if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
                                struct compat_ncp_privatedata_ioctl user32;
@@ -733,8 +737,6 @@ outrel:
        case NCP_IOC_SETPRIVATEDATA_32:
 #endif
        case NCP_IOC_SETPRIVATEDATA:
-               if (uid != server->m.mounted_uid)
-                       return -EACCES;
                {
                        struct ncp_privatedata_ioctl user;
                        void* new;
@@ -762,12 +764,12 @@ outrel:
                        } else {
                                new = NULL;
                        }
-                       /* enter critical section */
+                       down_write(&server->auth_rwsem);
                        old = server->priv.data;
                        oldlen = server->priv.len;
                        server->priv.len = user.len;
                        server->priv.data = new;
-                       /* leave critical section */
+                       up_write(&server->auth_rwsem);
                        kfree(old);
                        return 0;
                }
@@ -775,17 +777,13 @@ outrel:
 #ifdef CONFIG_NCPFS_NLS
        case NCP_IOC_SETCHARSETS:
                return ncp_set_charsets(server, argp);
-               
+
        case NCP_IOC_GETCHARSETS:
                return ncp_get_charsets(server, argp);
 
 #endif /* CONFIG_NCPFS_NLS */
 
        case NCP_IOC_SETDENTRYTTL:
-               if (file_permission(filp, MAY_WRITE) != 0 &&
-                   uid != server->m.mounted_uid)
-                       return -EACCES;
-
                {
                        u_int32_t user;
 
@@ -795,13 +793,13 @@ outrel:
                        if (user > 20000)
                                return -EINVAL;
                        user = (user * HZ) / 1000;
-                       server->dentry_ttl = user;
+                       atomic_set(&server->dentry_ttl, user);
                        return 0;
                }
-               
+
        case NCP_IOC_GETDENTRYTTL:
                {
-                       u_int32_t user = (server->dentry_ttl * 1000) / HZ;
+                       u_int32_t user = (atomic_read(&server->dentry_ttl) * 1000) / HZ;
                        if (copy_to_user(argp, &user, sizeof(user)))
                                return -EFAULT;
                        return 0;
@@ -811,59 +809,103 @@ outrel:
        return -EINVAL;
 }
 
-static int ncp_ioctl_need_write(unsigned int cmd)
+long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct ncp_server *server = NCP_SERVER(inode);
+       uid_t uid = current_uid();
+       int need_drop_write = 0;
+       long ret;
+
        switch (cmd) {
-       case NCP_IOC_GET_FS_INFO:
-       case NCP_IOC_GET_FS_INFO_V2:
-       case NCP_IOC_NCPREQUEST:
-       case NCP_IOC_SETDENTRYTTL:
-       case NCP_IOC_SIGN_INIT:
-       case NCP_IOC_LOCKUNLOCK:
-       case NCP_IOC_SET_SIGN_WANTED:
-               return 1;
-       case NCP_IOC_GETOBJECTNAME:
-       case NCP_IOC_SETOBJECTNAME:
-       case NCP_IOC_GETPRIVATEDATA:
-       case NCP_IOC_SETPRIVATEDATA:
        case NCP_IOC_SETCHARSETS:
-       case NCP_IOC_GETCHARSETS:
        case NCP_IOC_CONN_LOGGED_IN:
-       case NCP_IOC_GETDENTRYTTL:
-       case NCP_IOC_GETMOUNTUID2:
-       case NCP_IOC_SIGN_WANTED:
-       case NCP_IOC_GETROOT:
        case NCP_IOC_SETROOT:
-               return 0;
-       default:
-               /* unknown IOCTL command, assume write */
-               return 1;
+               if (!capable(CAP_SYS_ADMIN)) {
+                       ret = -EACCES;
+                       goto out;
+               }
+               break;
        }
-}
-
-long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-       long ret;
-
-       lock_kernel();
-       if (ncp_ioctl_need_write(cmd)) {
+       if (server->m.mounted_uid != uid) {
+               switch (cmd) {
                /*
-                * inside the ioctl(), any failures which
-                * are because of file_permission() are
-                * -EACCESS, so it seems consistent to keep
-                *  that here.
+                * Only mount owner can issue these ioctls.  Information
+                * necessary to authenticate to other NDS servers are
+                * stored here.
                 */
-               if (mnt_want_write(filp->f_path.mnt)) {
+               case NCP_IOC_GETOBJECTNAME:
+               case NCP_IOC_SETOBJECTNAME:
+               case NCP_IOC_GETPRIVATEDATA:
+               case NCP_IOC_SETPRIVATEDATA:
+#ifdef CONFIG_COMPAT
+               case NCP_IOC_GETOBJECTNAME_32:
+               case NCP_IOC_SETOBJECTNAME_32:
+               case NCP_IOC_GETPRIVATEDATA_32:
+               case NCP_IOC_SETPRIVATEDATA_32:
+#endif
                        ret = -EACCES;
                        goto out;
+               /*
+                * These require write access on the inode if user id
+                * does not match.  Note that they do not write to the
+                * file...  But old code did mnt_want_write, so I keep
+                * it as is.  Of course not for mountpoint owner, as
+                * that breaks read-only mounts altogether as ncpmount
+                * needs working NCP_IOC_NCPREQUEST and
+                * NCP_IOC_GET_FS_INFO.  Some of these codes (setdentryttl,
+                * signinit, setsignwanted) should be probably restricted
+                * to owner only, or even more to CAP_SYS_ADMIN).
+                */
+               case NCP_IOC_GET_FS_INFO:
+               case NCP_IOC_GET_FS_INFO_V2:
+               case NCP_IOC_NCPREQUEST:
+               case NCP_IOC_SETDENTRYTTL:
+               case NCP_IOC_SIGN_INIT:
+               case NCP_IOC_LOCKUNLOCK:
+               case NCP_IOC_SET_SIGN_WANTED:
+#ifdef CONFIG_COMPAT
+               case NCP_IOC_GET_FS_INFO_V2_32:
+               case NCP_IOC_NCPREQUEST_32:
+#endif
+                       ret = mnt_want_write_file(filp);
+                       if (ret)
+                               goto out;
+                       need_drop_write = 1;
+                       ret = inode_permission(inode, MAY_WRITE);
+                       if (ret)
+                               goto outDropWrite;
+                       break;
+               /*
+                * Read access required.
+                */
+               case NCP_IOC_GETMOUNTUID16:
+               case NCP_IOC_GETMOUNTUID32:
+               case NCP_IOC_GETMOUNTUID64:
+               case NCP_IOC_GETROOT:
+               case NCP_IOC_SIGN_WANTED:
+                       ret = inode_permission(inode, MAY_READ);
+                       if (ret)
+                               goto out;
+                       break;
+               /*
+                * Anybody can read these.
+                */
+               case NCP_IOC_GETCHARSETS:
+               case NCP_IOC_GETDENTRYTTL:
+               default:
+               /* Three codes below are protected by CAP_SYS_ADMIN above. */
+               case NCP_IOC_SETCHARSETS:
+               case NCP_IOC_CONN_LOGGED_IN:
+               case NCP_IOC_SETROOT:
+                       break;
                }
        }
-       ret = __ncp_ioctl(filp, cmd, arg);
-       if (ncp_ioctl_need_write(cmd))
+       ret = __ncp_ioctl(inode, cmd, arg);
+outDropWrite:
+       if (need_drop_write)
                mnt_drop_write(filp->f_path.mnt);
-
 out:
-       unlock_kernel();
        return ret;
 }
 
@@ -872,10 +914,8 @@ long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long ret;
 
-       lock_kernel();
        arg = (unsigned long) compat_ptr(arg);
        ret = ncp_ioctl(file, cmd, arg);
-       unlock_kernel();
        return ret;
 }
 #endif
index 0ec6237a5970f162e0ed0d72b33fa9f1e15a7b86..a95615a0b6ac420fcfedbc8e6460173ddb3b3f97 100644 (file)
@@ -107,17 +107,17 @@ ncp_reply_data(struct ncp_server *server, int offset)
        return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
 }
 
-static inline u8 BVAL(void *data)
+static inline u8 BVAL(const void *data)
 {
-       return *(u8 *)data;
+       return *(const u8 *)data;
 }
 
 static u8 ncp_reply_byte(struct ncp_server *server, int offset)
 {
-       return *(u8 *)ncp_reply_data(server, offset);
+       return *(const u8 *)ncp_reply_data(server, offset);
 }
 
-static inline u16 WVAL_LH(void *data)
+static inline u16 WVAL_LH(const void *data)
 {
        return get_unaligned_le16(data);
 }
@@ -134,7 +134,7 @@ ncp_reply_be16(struct ncp_server *server, int offset)
        return get_unaligned_be16(ncp_reply_data(server, offset));
 }
 
-static inline u32 DVAL_LH(void *data)
+static inline u32 DVAL_LH(const void *data)
 {
        return get_unaligned_le32(data);
 }
@@ -349,9 +349,9 @@ int ncp_dirhandle_free(struct ncp_server* server, __u8 dirhandle) {
        return result;
 }
 
-void ncp_extract_file_info(void *structure, struct nw_info_struct *target)
+void ncp_extract_file_info(const void *structure, struct nw_info_struct *target)
 {
-       __u8 *name_len;
+       const __u8 *name_len;
        const int info_struct_size = offsetof(struct nw_info_struct, nameLen);
 
        memcpy(target, structure, info_struct_size);
@@ -364,7 +364,7 @@ void ncp_extract_file_info(void *structure, struct nw_info_struct *target)
 }
 
 #ifdef CONFIG_NCPFS_NFS_NS
-static inline void ncp_extract_nfs_info(unsigned char *structure,
+static inline void ncp_extract_nfs_info(const unsigned char *structure,
                                 struct nw_nfs_info *target)
 {
        target->mode = DVAL_LH(structure);
@@ -417,7 +417,7 @@ int ncp_obtain_nfs_info(struct ncp_server *server,
  * Returns information for a (one-component) name relative to
  * the specified directory.
  */
-int ncp_obtain_info(struct ncp_server *server, struct inode *dir, char *path,
+int ncp_obtain_info(struct ncp_server *server, struct inode *dir, const char *path,
                        struct nw_info_struct *target)
 {
        __u8  volnum = NCP_FINFO(dir)->volNumber;
@@ -452,16 +452,16 @@ out:
 #ifdef CONFIG_NCPFS_NFS_NS
 static int
 ncp_obtain_DOS_dir_base(struct ncp_server *server,
-               __u8 volnum, __le32 dirent,
-               char *path, /* At most 1 component */
+               __u8 ns, __u8 volnum, __le32 dirent,
+               const char *path, /* At most 1 component */
                __le32 *DOS_dir_base)
 {
        int result;
 
        ncp_init_request(server);
        ncp_add_byte(server, 6); /* subfunction */
-       ncp_add_byte(server, server->name_space[volnum]);
-       ncp_add_byte(server, server->name_space[volnum]);
+       ncp_add_byte(server, ns);
+       ncp_add_byte(server, ns);
        ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */
        ncp_add_dword(server, RIM_DIRECTORY);
        ncp_add_handle_path(server, volnum, dirent, 1, path);
@@ -523,10 +523,27 @@ ncp_get_known_namespace(struct ncp_server *server, __u8 volume)
 #endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */
 }
 
+int
+ncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns)
+{
+       int ns = ncp_get_known_namespace(server, volume);
+
+       if (ret_ns)
+               *ret_ns = ns;
+
+       DPRINTK("lookup_vol: namespace[%d] = %d\n",
+               volume, server->name_space[volume]);
+
+       if (server->name_space[volume] == ns)
+               return 0;
+       server->name_space[volume] = ns;
+       return 1;
+}
+
 static int
 ncp_ObtainSpecificDirBase(struct ncp_server *server,
                __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base,
-               char *path, /* At most 1 component */
+               const char *path, /* At most 1 component */
                __le32 *dirEntNum, __le32 *DosDirNum)
 {
        int result;
@@ -560,14 +577,13 @@ ncp_mount_subdir(struct ncp_server *server,
 {
        int dstNS;
        int result;
-       
-       dstNS = ncp_get_known_namespace(server, volNumber);
+
+       ncp_update_known_namespace(server, volNumber, &dstNS);
        if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, 
                                      dirEntNum, NULL, newDirEnt, newDosEnt)) != 0)
        {
                return result;
        }
-       server->name_space[volNumber] = dstNS;
        *volume = volNumber;
        server->m.mounted_vol[1] = 0;
        server->m.mounted_vol[0] = 'X';
@@ -575,11 +591,10 @@ ncp_mount_subdir(struct ncp_server *server,
 }
 
 int 
-ncp_get_volume_root(struct ncp_server *server, const char *volname,
-                   __u32* volume, __le32* dirent, __le32* dosdirent)
+ncp_get_volume_root(struct ncp_server *server,
+                   const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent)
 {
        int result;
-       __u8 volnum;
 
        DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname);
 
@@ -601,21 +616,14 @@ ncp_get_volume_root(struct ncp_server *server, const char *volname,
                return result;
        }
        *dirent = *dosdirent = ncp_reply_dword(server, 4);
-       volnum = ncp_reply_byte(server, 8);
+       *volume = ncp_reply_byte(server, 8);
        ncp_unlock_server(server);
-       *volume = volnum;
-
-       server->name_space[volnum] = ncp_get_known_namespace(server, volnum);
-
-       DPRINTK("lookup_vol: namespace[%d] = %d\n",
-               volnum, server->name_space[volnum]);
-
        return 0;
 }
 
 int
-ncp_lookup_volume(struct ncp_server *server, const char *volname,
-                 struct nw_info_struct *target)
+ncp_lookup_volume(struct ncp_server *server,
+                 const char *volname, struct nw_info_struct *target)
 {
        int result;
 
@@ -625,6 +633,7 @@ ncp_lookup_volume(struct ncp_server *server, const char *volname,
        if (result) {
                return result;
        }
+       ncp_update_known_namespace(server, target->volNumber, NULL);
        target->nameLen = strlen(volname);
        memcpy(target->entryName, volname, target->nameLen+1);
        target->attributes = aDIR;
@@ -676,8 +685,8 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
 {
        int result = 0;
 
+       ncp_init_request(server);
        if (server->name_space[volnum] == NW_NS_NFS) {
-               ncp_init_request(server);
                ncp_add_byte(server, 25);       /* subfunction */
                ncp_add_byte(server, server->name_space[volnum]);
                ncp_add_byte(server, NW_NS_NFS);
@@ -690,8 +699,8 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
                ncp_add_dword_lh(server, 1);    /* nlinks */
                ncp_add_dword_lh(server, rdev);
                result = ncp_request(server, 87);
-               ncp_unlock_server(server);
        }
+       ncp_unlock_server(server);
        return result;
 }
 #endif
@@ -700,7 +709,7 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
 static int
 ncp_DeleteNSEntry(struct ncp_server *server,
                  __u8 have_dir_base, __u8 volnum, __le32 dirent,
-                 char* name, __u8 ns, __le16 attr)
+                 const char* name, __u8 ns, __le16 attr)
 {
        int result;
 
@@ -734,23 +743,25 @@ ncp_del_file_or_subdir2(struct ncp_server *server,
 
 int
 ncp_del_file_or_subdir(struct ncp_server *server,
-                      struct inode *dir, char *name)
+                      struct inode *dir, const char *name)
 {
        __u8  volnum = NCP_FINFO(dir)->volNumber;
        __le32 dirent = NCP_FINFO(dir)->dirEntNum;
+       int name_space;
 
+       name_space = server->name_space[volnum];
 #ifdef CONFIG_NCPFS_NFS_NS
-       if (server->name_space[volnum]==NW_NS_NFS)
+       if (name_space == NW_NS_NFS)
        {
                int result;
  
-               result=ncp_obtain_DOS_dir_base(server, volnum, dirent, name, &dirent);
+               result=ncp_obtain_DOS_dir_base(server, name_space, volnum, dirent, name, &dirent);
                if (result) return result;
-               return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006));
+               name = NULL;
+               name_space = NW_NS_DOS;
        }
-       else
 #endif /* CONFIG_NCPFS_NFS_NS */
-               return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, server->name_space[volnum], cpu_to_le16(0x8006));
+       return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, name_space, cpu_to_le16(0x8006));
 }
 
 static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6])
@@ -765,7 +776,7 @@ static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6])
 /* If both dir and name are NULL, then in target there's already a
    looked-up entry that wants to be opened. */
 int ncp_open_create_file_or_subdir(struct ncp_server *server,
-                                  struct inode *dir, char *name,
+                                  struct inode *dir, const char *name,
                                   int open_create_mode,
                                   __le32 create_attributes,
                                   __le16 desired_acc_rights,
@@ -890,8 +901,8 @@ int ncp_search_for_fileset(struct ncp_server *server,
 
 static int
 ncp_RenameNSEntry(struct ncp_server *server,
-                 struct inode *old_dir, char *old_name, __le16 old_type,
-                 struct inode *new_dir, char *new_name)
+                 struct inode *old_dir, const char *old_name, __le16 old_type,
+                 struct inode *new_dir, const char *new_name)
 {
        int result = -EINVAL;
 
@@ -929,8 +940,8 @@ out:
 }
 
 int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
-                               struct inode *old_dir, char *old_name,
-                               struct inode *new_dir, char *new_name)
+                               struct inode *old_dir, const char *old_name,
+                               struct inode *new_dir, const char *new_name)
 {
         int result;
         __le16 old_type = cpu_to_le16(0x06);
@@ -958,7 +969,7 @@ int
 ncp_read_kernel(struct ncp_server *server, const char *file_id,
             __u32 offset, __u16 to_read, char *target, int *bytes_read)
 {
-       char *source;
+       const char *source;
        int result;
 
        ncp_init_request(server);
index 2441d1ab57dc57abe66ba24126b3b9221b1692bc..3c57eca634ce12f5d76b77959a3422677c9c3c53 100644 (file)
@@ -65,10 +65,11 @@ static inline void ncp_inode_close(struct inode *inode) {
        atomic_dec(&NCP_FINFO(inode)->opened);
 }
 
-void ncp_extract_file_info(void* src, struct nw_info_struct* target);
-int ncp_obtain_info(struct ncp_server *server, struct inode *, char *,
+void ncp_extract_file_info(const void* src, struct nw_info_struct* target);
+int ncp_obtain_info(struct ncp_server *server, struct inode *, const char *,
                struct nw_info_struct *target);
 int ncp_obtain_nfs_info(struct ncp_server *server, struct nw_info_struct *target);
+int ncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns);
 int ncp_get_volume_root(struct ncp_server *server, const char *volname,
                        __u32 *volume, __le32 *dirent, __le32 *dosdirent);
 int ncp_lookup_volume(struct ncp_server *, const char *, struct nw_info_struct *);
@@ -80,8 +81,8 @@ int ncp_modify_nfs_info(struct ncp_server *, __u8 volnum, __le32 dirent,
                        __u32 mode, __u32 rdev);
 
 int ncp_del_file_or_subdir2(struct ncp_server *, struct dentry*);
-int ncp_del_file_or_subdir(struct ncp_server *, struct inode *, char *);
-int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, char *,
+int ncp_del_file_or_subdir(struct ncp_server *, struct inode *, const char *);
+int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, const char *,
                                int, __le32, __le16, struct ncp_entry_info *);
 
 int ncp_initialize_search(struct ncp_server *, struct inode *,
@@ -93,7 +94,7 @@ int ncp_search_for_fileset(struct ncp_server *server,
                           char** rbuf, size_t* rsize);
 
 int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
-                             struct inode *, char *, struct inode *, char *);
+                             struct inode *, const char *, struct inode *, const char *);
 
 
 int
@@ -170,13 +171,13 @@ static inline int ncp_strnicmp(struct nls_table *t, const unsigned char *s1,
 #endif /* CONFIG_NCPFS_NLS */
 
 #define NCP_GET_AGE(dentry)    (jiffies - (dentry)->d_time)
-#define NCP_MAX_AGE(server)    ((server)->dentry_ttl)
+#define NCP_MAX_AGE(server)    atomic_read(&(server)->dentry_ttl)
 #define NCP_TEST_AGE(server,dentry)    (NCP_GET_AGE(dentry) < NCP_MAX_AGE(server))
 
 static inline void
 ncp_age_dentry(struct ncp_server* server, struct dentry* dentry)
 {
-       dentry->d_time = jiffies - server->dentry_ttl;
+       dentry->d_time = jiffies - NCP_MAX_AGE(server);
 }
 
 static inline void
index 7c0b5c21e6cf668dc791212327ebe46b8a3007bf..d8b2d7e6910b1a843a425b7a84164b2b061e99b6 100644 (file)
 
 /* i386: 32-bit, little endian, handles mis-alignment */
 #ifdef __i386__
-#define GET_LE32(p) (*(int *)(p))
+#define GET_LE32(p) (*(const int *)(p))
 #define PUT_LE32(p,v) { *(int *)(p)=v; }
 #else
 /* from include/ncplib.h */
-#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
+#define BVAL(buf,pos) (((const __u8 *)(buf))[pos])
 #define PVAL(buf,pos) ((unsigned)BVAL(buf,pos))
-#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
+#define BSET(buf,pos,val) (((__u8 *)(buf))[pos] = (val))
 
 static inline __u16
-WVAL_LH(__u8 * buf, int pos)
+WVAL_LH(const __u8 * buf, int pos)
 {
        return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8;
 }
 static inline __u32
-DVAL_LH(__u8 * buf, int pos)
+DVAL_LH(const __u8 * buf, int pos)
 {
        return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16;
 }
index c7ff6c700a6efdca195b43a18414e221ecafc824..668bd267346e57ed80700e4b8af541ad9dd5f476 100644 (file)
@@ -746,7 +746,6 @@ static int ncp_do_request(struct ncp_server *server, int size,
                return -EIO;
        }
        if (!ncp_conn_valid(server)) {
-               printk(KERN_ERR "ncpfs: Connection invalid!\n");
                return -EIO;
        }
        {
index b9c3c43cea1def16da3d9df934fd846dd478488f..232a7eead33a488c4a5d67bc83e3a1971d9665df 100644 (file)
@@ -71,20 +71,20 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
        if (inode->i_flock == NULL)
                goto out;
 
-       /* Protect inode->i_flock using the BKL */
-       lock_kernel();
+       /* Protect inode->i_flock using the file locks lock */
+       lock_flocks();
        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
                        continue;
                if (nfs_file_open_context(fl->fl_file) != ctx)
                        continue;
-               unlock_kernel();
+               unlock_flocks();
                status = nfs4_lock_delegation_recall(state, fl);
                if (status < 0)
                        goto out;
-               lock_kernel();
+               lock_flocks();
        }
-       unlock_kernel();
+       unlock_flocks();
 out:
        return status;
 }
index 3e2f19b04c06b4b3fb0f01cb409a544054940222..96524c5dca6b8bd45fc0c845546e783d318d7e4f 100644 (file)
@@ -40,7 +40,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/fs.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_idmap.h>
 #include <linux/kthread.h>
@@ -970,13 +970,13 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
        /* Guard against delegation returns and new lock/unlock calls */
        down_write(&nfsi->rwsem);
        /* Protect inode->i_flock using the BKL */
-       lock_kernel();
+       lock_flocks();
        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
                        continue;
                if (nfs_file_open_context(fl->fl_file)->state != state)
                        continue;
-               unlock_kernel();
+               unlock_flocks();
                status = ops->recover_lock(state, fl);
                switch (status) {
                        case 0:
@@ -1003,9 +1003,9 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
                                /* kill_proc(fl->fl_pid, SIGLOST, 1); */
                                status = 0;
                }
-               lock_kernel();
+               lock_flocks();
        }
-       unlock_kernel();
+       unlock_flocks();
 out:
        up_write(&nfsi->rwsem);
        return status;
index cf0d2ffb3c84a149bc904323cd53599620c8c917..a7292fcf7718e0d1471ddcfd2dab4e3957f17e18 100644 (file)
@@ -33,7 +33,7 @@
 */
 
 #include <linux/file.h>
-#include <linux/smp_lock.h>
+#include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/swap.h>
@@ -3895,7 +3895,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
        struct inode *inode = filp->fi_inode;
        int status = 0;
 
-       lock_kernel();
+       lock_flocks();
        for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
                if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
                        status = 1;
@@ -3903,7 +3903,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
                }
        }
 out:
-       unlock_kernel();
+       unlock_flocks();
        return status;
 }
 
index f90a33d9a5b097c06038f614cbbcecb1abfab191..0442ee3b394fd7f65315482078cc4bc463f300eb 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/fs.h>
 #include <linux/wait.h>
-#include <linux/smp_lock.h>    /* lock_kernel(), unlock_kernel() */
 #include <linux/slab.h>
 #include <linux/capability.h>  /* capable() */
 #include <linux/uaccess.h>     /* copy_from_user(), copy_to_user() */
index 922263393c765664f6b5598f4c144093ec9e582c..9f4913f78408a80e5c9b1253c19ac092adecb2b2 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/parser.h>
 #include <linux/random.h>
 #include <linux/crc32.h>
-#include <linux/smp_lock.h>
 #include <linux/vfs.h>
 #include <linux/writeback.h>
 #include <linux/kobject.h>
@@ -342,8 +341,6 @@ static void nilfs_put_super(struct super_block *sb)
        struct nilfs_sb_info *sbi = NILFS_SB(sb);
        struct the_nilfs *nilfs = sbi->s_nilfs;
 
-       lock_kernel();
-
        nilfs_detach_segment_constructor(sbi);
 
        if (!(sb->s_flags & MS_RDONLY)) {
@@ -361,8 +358,6 @@ static void nilfs_put_super(struct super_block *sb)
        sbi->s_super = NULL;
        sb->s_fs_info = NULL;
        nilfs_put_sbinfo(sbi);
-
-       unlock_kernel();
 }
 
 static int nilfs_sync_fs(struct super_block *sb, int wait)
@@ -949,8 +944,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        struct nilfs_mount_options old_opts;
        int was_snapshot, err;
 
-       lock_kernel();
-
        down_write(&nilfs->ns_super_sem);
        old_sb_flags = sb->s_flags;
        old_opts.mount_opt = sbi->s_mount_opt;
@@ -1024,7 +1017,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        }
  out:
        up_write(&nilfs->ns_super_sem);
-       unlock_kernel();
        return 0;
 
  restore_opts:
@@ -1032,7 +1024,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        sbi->s_mount_opt = old_opts.mount_opt;
        sbi->s_snapshot_cno = old_opts.snapshot_cno;
        up_write(&nilfs->ns_super_sem);
-       unlock_kernel();
        return err;
 }
 
@@ -1205,7 +1196,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        put_nilfs(nilfs);
  failed:
        close_bdev_exclusive(sd.bdev, mode);
-
        return err;
 
  cancel_new:
index 512806171bfa2e2dfb73975feb60ea9560a654a7..19c5180f8a28c063b9a8cf5fefc58a6c61512455 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
 #include <linux/moduleparam.h>
-#include <linux/smp_lock.h>
 #include <linux/bitmap.h>
 
 #include "sysctl.h"
@@ -445,7 +444,6 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 
        ntfs_debug("Entering with remount options string: %s", opt);
 
-       lock_kernel();
 #ifndef NTFS_RW
        /* For read-only compiled driver, enforce read-only flag. */
        *flags |= MS_RDONLY;
@@ -469,18 +467,15 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                if (NVolErrors(vol)) {
                        ntfs_error(sb, "Volume has errors and is read-only%s",
                                        es);
-                       unlock_kernel();
                        return -EROFS;
                }
                if (vol->vol_flags & VOLUME_IS_DIRTY) {
                        ntfs_error(sb, "Volume is dirty and read-only%s", es);
-                       unlock_kernel();
                        return -EROFS;
                }
                if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
                        ntfs_error(sb, "Volume has been modified by chkdsk "
                                        "and is read-only%s", es);
-                       unlock_kernel();
                        return -EROFS;
                }
                if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
@@ -488,13 +483,11 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                                        "(0x%x) and is read-only%s",
                                        (unsigned)le16_to_cpu(vol->vol_flags),
                                        es);
-                       unlock_kernel();
                        return -EROFS;
                }
                if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
                        ntfs_error(sb, "Failed to set dirty bit in volume "
                                        "information flags%s", es);
-                       unlock_kernel();
                        return -EROFS;
                }
 #if 0
@@ -514,21 +507,18 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
                        ntfs_error(sb, "Failed to empty journal $LogFile%s",
                                        es);
                        NVolSetErrors(vol);
-                       unlock_kernel();
                        return -EROFS;
                }
                if (!ntfs_mark_quotas_out_of_date(vol)) {
                        ntfs_error(sb, "Failed to mark quotas out of date%s",
                                        es);
                        NVolSetErrors(vol);
-                       unlock_kernel();
                        return -EROFS;
                }
                if (!ntfs_stamp_usnjrnl(vol)) {
                        ntfs_error(sb, "Failed to stamp transation log "
                                        "($UsnJrnl)%s", es);
                        NVolSetErrors(vol);
-                       unlock_kernel();
                        return -EROFS;
                }
        } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
@@ -544,11 +534,9 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 
        // TODO: Deal with *flags.
 
-       if (!parse_options(vol, opt)) {
-               unlock_kernel();
+       if (!parse_options(vol, opt))
                return -EINVAL;
-       }
-       unlock_kernel();
+
        ntfs_debug("Done.");
        return 0;
 }
@@ -2261,8 +2249,6 @@ static void ntfs_put_super(struct super_block *sb)
 
        ntfs_debug("Entering.");
 
-       lock_kernel();
-
 #ifdef NTFS_RW
        /*
         * Commit all inodes while they are still open in case some of them
@@ -2433,8 +2419,6 @@ static void ntfs_put_super(struct super_block *sb)
 
        sb->s_fs_info = NULL;
        kfree(vol);
-
-       unlock_kernel();
 }
 
 /**
@@ -2772,8 +2756,6 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
        init_rwsem(&vol->mftbmp_lock);
        init_rwsem(&vol->lcnbmp_lock);
 
-       unlock_kernel();
-
        /* By default, enable sparse support. */
        NVolSetSparseEnabled(vol);
 
@@ -2940,7 +2922,6 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
                }
                mutex_unlock(&ntfs_lock);
                sb->s_export_op = &ntfs_export_ops;
-               lock_kernel();
                lockdep_on();
                return 0;
        }
@@ -3057,7 +3038,6 @@ iput_tmp_ino_err_out_now:
        }
        /* Errors at this stage are irrelevant. */
 err_out_now:
-       lock_kernel();
        sb->s_fs_info = NULL;
        kfree(vol);
        ntfs_debug("Failed, returning -EINVAL.");
index 2dc57bca0688165366364d88448d1e884ef6dd9f..0e68f542ef2e25330c55ccd26ed43991570f5226 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/reboot.h>
 #include <asm/uaccess.h>
 
@@ -612,12 +611,10 @@ static int ocfs2_control_open(struct inode *inode, struct file *file)
                return -ENOMEM;
        p->op_this_node = -1;
 
-       lock_kernel();
        mutex_lock(&ocfs2_control_lock);
        file->private_data = p;
        list_add(&p->op_list, &ocfs2_control_private_list);
        mutex_unlock(&ocfs2_control_lock);
-       unlock_kernel();
 
        return 0;
 }
index a8a0ca44f88f30d9d783301dc2a10d67df165510..56f0cb3958209b944ecb07a3a8262efc3b9aa75d 100644 (file)
@@ -630,8 +630,6 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
        struct ocfs2_super *osb = OCFS2_SB(sb);
        u32 tmp;
 
-       lock_kernel();
-
        if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
            !ocfs2_check_set_options(sb, &parsed_options)) {
                ret = -EINVAL;
@@ -739,7 +737,6 @@ unlock_osb:
                                                        MS_POSIXACL : 0);
        }
 out:
-       unlock_kernel();
        return ret;
 }
 
@@ -1696,13 +1693,9 @@ static void ocfs2_put_super(struct super_block *sb)
 {
        mlog_entry("(0x%p)\n", sb);
 
-       lock_kernel();
-
        ocfs2_sync_blockdev(sb);
        ocfs2_dismount_volume(sb, 0);
 
-       unlock_kernel();
-
        mlog_exit_void();
 }
 
index 6e8fc62b40a8c4142351ebc5c23a958c9d9b412e..7b0329468a5d9629196527039fa31771554a0494 100644 (file)
@@ -11,7 +11,6 @@
  * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support.
  */
 
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include "qnx4.h"
 
@@ -29,8 +28,6 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
        QNX4DEBUG((KERN_INFO "qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
        QNX4DEBUG((KERN_INFO "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);
@@ -71,7 +68,6 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
                brelse(bh);
        }
 out:
-       unlock_kernel();
        return 0;
 }
 
index 16829722be93658abb8a153bff2422396c02e8b0..01bad30026fc7ea1026da00bba7bd3f507e1d468 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/highuid.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
@@ -157,8 +156,6 @@ static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct super_block *sb = dentry->d_sb;
        u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
 
-       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;
@@ -168,8 +165,6 @@ static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_fsid.val[0] = (u32)id;
        buf->f_fsid.val[1] = (u32)(id >> 32);
 
-       unlock_kernel();
-
        return 0;
 }
 
@@ -283,7 +278,6 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
                goto outi;
 
        brelse(bh);
-
        return 0;
 
       outi:
index 58703ebba879e36c35824bc61bbf8669efb7ad32..275327b5615ea0c2fc8485eb7511dce6ec43c643 100644 (file)
@@ -12,7 +12,6 @@
  * 04-07-1998 by Frank Denis : first step for rmdir/unlink.
  */
 
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include "qnx4.h"
 
@@ -109,7 +108,6 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nam
        int len = dentry->d_name.len;
        struct inode *foundinode = NULL;
 
-       lock_kernel();
        if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
                goto out;
        /* The entry is linked, let's get the real info */
@@ -123,13 +121,11 @@ struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nam
 
        foundinode = qnx4_iget(dir->i_sb, ino);
        if (IS_ERR(foundinode)) {
-               unlock_kernel();
                QNX4DEBUG((KERN_ERR "qnx4: lookup->iget -> error %ld\n",
                           PTR_ERR(foundinode)));
                return ERR_CAST(foundinode);
        }
 out:
-       unlock_kernel();
        d_add(dentry, foundinode);
 
        return NULL;
index 450c9194198861483daa183fb6582e1c9790eadb..8fc5e50e142fad71ad05aa38f726ae0d6d4ca566 100644 (file)
@@ -501,6 +501,8 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        void *mem;
        static int warn_count;
 
+       lock_kernel();
+
        if (warn_count < 5) {
                warn_count++;
                printk(KERN_EMERG "smbfs is deprecated and will be removed"
@@ -621,6 +623,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
 
        smb_new_dentry(sb->s_root);
 
+       unlock_kernel();
        return 0;
 
 out_no_root:
@@ -643,9 +646,11 @@ out_wrong_data:
 out_no_data:
        printk(KERN_ERR "smb_fill_super: missing data argument\n");
 out_fail:
+       unlock_kernel();
        return -EINVAL;
 out_no_server:
        printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n");
+       unlock_kernel();
        return -ENOMEM;
 }
 
index 88b4f8606652b8e675621a2f545aff357ea176ae..07a4f115604850d77191baed3a7fd96c7d161661 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/fs.h>
 #include <linux/vfs.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
@@ -354,8 +353,6 @@ static int squashfs_remount(struct super_block *sb, int *flags, char *data)
 
 static void squashfs_put_super(struct super_block *sb)
 {
-       lock_kernel();
-
        if (sb->s_fs_info) {
                struct squashfs_sb_info *sbi = sb->s_fs_info;
                squashfs_cache_delete(sbi->block_cache);
@@ -370,8 +367,6 @@ static void squashfs_put_super(struct super_block *sb)
                kfree(sb->s_fs_info);
                sb->s_fs_info = NULL;
        }
-
-       unlock_kernel();
 }
 
 
index 65412d84a45d7c5e6e8563111c7ca4b66cec32b7..76f3d6d97b402ea14c391c46b8a924af9888cc6c 100644 (file)
@@ -1880,6 +1880,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        struct kernel_lb_addr rootdir, fileset;
        struct udf_sb_info *sbi;
 
+       lock_kernel();
+
        uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
        uopt.uid = -1;
        uopt.gid = -1;
@@ -1888,8 +1890,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        uopt.dmode = UDF_INVALID_MODE;
 
        sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
-       if (!sbi)
+       if (!sbi) {
+               unlock_kernel();
                return -ENOMEM;
+       }
 
        sb->s_fs_info = sbi;
 
@@ -2035,6 +2039,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
        sb->s_maxbytes = MAX_LFS_FILESIZE;
+       unlock_kernel();
        return 0;
 
 error_out:
@@ -2055,6 +2060,7 @@ error_out:
        kfree(sbi);
        sb->s_fs_info = NULL;
 
+       unlock_kernel();
        return -EINVAL;
 }
 
index d510c1b91817c9543ea5da4f062af0cc7eb3ae4f..6b9be90dae7dd7affc1ccba35c02bd9fac193570 100644 (file)
@@ -696,6 +696,8 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
        unsigned maxsymlen;
        int ret = -EINVAL;
 
+       lock_kernel();
+
        uspi = NULL;
        ubh = NULL;
        flags = 0;
@@ -1163,6 +1165,7 @@ magic_found:
                        goto failed;
 
        UFSD("EXIT\n");
+       unlock_kernel();
        return 0;
 
 dalloc_failed:
@@ -1174,10 +1177,12 @@ failed:
        kfree(sbi);
        sb->s_fs_info = NULL;
        UFSD("EXIT (FAILED)\n");
+       unlock_kernel();
        return ret;
 
 failed_nomem:
        UFSD("EXIT (NOMEM)\n");
+       unlock_kernel();
        return -ENOMEM;
 }
 
index 7d6f18fddfdb9241b6734eb918828dbec253a8ba..75e27a25c6e3d492ec5c083ad205be490f77bf93 100644 (file)
@@ -1093,10 +1093,6 @@ struct file_lock {
 
 #include <linux/fcntl.h>
 
-/* temporary stubs for BKL removal */
-#define lock_flocks() lock_kernel()
-#define unlock_flocks() unlock_kernel()
-
 extern void send_sigio(struct fown_struct *fown, int fd, int band);
 
 #ifdef CONFIG_FILE_LOCKING
@@ -1135,6 +1131,8 @@ extern int vfs_setlease(struct file *, long, struct file_lock **);
 extern int lease_modify(struct file_lock **, int);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
 extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
+extern void lock_flocks(void);
+extern void unlock_flocks(void);
 #else /* !CONFIG_FILE_LOCKING */
 static inline int fcntl_getlk(struct file *file, struct flock __user *user)
 {
@@ -1277,6 +1275,14 @@ static inline int lock_may_write(struct inode *inode, loff_t start,
        return 1;
 }
 
+static inline void lock_flocks(void)
+{
+}
+
+static inline void unlock_flocks(void)
+{
+}
+
 #endif /* !CONFIG_FILE_LOCKING */
 
 
index 4522aed00906c81f885eae6ed5c0ecd9f399bde8..ef663061d5ac5e3725b87ff11cc9bd3309a4db8c 100644 (file)
@@ -241,34 +241,6 @@ int ncp_mmap(struct file *, struct vm_area_struct *);
 /* linux/fs/ncpfs/ncplib_kernel.c */
 int ncp_make_closed(struct inode *);
 
-#define ncp_namespace(i)       (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
-
-static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
-{
-#ifdef CONFIG_NCPFS_SMALLDOS
-       int ns = ncp_namespace(i);
-
-       if ((ns == NW_NS_DOS)
-#ifdef CONFIG_NCPFS_OS2_NS
-               || ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS))
-#endif /* CONFIG_NCPFS_OS2_NS */
-                               )
-               return 0;
-#endif /* CONFIG_NCPFS_SMALLDOS */
-       return 1;
-}
-
-#define ncp_preserve_case(i)   (ncp_namespace(i) != NW_NS_DOS)
-
-static inline int ncp_case_sensitive(struct inode *i)
-{
-#ifdef CONFIG_NCPFS_NFS_NS
-       return ncp_namespace(i) == NW_NS_NFS;
-#else
-       return 0;
-#endif /* CONFIG_NCPFS_NFS_NS */
-} 
-
 #endif                         /* __KERNEL__ */
 
 #endif                         /* _LINUX_NCP_FS_H */
index 8da05bc098ca86b2ba5758af8b0b7885c7894dd3..d64b0e89433691bf532577a4b193781c4e0516b6 100644 (file)
@@ -62,6 +62,7 @@ struct ncp_server {
        int ncp_reply_size;
 
        int root_setuped;
+       struct mutex root_setup_lock;
 
        /* info for packet signing */
        int sign_wanted;        /* 1=Server needs signed packets */
@@ -81,13 +82,14 @@ struct ncp_server {
                size_t  len;
                void*   data;
        } priv;
+       struct rw_semaphore auth_rwsem;
 
        /* nls info: codepage for volume and charset for I/O */
        struct nls_table *nls_vol;
        struct nls_table *nls_io;
 
        /* maximum age in jiffies */
-       int dentry_ttl;
+       atomic_t dentry_ttl;
 
        /* miscellaneous */
        unsigned int flags;
index 291ba3d04beab08f0edc4a0239bae956941e50d9..7b69b8d0313d63a92bd4efaf4d07676456fe71fc 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/cgroupstats.h>
 #include <linux/hash.h>
 #include <linux/namei.h>
-#include <linux/smp_lock.h>
 #include <linux/pid_namespace.h>
 #include <linux/idr.h>
 #include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */
@@ -1222,7 +1221,6 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
        struct cgroup *cgrp = &root->top_cgroup;
        struct cgroup_sb_opts opts;
 
-       lock_kernel();
        mutex_lock(&cgrp->dentry->d_inode->i_mutex);
        mutex_lock(&cgroup_mutex);
 
@@ -1255,7 +1253,6 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
        kfree(opts.name);
        mutex_unlock(&cgroup_mutex);
        mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
-       unlock_kernel();
        return ret;
 }
 
@@ -1568,7 +1565,6 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
  out_err:
        kfree(opts.release_agent);
        kfree(opts.name);
-
        return ret;
 }