Merge branch 'vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl

* '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
  ...
This commit is contained in:
Linus Torvalds 2010-10-22 10:52:01 -07:00
commit 79f14b7c56
59 changed files with 700 additions and 720 deletions

View File

@ -33,7 +33,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>

View File

@ -352,11 +352,15 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
struct adfs_sb_info *asb; struct adfs_sb_info *asb;
struct inode *root; struct inode *root;
lock_kernel();
sb->s_flags |= MS_NODIRATIME; sb->s_flags |= MS_NODIRATIME;
asb = kzalloc(sizeof(*asb), GFP_KERNEL); asb = kzalloc(sizeof(*asb), GFP_KERNEL);
if (!asb) if (!asb) {
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
sb->s_fs_info = asb; sb->s_fs_info = asb;
/* set default options */ /* set default options */
@ -474,6 +478,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
goto error; goto error;
} else } else
sb->s_root->d_op = &adfs_dentry_operations; sb->s_root->d_op = &adfs_dentry_operations;
unlock_kernel();
return 0; return 0;
error_free_bh: error_free_bh:
@ -481,6 +486,7 @@ error_free_bh:
error: error:
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(asb); kfree(asb);
unlock_kernel();
return -EINVAL; return -EINVAL;
} }

View File

@ -16,7 +16,6 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "affs.h" #include "affs.h"
@ -46,8 +45,6 @@ affs_put_super(struct super_block *sb)
struct affs_sb_info *sbi = AFFS_SB(sb); struct affs_sb_info *sbi = AFFS_SB(sb);
pr_debug("AFFS: put_super()\n"); pr_debug("AFFS: put_super()\n");
lock_kernel();
if (!(sb->s_flags & MS_RDONLY) && sb->s_dirt) if (!(sb->s_flags & MS_RDONLY) && sb->s_dirt)
affs_commit_super(sb, 1, 1); affs_commit_super(sb, 1, 1);
@ -56,8 +53,6 @@ affs_put_super(struct super_block *sb)
affs_brelse(sbi->s_root_bh); affs_brelse(sbi->s_root_bh);
kfree(sbi); kfree(sbi);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
unlock_kernel();
} }
static void 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); sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
mutex_init(&sbi->s_bmlock); mutex_init(&sbi->s_bmlock);
spin_lock_init(&sbi->symlink_lock); spin_lock_init(&sbi->symlink_lock);
@ -527,7 +523,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
kfree(new_opts); kfree(new_opts);
return -EINVAL; return -EINVAL;
} }
lock_kernel();
replace_mount_options(sb, new_opts); replace_mount_options(sb, new_opts);
sbi->s_flags = mount_flags; 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); memcpy(sbi->s_volume, volume, 32);
spin_unlock(&sbi->symlink_lock); spin_unlock(&sbi->symlink_lock);
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
unlock_kernel();
return 0; return 0;
}
if (*flags & MS_RDONLY) { if (*flags & MS_RDONLY) {
affs_write_super(sb); affs_write_super(sb);
affs_free_bitmap(sb); affs_free_bitmap(sb);
} else } else
res = affs_init_bitmap(sb, flags); res = affs_init_bitmap(sb, flags);
unlock_kernel();
return res; return res;
} }

View File

@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <linux/smp_lock.h>
#include "internal.h" #include "internal.h"
#define AFS_LOCK_GRANTED 0 #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; 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 /* make sure we've got a callback on this file and that our view of the
* data version is up to date */ * data version is up to date */
@ -421,7 +420,7 @@ given_lock:
afs_vnode_fetch_status(vnode, NULL, key); afs_vnode_fetch_status(vnode, NULL, key);
error: error:
unlock_kernel(); unlock_flocks();
_leave(" = %d", ret); _leave(" = %d", ret);
return ret; return ret;

View File

@ -19,7 +19,6 @@
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/parser.h> #include <linux/parser.h>
@ -453,12 +452,8 @@ static void afs_put_super(struct super_block *sb)
_enter(""); _enter("");
lock_kernel();
afs_put_volume(as->volume); afs_put_volume(as->volume);
unlock_kernel();
_leave(""); _leave("");
} }

View 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_rmdir(struct inode *,struct dentry *);
static int autofs_root_mkdir(struct inode *,struct dentry *,int); static int autofs_root_mkdir(struct inode *,struct dentry *,int);
static long autofs_root_ioctl(struct file *,unsigned int,unsigned long); 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); static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);
#endif
const struct file_operations autofs_root_operations = { const struct file_operations autofs_root_operations = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,

View File

@ -19,7 +19,7 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/smp_lock.h> #include <linux/mutex.h>
#include "autofs_i.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_rmdir(struct inode *,struct dentry *);
static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long); 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); 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 int autofs4_dir_open(struct inode *inode, struct file *file);
static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
static void *autofs4_follow_link(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, static long autofs4_root_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
long ret; long ret;
struct inode *inode = filp->f_dentry->d_inode; struct inode *inode = filp->f_dentry->d_inode;
lock_kernel(); mutex_lock(&autofs4_ioctl_mutex);
ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
unlock_kernel(); mutex_unlock(&autofs4_ioctl_mutex);
return ret; return ret;
} }
@ -998,13 +1002,13 @@ static long autofs4_root_compat_ioctl(struct file *filp,
struct inode *inode = filp->f_path.dentry->d_inode; struct inode *inode = filp->f_path.dentry->d_inode;
int ret; int ret;
lock_kernel(); mutex_lock(&autofs4_ioctl_mutex);
if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
else else
ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
(unsigned long)compat_ptr(arg)); (unsigned long)compat_ptr(arg));
unlock_kernel(); mutex_unlock(&autofs4_ioctl_mutex);
return ret; return ret;
} }

View File

@ -12,7 +12,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/writeback.h> #include <linux/writeback.h>
@ -215,14 +214,10 @@ static void bfs_put_super(struct super_block *s)
if (!info) if (!info)
return; return;
lock_kernel();
mutex_destroy(&info->bfs_lock); mutex_destroy(&info->bfs_lock);
kfree(info->si_imap); kfree(info->si_imap);
kfree(info); kfree(info);
s->s_fs_info = NULL; s->s_fs_info = NULL;
unlock_kernel();
} }
static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)

View File

@ -35,7 +35,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/smp_lock.h>
#include "cifsfs.h" #include "cifsfs.h"
#include "cifspdu.h" #include "cifspdu.h"
#define DECLARE_GLOBALS_HERE #define DECLARE_GLOBALS_HERE
@ -200,8 +199,6 @@ cifs_put_super(struct super_block *sb)
return; return;
} }
lock_kernel();
rc = cifs_umount(sb, cifs_sb); rc = cifs_umount(sb, cifs_sb);
if (rc) if (rc)
cERROR(1, "cifs_umount failed with return code %d", 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); unload_nls(cifs_sb->local_nls);
bdi_destroy(&cifs_sb->bdi); bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb); kfree(cifs_sb);
unlock_kernel();
} }
static int 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 flags, const char *dev_name, void *data, struct vfsmount *mnt)
{ {
int rc; 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); 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) 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 /* note that this is called by vfs setlease with lock_flocks held
although I doubt that BKL is needed here in cifs */ to protect *lease from going away */
struct inode *inode = file->f_path.dentry->d_inode; struct inode *inode = file->f_path.dentry->d_inode;
if (!(S_ISREG(inode->i_mode))) if (!(S_ISREG(inode->i_mode)))

View File

@ -148,6 +148,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
int error; int error;
int idx; int idx;
lock_kernel();
idx = get_device_index((struct coda_mount_data *) data); idx = get_device_index((struct coda_mount_data *) data);
/* Ignore errors in data, for backward compatibility */ /* 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]; vc = &coda_comms[idx];
if (!vc->vc_inuse) { if (!vc->vc_inuse) {
printk("coda_read_super: No pseudo device\n"); printk("coda_read_super: No pseudo device\n");
unlock_kernel();
return -EINVAL; return -EINVAL;
} }
if ( vc->vc_sb ) { if ( vc->vc_sb ) {
printk("coda_read_super: Device already mounted\n"); printk("coda_read_super: Device already mounted\n");
unlock_kernel();
return -EBUSY; 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); sb->s_root = d_alloc_root(root);
if (!sb->s_root) if (!sb->s_root)
goto error; goto error;
return 0; unlock_kernel();
return 0;
error: error:
bdi_destroy(&vc->bdi); bdi_destroy(&vc->bdi);
@ -212,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
if (vc) if (vc)
vc->vc_sb = NULL; vc->vc_sb = NULL;
unlock_kernel();
return -EINVAL; return -EINVAL;
} }

View File

@ -31,7 +31,6 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/fs_stack.h> #include <linux/fs_stack.h>
#include <linux/smp_lock.h>
#include "ecryptfs_kernel.h" #include "ecryptfs_kernel.h"
/** /**
@ -284,11 +283,9 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
int rc = 0; int rc = 0;
struct file *lower_file = NULL; struct file *lower_file = NULL;
lock_kernel();
lower_file = ecryptfs_file_to_lower(file); lower_file = ecryptfs_file_to_lower(file);
if (lower_file->f_op && lower_file->f_op->fasync) if (lower_file->f_op && lower_file->f_op->fasync)
rc = lower_file->f_op->fasync(fd, lower_file, flag); rc = lower_file->f_op->fasync(fd, lower_file, flag);
unlock_kernel();
return rc; return rc;
} }

View File

@ -747,15 +747,16 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
__le32 features; __le32 features;
int err; int err;
err = -ENOMEM;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; goto failed_unlock;
sbi->s_blockgroup_lock = sbi->s_blockgroup_lock =
kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
if (!sbi->s_blockgroup_lock) { if (!sbi->s_blockgroup_lock) {
kfree(sbi); kfree(sbi);
return -ENOMEM; goto failed_unlock;
} }
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sbi->s_sb_block = sb_block; sbi->s_sb_block = sb_block;
@ -1107,6 +1108,7 @@ failed_sbi:
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock); kfree(sbi->s_blockgroup_lock);
kfree(sbi); kfree(sbi);
failed_unlock:
return ret; return ret;
} }

View File

@ -411,9 +411,6 @@ static void ext3_put_super (struct super_block * sb)
int i, err; int i, err;
dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
lock_kernel();
ext3_xattr_put_super(sb); ext3_xattr_put_super(sb);
err = journal_destroy(sbi->s_journal); err = journal_destroy(sbi->s_journal);
sbi->s_journal = NULL; sbi->s_journal = NULL;
@ -462,8 +459,6 @@ static void ext3_put_super (struct super_block * sb)
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock); kfree(sbi->s_blockgroup_lock);
kfree(sbi); kfree(sbi);
unlock_kernel();
} }
static struct kmem_cache *ext3_inode_cachep; 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_resgid = EXT3_DEF_RESGID;
sbi->s_sb_block = sb_block; sbi->s_sb_block = sb_block;
unlock_kernel();
blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE); blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
if (!blocksize) { if (!blocksize) {
ext3_msg(sb, KERN_ERR, "error: unable to set 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": test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
"writeback"); "writeback");
lock_kernel();
return 0; return 0;
cantfind_ext3: cantfind_ext3:
@ -2055,7 +2047,6 @@ out_fail:
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock); kfree(sbi->s_blockgroup_lock);
kfree(sbi); kfree(sbi);
lock_kernel();
return ret; return ret;
} }
@ -2538,8 +2529,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
int i; int i;
#endif #endif
lock_kernel();
/* Store the original options */ /* Store the original options */
lock_super(sb); lock_super(sb);
old_sb_flags = sb->s_flags; 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]); kfree(old_opts.s_qf_names[i]);
#endif #endif
unlock_super(sb); unlock_super(sb);
unlock_kernel();
if (enable_quota) if (enable_quota)
dquot_resume(sb, -1); dquot_resume(sb, -1);
@ -2669,7 +2657,6 @@ restore_opts:
} }
#endif #endif
unlock_super(sb); unlock_super(sb);
unlock_kernel();
return err; return err;
} }

View File

@ -26,7 +26,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/exportfs.h> #include <linux/exportfs.h>
#include <linux/vfs.h> #include <linux/vfs.h>
@ -708,7 +707,6 @@ static void ext4_put_super(struct super_block *sb)
destroy_workqueue(sbi->dio_unwritten_wq); destroy_workqueue(sbi->dio_unwritten_wq);
lock_super(sb); lock_super(sb);
lock_kernel();
if (sb->s_dirt) if (sb->s_dirt)
ext4_commit_super(sb, 1); 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 * Now that we are completely done shutting down the
* superblock, we need to actually destroy the kobject. * superblock, we need to actually destroy the kobject.
*/ */
unlock_kernel();
unlock_super(sb); unlock_super(sb);
kobject_put(&sbi->s_kobj); kobject_put(&sbi->s_kobj);
wait_for_completion(&sbi->s_kobj_unregister); 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 = sbi->s_sectors_written_start =
part_stat_read(sb->s_bdev->bd_part, sectors[1]); part_stat_read(sb->s_bdev->bd_part, sectors[1]);
unlock_kernel();
/* Cleanup superblock name */ /* Cleanup superblock name */
for (cp = sb->s_id; (cp = strchr(cp, '/'));) for (cp = sb->s_id; (cp = strchr(cp, '/'));)
*cp = '!'; *cp = '!';
@ -3164,7 +3159,6 @@ no_journal:
if (es->s_error_count) if (es->s_error_count)
mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */ mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */
lock_kernel();
kfree(orig_data); kfree(orig_data);
return 0; return 0;
@ -3211,7 +3205,6 @@ out_fail:
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock); kfree(sbi->s_blockgroup_lock);
kfree(sbi); kfree(sbi);
lock_kernel();
out_free_orig: out_free_orig:
kfree(orig_data); kfree(orig_data);
return ret; return ret;
@ -3720,8 +3713,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
#endif #endif
char *orig_data = kstrdup(data, GFP_KERNEL); char *orig_data = kstrdup(data, GFP_KERNEL);
lock_kernel();
/* Store the original options */ /* Store the original options */
lock_super(sb); lock_super(sb);
old_sb_flags = sb->s_flags; 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]); kfree(old_opts.s_qf_names[i]);
#endif #endif
unlock_super(sb); unlock_super(sb);
unlock_kernel();
if (enable_quota) if (enable_quota)
dquot_resume(sb, -1); dquot_resume(sb, -1);
@ -3882,7 +3872,6 @@ restore_opts:
} }
#endif #endif
unlock_super(sb); unlock_super(sb);
unlock_kernel();
kfree(orig_data); kfree(orig_data);
return err; return err;
} }

View File

@ -14,7 +14,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/mpage.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); struct msdos_sb_info *sbi = MSDOS_SB(sb);
lock_kernel();
if (sb->s_dirt) if (sb->s_dirt)
fat_write_super(sb); fat_write_super(sb);
@ -504,8 +501,6 @@ static void fat_put_super(struct super_block *sb)
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sbi); kfree(sbi);
unlock_kernel();
} }
static struct kmem_cache *fat_inode_cachep; static struct kmem_cache *fat_inode_cachep;

View File

@ -662,12 +662,16 @@ static int msdos_fill_super(struct super_block *sb, void *data, int silent)
{ {
int res; int res;
lock_super(sb);
res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0); res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0);
if (res) if (res) {
unlock_super(sb);
return res; return res;
}
sb->s_flags |= MS_NOATIME; sb->s_flags |= MS_NOATIME;
sb->s_root->d_op = &msdos_dentry_operations; sb->s_root->d_op = &msdos_dentry_operations;
unlock_super(sb);
return 0; return 0;
} }

View File

@ -1055,15 +1055,19 @@ static int vfat_fill_super(struct super_block *sb, void *data, int silent)
{ {
int res; int res;
lock_super(sb);
res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1); res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1);
if (res) if (res) {
unlock_super(sb);
return res; return res;
}
if (MSDOS_SB(sb)->options.name_check != 's') if (MSDOS_SB(sb)->options.name_check != 's')
sb->s_root->d_op = &vfat_ci_dentry_ops; sb->s_root->d_op = &vfat_ci_dentry_ops;
else else
sb->s_root->d_op = &vfat_dentry_ops; sb->s_root->d_op = &vfat_dentry_ops;
unlock_super(sb);
return 0; return 0;
} }

View File

@ -36,7 +36,6 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include "vxfs.h" #include "vxfs.h"
#include "vxfs_dir.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) if (dp->d_name.len > VXFS_NAMELEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel();
ino = vxfs_inode_by_name(dip, dp); ino = vxfs_inode_by_name(dip, dp);
if (ino) { if (ino) {
ip = vxfs_iget(dip->i_sb, ino); ip = vxfs_iget(dip->i_sb, ino);
if (IS_ERR(ip)) { if (IS_ERR(ip))
unlock_kernel();
return ERR_CAST(ip); return ERR_CAST(ip);
}
} }
unlock_kernel();
d_add(dp, ip); d_add(dp, ip);
return NULL; return NULL;
} }
@ -248,8 +243,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
u_long page, npages, block, pblocks, nblocks, offset; u_long page, npages, block, pblocks, nblocks, offset;
loff_t pos; loff_t pos;
lock_kernel();
switch ((long)fp->f_pos) { switch ((long)fp->f_pos) {
case 0: case 0:
if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 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; pos = fp->f_pos - 2;
if (pos > VXFS_DIRROUND(ip->i_size)) { if (pos > VXFS_DIRROUND(ip->i_size))
unlock_kernel();
return 0; return 0;
}
npages = dir_pages(ip); npages = dir_pages(ip);
nblocks = dir_blocks(ip); nblocks = dir_blocks(ip);
@ -327,6 +318,5 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
done: done:
fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2; fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
out: out:
unlock_kernel();
return 0; return 0;
} }

View File

@ -38,7 +38,6 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/mount.h> #include <linux/mount.h>
@ -81,16 +80,12 @@ vxfs_put_super(struct super_block *sbp)
{ {
struct vxfs_sb_info *infp = VXFS_SBI(sbp); struct vxfs_sb_info *infp = VXFS_SBI(sbp);
lock_kernel();
vxfs_put_fake_inode(infp->vsi_fship); vxfs_put_fake_inode(infp->vsi_fship);
vxfs_put_fake_inode(infp->vsi_ilist); vxfs_put_fake_inode(infp->vsi_ilist);
vxfs_put_fake_inode(infp->vsi_stilist); vxfs_put_fake_inode(infp->vsi_stilist);
brelse(infp->vsi_bp); brelse(infp->vsi_bp);
kfree(infp); 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. * The superblock on success, else %NULL.
* *
* Locking: * 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) static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
{ {

View 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), * cluster; until we do, disable leases (by just returning -EINVAL),
* unless the administrator has requested purely local locking. * unless the administrator has requested purely local locking.
* *
* Locking: called under lock_flocks
*
* Returns: errno * Returns: errno
*/ */

View File

@ -20,7 +20,6 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include "hfs_fs.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) static void hfs_put_super(struct super_block *sb)
{ {
lock_kernel();
if (sb->s_dirt) if (sb->s_dirt)
hfs_write_super(sb); hfs_write_super(sb);
hfs_mdb_close(sb); hfs_mdb_close(sb);
/* release the MDB's resources */ /* release the MDB's resources */
hfs_mdb_put(sb); 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); sbi = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
INIT_HLIST_HEAD(&sbi->rsrc_inodes); INIT_HLIST_HEAD(&sbi->rsrc_inodes);

View File

@ -477,11 +477,15 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
int o; int o;
lock_kernel();
save_mount_options(s, options); save_mount_options(s, options);
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi) {
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
s->s_fs_info = sbi; s->s_fs_info = sbi;
sbi->sb_bmp_dir = NULL; 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; root->i_blocks = 5;
hpfs_brelse4(&qbh); hpfs_brelse4(&qbh);
} }
unlock_kernel();
return 0; return 0;
bail4: brelse(bh2); bail4: brelse(bh2);
@ -677,6 +682,7 @@ bail0:
kfree(sbi->sb_cp_table); kfree(sbi->sb_cp_table);
s->s_fs_info = NULL; s->s_fs_info = NULL;
kfree(sbi); kfree(sbi);
unlock_kernel();
return -EINVAL; return -EINVAL;
} }

View File

@ -10,7 +10,6 @@
* *
* isofs directory handling functions * isofs directory handling functions
*/ */
#include <linux/smp_lock.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include "isofs.h" #include "isofs.h"
@ -255,18 +254,19 @@ static int isofs_readdir(struct file *filp,
char *tmpname; char *tmpname;
struct iso_directory_record *tmpde; struct iso_directory_record *tmpde;
struct inode *inode = filp->f_path.dentry->d_inode; 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); tmpname = (char *)__get_free_page(GFP_KERNEL);
if (tmpname == NULL) if (tmpname == NULL)
return -ENOMEM; return -ENOMEM;
lock_kernel(); mutex_lock(&sbi->s_mutex);
tmpde = (struct iso_directory_record *) (tmpname+1024); tmpde = (struct iso_directory_record *) (tmpname+1024);
result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde); result = do_isofs_readdir(inode, filp, dirent, filldir, tmpname, tmpde);
free_page((unsigned long) tmpname); free_page((unsigned long) tmpname);
unlock_kernel(); mutex_unlock(&sbi->s_mutex);
return result; return result;
} }

View File

@ -17,7 +17,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/nls.h> #include <linux/nls.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/smp_lock.h>
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/parser.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); struct isofs_sb_info *sbi = ISOFS_SB(sb);
#ifdef CONFIG_JOLIET #ifdef CONFIG_JOLIET
lock_kernel();
unload_nls(sbi->s_nls_iocharset); unload_nls(sbi->s_nls_iocharset);
unlock_kernel();
#endif #endif
kfree(sbi); kfree(sbi);
@ -823,6 +818,7 @@ root_found:
sbi->s_utf8 = opt.utf8; sbi->s_utf8 = opt.utf8;
sbi->s_nocompress = opt.nocompress; sbi->s_nocompress = opt.nocompress;
sbi->s_overriderockperm = opt.overriderockperm; sbi->s_overriderockperm = opt.overriderockperm;
mutex_init(&sbi->s_mutex);
/* /*
* It would be incredibly stupid to allow people to mark every file * 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 * 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; int section, rv, error;
struct iso_inode_info *ei = ISOFS_I(inode); struct iso_inode_info *ei = ISOFS_I(inode);
lock_kernel();
error = -EIO; error = -EIO;
rv = 0; rv = 0;
if (iblock < 0 || iblock != iblock_s) { if (iblock < 0 || iblock != iblock_s) {
@ -1054,7 +1048,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
error = 0; error = 0;
abort: abort:
unlock_kernel();
return rv != 0 ? rv : error; return rv != 0 ? rv : error;
} }

View File

@ -55,6 +55,7 @@ struct isofs_sb_info {
gid_t s_gid; gid_t s_gid;
uid_t s_uid; uid_t s_uid;
struct nls_table *s_nls_iocharset; /* Native language support table */ 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) #define ISOFS_INVALID_MODE ((mode_t) -1)

View File

@ -6,7 +6,6 @@
* (C) 1991 Linus Torvalds - minix filesystem * (C) 1991 Linus Torvalds - minix filesystem
*/ */
#include <linux/smp_lock.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include "isofs.h" #include "isofs.h"
@ -168,6 +167,7 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
int found; int found;
unsigned long uninitialized_var(block); unsigned long uninitialized_var(block);
unsigned long uninitialized_var(offset); unsigned long uninitialized_var(offset);
struct isofs_sb_info *sbi = ISOFS_SB(dir->i_sb);
struct inode *inode; struct inode *inode;
struct page *page; struct page *page;
@ -177,7 +177,7 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
if (!page) if (!page)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
lock_kernel(); mutex_lock(&sbi->s_mutex);
found = isofs_find_entry(dir, dentry, found = isofs_find_entry(dir, dentry,
&block, &offset, &block, &offset,
page_address(page), page_address(page),
@ -188,10 +188,10 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nam
if (found) { if (found) {
inode = isofs_iget(dir->i_sb, block, offset); inode = isofs_iget(dir->i_sb, block, offset);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
unlock_kernel(); mutex_unlock(&sbi->s_mutex);
return ERR_CAST(inode); return ERR_CAST(inode);
} }
} }
unlock_kernel(); mutex_unlock(&sbi->s_mutex);
return d_splice_alias(inode, dentry); return d_splice_alias(inode, dentry);
} }

View File

@ -8,7 +8,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include "isofs.h" #include "isofs.h"
#include "rock.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 inode *inode = page->mapping->host;
struct iso_inode_info *ei = ISOFS_I(inode); struct iso_inode_info *ei = ISOFS_I(inode);
struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb);
char *link = kmap(page); char *link = kmap(page);
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
struct buffer_head *bh; struct buffer_head *bh;
@ -673,12 +673,12 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
struct rock_state rs; struct rock_state rs;
int ret; int ret;
if (!ISOFS_SB(inode->i_sb)->s_rock) if (!sbi->s_rock)
goto error; goto error;
init_rock_state(&rs, inode); init_rock_state(&rs, inode);
block = ei->i_iget5_block; block = ei->i_iget5_block;
lock_kernel(); mutex_lock(&sbi->s_mutex);
bh = sb_bread(inode->i_sb, block); bh = sb_bread(inode->i_sb, block);
if (!bh) if (!bh)
goto out_noread; goto out_noread;
@ -748,7 +748,7 @@ repeat:
goto fail; goto fail;
brelse(bh); brelse(bh);
*rpnt = '\0'; *rpnt = '\0';
unlock_kernel(); mutex_unlock(&sbi->s_mutex);
SetPageUptodate(page); SetPageUptodate(page);
kunmap(page); kunmap(page);
unlock_page(page); unlock_page(page);
@ -765,7 +765,7 @@ out_bad_span:
printk("symlink spans iso9660 blocks\n"); printk("symlink spans iso9660 blocks\n");
fail: fail:
brelse(bh); brelse(bh);
unlock_kernel(); mutex_unlock(&sbi->s_mutex);
error: error:
SetPageError(page); SetPageError(page);
kunmap(page); kunmap(page);

View File

@ -21,7 +21,6 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/smp_lock.h>
#include "nodelist.h" #include "nodelist.h"
static int jffs2_flash_setup(struct jffs2_sb_info *c); 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 This also catches the case where it was stopped and this
is just a remount to restart it. is just a remount to restart it.
Flush the writebuffer, if neccecary, else we loose it */ Flush the writebuffer, if neccecary, else we loose it */
lock_kernel();
if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->s_flags & MS_RDONLY)) {
jffs2_stop_garbage_collect_thread(c); jffs2_stop_garbage_collect_thread(c);
mutex_lock(&c->alloc_sem); 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); jffs2_start_garbage_collect_thread(c);
*flags |= MS_NOATIME; *flags |= MS_NOATIME;
unlock_kernel();
return 0; return 0;
} }

View File

@ -12,7 +12,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/fs.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) static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct jffs2_sb_info *c; struct jffs2_sb_info *c;
int ret;
D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():" D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():"
" New superblock for device %d (\"%s\")\n", " 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 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
sb->s_flags |= MS_POSIXACL; sb->s_flags |= MS_POSIXACL;
#endif #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, 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")); D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
lock_kernel();
if (sb->s_dirt) if (sb->s_dirt)
jffs2_write_super(sb); jffs2_write_super(sb);
@ -215,8 +214,6 @@ static void jffs2_put_super (struct super_block *sb)
if (c->mtd->sync) if (c->mtd->sync)
c->mtd->sync(c->mtd); c->mtd->sync(c->mtd);
unlock_kernel();
D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
} }

View File

@ -33,7 +33,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_filsys.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); dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
lock_kernel();
rc = jfs_umount(sb); rc = jfs_umount(sb);
if (rc) if (rc)
jfs_err("jfs_umount failed with return code %d", 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); iput(sbi->direct_inode);
kfree(sbi); kfree(sbi);
unlock_kernel();
} }
enum { enum {
@ -369,19 +364,16 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
if (!parse_options(data, sb, &newLVSize, &flag)) { if (!parse_options(data, sb, &newLVSize, &flag)) {
return -EINVAL; return -EINVAL;
} }
lock_kernel();
if (newLVSize) { if (newLVSize) {
if (sb->s_flags & MS_RDONLY) { if (sb->s_flags & MS_RDONLY) {
printk(KERN_ERR printk(KERN_ERR
"JFS: resize requires volume to be mounted read-write\n"); "JFS: resize requires volume to be mounted read-write\n");
unlock_kernel();
return -EROFS; return -EROFS;
} }
rc = jfs_extendfs(sb, newLVSize, 0); rc = jfs_extendfs(sb, newLVSize, 0);
if (rc) { if (rc)
unlock_kernel();
return rc; return rc;
}
} }
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { 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 */ /* mark the fs r/w for quota activity */
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
unlock_kernel();
dquot_resume(sb, -1); dquot_resume(sb, -1);
return ret; return ret;
} }
if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
rc = dquot_suspend(sb, -1); rc = dquot_suspend(sb, -1);
if (rc < 0) { if (rc < 0) {
unlock_kernel();
return rc; return rc;
} }
rc = jfs_umount_rw(sb); rc = jfs_umount_rw(sb);
JFS_SBI(sb)->flag = flag; JFS_SBI(sb)->flag = flag;
unlock_kernel();
return rc; return rc;
} }
if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY)) if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->s_flags & MS_RDONLY)) {
rc = jfs_umount_rw(sb); rc = jfs_umount_rw(sb);
if (rc) { if (rc)
unlock_kernel();
return rc; return rc;
}
JFS_SBI(sb)->flag = flag; JFS_SBI(sb)->flag = flag;
ret = jfs_mount_rw(sb, 1); ret = jfs_mount_rw(sb, 1);
unlock_kernel();
return ret; return ret;
} }
JFS_SBI(sb)->flag = flag; JFS_SBI(sb)->flag = flag;
unlock_kernel();
return 0; 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); sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sbi->sb = sb; sbi->sb = sb;
sbi->uid = sbi->gid = sbi->umask = -1; sbi->uid = sbi->gid = sbi->umask = -1;

View File

@ -143,6 +143,22 @@ int lease_break_time = 45;
static LIST_HEAD(file_lock_list); static LIST_HEAD(file_lock_list);
static LIST_HEAD(blocked_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; static struct kmem_cache *filelock_cache __read_mostly;
/* Allocate an empty lock structure. */ /* 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) static void locks_delete_block(struct file_lock *waiter)
{ {
lock_kernel(); lock_flocks();
__locks_delete_block(waiter); __locks_delete_block(waiter);
unlock_kernel(); unlock_flocks();
} }
/* Insert waiter into blocker's block list. /* 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; struct file_lock *cfl;
lock_kernel(); lock_flocks();
for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
if (!IS_POSIX(cfl)) if (!IS_POSIX(cfl))
continue; continue;
@ -657,7 +673,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
fl->fl_pid = pid_vnr(cfl->fl_nspid); fl->fl_pid = pid_vnr(cfl->fl_nspid);
} else } else
fl->fl_type = F_UNLCK; fl->fl_type = F_UNLCK;
unlock_kernel(); unlock_flocks();
return; return;
} }
EXPORT_SYMBOL(posix_test_lock); 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 error = 0;
int found = 0; int found = 0;
lock_kernel(); if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) {
new_fl = locks_alloc_lock();
if (!new_fl)
return -ENOMEM;
}
lock_flocks();
if (request->fl_flags & FL_ACCESS) if (request->fl_flags & FL_ACCESS)
goto find_conflict; goto find_conflict;
if (request->fl_type != F_UNLCK) {
error = -ENOMEM;
new_fl = locks_alloc_lock();
if (new_fl == NULL)
goto out;
error = 0;
}
for_each_lock(inode, before) { for_each_lock(inode, before) {
struct file_lock *fl = *before; struct file_lock *fl = *before;
if (IS_POSIX(fl)) 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, * If a higher-priority process was blocked on the old file lock,
* give it the opportunity to lock the file. * give it the opportunity to lock the file.
*/ */
if (found) if (found) {
unlock_flocks();
cond_resched(); cond_resched();
lock_flocks();
}
find_conflict: find_conflict:
for_each_lock(inode, before) { for_each_lock(inode, before) {
@ -794,7 +811,7 @@ find_conflict:
error = 0; error = 0;
out: out:
unlock_kernel(); unlock_flocks();
if (new_fl) if (new_fl)
locks_free_lock(new_fl); locks_free_lock(new_fl);
return error; return error;
@ -823,7 +840,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
new_fl2 = locks_alloc_lock(); new_fl2 = locks_alloc_lock();
} }
lock_kernel(); lock_flocks();
if (request->fl_type != F_UNLCK) { if (request->fl_type != F_UNLCK) {
for_each_lock(inode, before) { for_each_lock(inode, before) {
fl = *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); locks_wake_up_blocks(left);
} }
out: out:
unlock_kernel(); unlock_flocks();
/* /*
* Free any unused locks. * 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. * 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) { for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!IS_POSIX(fl)) if (!IS_POSIX(fl))
continue; continue;
if (fl->fl_owner != owner) if (fl->fl_owner != owner)
break; break;
} }
unlock_kernel(); unlock_flocks();
return fl ? -EAGAIN : 0; 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); new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
lock_kernel(); lock_flocks();
time_out_leases(inode); time_out_leases(inode);
@ -1247,8 +1264,10 @@ restart:
break_time++; break_time++;
} }
locks_insert_block(flock, new_fl); locks_insert_block(flock, new_fl);
unlock_flocks();
error = wait_event_interruptible_timeout(new_fl->fl_wait, error = wait_event_interruptible_timeout(new_fl->fl_wait,
!new_fl->fl_next, break_time); !new_fl->fl_next, break_time);
lock_flocks();
__locks_delete_block(new_fl); __locks_delete_block(new_fl);
if (error >= 0) { if (error >= 0) {
if (error == 0) if (error == 0)
@ -1263,7 +1282,7 @@ restart:
} }
out: out:
unlock_kernel(); unlock_flocks();
if (!IS_ERR(new_fl)) if (!IS_ERR(new_fl))
locks_free_lock(new_fl); locks_free_lock(new_fl);
return error; return error;
@ -1319,7 +1338,7 @@ int fcntl_getlease(struct file *filp)
struct file_lock *fl; struct file_lock *fl;
int type = F_UNLCK; int type = F_UNLCK;
lock_kernel(); lock_flocks();
time_out_leases(filp->f_path.dentry->d_inode); time_out_leases(filp->f_path.dentry->d_inode);
for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl); for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl);
fl = fl->fl_next) { fl = fl->fl_next) {
@ -1328,7 +1347,7 @@ int fcntl_getlease(struct file *filp)
break; break;
} }
} }
unlock_kernel(); unlock_flocks();
return type; return type;
} }
@ -1341,7 +1360,7 @@ int fcntl_getlease(struct file *filp)
* The (input) flp->fl_lmops->fl_break function is required * The (input) flp->fl_lmops->fl_break function is required
* by break_lease(). * 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) int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
{ {
@ -1436,7 +1455,15 @@ out:
} }
EXPORT_SYMBOL(generic_setlease); 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 * vfs_setlease - sets a lease on an open file
* @filp: file pointer * @filp: file pointer
* @arg: type of lease to obtain * @arg: type of lease to obtain
@ -1467,12 +1494,9 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
{ {
int error; int error;
lock_kernel(); lock_flocks();
if (filp->f_op && filp->f_op->setlease) error = __vfs_setlease(filp, arg, lease);
error = filp->f_op->setlease(filp, arg, lease); unlock_flocks();
else
error = generic_setlease(filp, arg, lease);
unlock_kernel();
return error; return error;
} }
@ -1499,9 +1523,9 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
if (error) if (error)
return error; return error;
lock_kernel(); lock_flocks();
error = vfs_setlease(filp, arg, &flp); error = __vfs_setlease(filp, arg, &flp);
if (error || arg == F_UNLCK) if (error || arg == F_UNLCK)
goto out_unlock; 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); error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
out_unlock: out_unlock:
unlock_kernel(); unlock_flocks();
return error; return error;
} }
@ -2020,7 +2044,7 @@ void locks_remove_flock(struct file *filp)
fl.fl_ops->fl_release_private(&fl); fl.fl_ops->fl_release_private(&fl);
} }
lock_kernel(); lock_flocks();
before = &inode->i_flock; before = &inode->i_flock;
while ((fl = *before) != NULL) { while ((fl = *before) != NULL) {
@ -2038,7 +2062,7 @@ void locks_remove_flock(struct file *filp)
} }
before = &fl->fl_next; 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; int status = 0;
lock_kernel(); lock_flocks();
if (waiter->fl_next) if (waiter->fl_next)
__locks_delete_block(waiter); __locks_delete_block(waiter);
else else
status = -ENOENT; status = -ENOENT;
unlock_kernel(); unlock_flocks();
return status; 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) static void *locks_start(struct seq_file *f, loff_t *pos)
{ {
lock_kernel(); lock_flocks();
f->private = (void *)1; f->private = (void *)1;
return seq_list_start(&file_lock_list, *pos); 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) static void locks_stop(struct seq_file *f, void *v)
{ {
unlock_kernel(); unlock_flocks();
} }
static const struct seq_operations locks_seq_operations = { 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; struct file_lock *fl;
int result = 1; int result = 1;
lock_kernel(); lock_flocks();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (IS_POSIX(fl)) { if (IS_POSIX(fl)) {
if (fl->fl_type == F_RDLCK) 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; result = 0;
break; break;
} }
unlock_kernel(); unlock_flocks();
return result; return result;
} }
@ -2271,7 +2295,7 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
{ {
struct file_lock *fl; struct file_lock *fl;
int result = 1; int result = 1;
lock_kernel(); lock_flocks();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (IS_POSIX(fl)) { if (IS_POSIX(fl)) {
if ((fl->fl_end < start) || (fl->fl_start > (start + len))) 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; result = 0;
break; break;
} }
unlock_kernel(); unlock_flocks();
return result; return result;
} }

View File

@ -1744,9 +1744,7 @@ static int do_new_mount(struct path *path, char *type, int flags,
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
lock_kernel();
mnt = do_kern_mount(type, flags, name, data); mnt = do_kern_mount(type, flags, name, data);
unlock_kernel();
if (IS_ERR(mnt)) if (IS_ERR(mnt))
return PTR_ERR(mnt); return PTR_ERR(mnt);

View 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 * Note: leave the hash unchanged if the directory
* is case-sensitive. * is case-sensitive.
@ -102,13 +130,12 @@ const struct dentry_operations ncp_root_dentry_operations =
static int static int
ncp_hash_dentry(struct dentry *dentry, struct qstr *this) ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
{ {
struct nls_table *t; if (!ncp_case_sensitive(dentry)) {
unsigned long hash; struct nls_table *t;
int i; unsigned long hash;
int i;
t = NCP_IO_TABLE(dentry); t = NCP_IO_TABLE(dentry);
if (!ncp_case_sensitive(dentry->d_inode)) {
hash = init_name_hash(); hash = init_name_hash();
for (i=0; i<this->len ; i++) for (i=0; i<this->len ; i++)
hash = partial_name_hash(ncp_tolower(t, this->name[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) if (a->len != b->len)
return 1; return 1;
if (ncp_case_sensitive(dentry->d_inode)) if (ncp_case_sensitive(dentry))
return strncmp(a->name, b->name, a->len); return strncmp(a->name, b->name, a->len);
return ncp_strnicmp(NCP_IO_TABLE(dentry), 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 static int
__ncp_lookup_validate(struct dentry *dentry) ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd)
{ {
struct ncp_server *server; struct ncp_server *server;
struct dentry *parent; struct dentry *parent;
@ -283,9 +310,6 @@ __ncp_lookup_validate(struct dentry *dentry)
server = NCP_SERVER(dir); server = NCP_SERVER(dir);
if (!ncp_conn_valid(server))
goto finished;
/* /*
* Inspired by smbfs: * Inspired by smbfs:
* The default validation is based on dentry age: * The default validation is based on dentry age:
@ -304,8 +328,11 @@ __ncp_lookup_validate(struct dentry *dentry)
if (ncp_is_server_root(dir)) { if (ncp_is_server_root(dir)) {
res = ncp_io2vol(server, __name, &len, dentry->d_name.name, res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
dentry->d_name.len, 1); dentry->d_name.len, 1);
if (!res) if (!res) {
res = ncp_lookup_volume(server, __name, &(finfo.i)); res = ncp_lookup_volume(server, __name, &(finfo.i));
if (!res)
ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
}
} else { } else {
res = ncp_io2vol(server, __name, &len, dentry->d_name.name, res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
dentry->d_name.len, !ncp_preserve_case(dir)); 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. * what we remember, it's not valid any more.
*/ */
if (!res) { 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); ncp_new_dentry(dentry);
val=1; val=1;
} else } else
DDPRINTK("ncp_lookup_validate: found, but dirEntNum changed\n"); 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: finished:
@ -335,16 +366,6 @@ finished:
return val; 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 * static struct dentry *
ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) 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; int result, mtime_valid = 0;
time_t mtime = 0; time_t mtime = 0;
lock_kernel();
ctl.page = NULL; ctl.page = NULL;
ctl.cache = NULL; ctl.cache = NULL;
@ -421,6 +440,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
(int) filp->f_pos); (int) filp->f_pos);
result = -EIO; result = -EIO;
/* Do not generate '.' and '..' when server is dead. */
if (!ncp_conn_valid(server)) if (!ncp_conn_valid(server))
goto out; goto out;
@ -532,6 +552,12 @@ read_really:
ctl.head.end = ctl.fpos - 1; ctl.head.end = ctl.fpos - 1;
ctl.head.eof = ctl.valid; ctl.head.eof = ctl.valid;
finished: finished:
if (ctl.page) {
kunmap(ctl.page);
SetPageUptodate(ctl.page);
unlock_page(ctl.page);
page_cache_release(ctl.page);
}
if (page) { if (page) {
cache->head = ctl.head; cache->head = ctl.head;
kunmap(page); kunmap(page);
@ -539,23 +565,17 @@ finished:
unlock_page(page); unlock_page(page);
page_cache_release(page); page_cache_release(page);
} }
if (ctl.page) {
kunmap(ctl.page);
SetPageUptodate(ctl.page);
unlock_page(ctl.page);
page_cache_release(ctl.page);
}
out: out:
unlock_kernel();
return result; return result;
} }
static int static int
ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 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 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 ncp_cache_control ctl = *ctrl;
struct qstr qname; struct qstr qname;
int valid = 0; int valid = 0;
@ -564,9 +584,9 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
__u8 __name[NCP_MAXPATHLEN + 1]; __u8 __name[NCP_MAXPATHLEN + 1];
qname.len = sizeof(__name); 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, 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 */ return 1; /* I'm not sure */
qname.name = __name; qname.name = __name;
@ -584,22 +604,64 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
goto end_advance; goto end_advance;
} else { } else {
hashed = 1; 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) { if (!newdent->d_inode) {
struct inode *inode;
entry->opened = 0; entry->opened = 0;
entry->ino = iunique(inode->i_sb, 2); entry->ino = iunique(dir->i_sb, 2);
newino = ncp_iget(inode->i_sb, entry); inode = ncp_iget(dir->i_sb, entry);
if (newino) { if (inode) {
newdent->d_op = &ncp_dentry_operations; newdent->d_op = &ncp_dentry_operations;
d_instantiate(newdent, newino); d_instantiate(newdent, inode);
if (!hashed) if (!hashed)
d_rehash(newdent); d_rehash(newdent);
} }
} else } else {
ncp_update_inode2(newdent->d_inode, entry); 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) { if (newdent->d_inode) {
ino = newdent->d_inode->i_ino; 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.cache = NULL;
ctl.idx -= NCP_DIRCACHE_SIZE; ctl.idx -= NCP_DIRCACHE_SIZE;
ctl.ofs += 1; 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) if (ctl.page)
ctl.cache = kmap(ctl.page); ctl.cache = kmap(ctl.page);
} }
@ -633,7 +695,7 @@ end_advance:
if (!ino) if (!ino)
ino = find_inode_number(dentry, &qname); ino = find_inode_number(dentry, &qname);
if (!ino) if (!ino)
ino = iunique(inode->i_sb, 2); ino = iunique(dir->i_sb, 2);
ctl.filled = filldir(dirent, qname.name, qname.len, ctl.filled = filldir(dirent, qname.name, qname.len,
filp->f_pos, ino, DT_UNKNOWN); filp->f_pos, ino, DT_UNKNOWN);
if (!ctl.filled) if (!ctl.filled)
@ -660,6 +722,7 @@ ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir,
(unsigned long) filp->f_pos); (unsigned long) filp->f_pos);
for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) { for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) {
int inval_dentry;
if (ncp_get_volume_info_with_number(server, i, &info) != 0) if (ncp_get_volume_info_with_number(server, i, &info) != 0)
return; return;
@ -675,8 +738,9 @@ ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir,
info.volume_name); info.volume_name);
continue; continue;
} }
inval_dentry = ncp_update_known_namespace(server, entry.i.volNumber, NULL);
entry.volume = entry.i.volNumber; 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; return;
} }
} }
@ -739,7 +803,7 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
rpl += onerpl; rpl += onerpl;
rpls -= onerpl; rpls -= onerpl;
entry.volume = entry.i.volNumber; 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; break;
} }
} while (more); } while (more);
@ -775,17 +839,19 @@ int ncp_conn_logged_in(struct super_block *sb)
if (dent) { if (dent) {
struct inode* ino = dent->d_inode; struct inode* ino = dent->d_inode;
if (ino) { if (ino) {
ncp_update_known_namespace(server, volNumber, NULL);
NCP_FINFO(ino)->volNumber = volNumber; NCP_FINFO(ino)->volNumber = volNumber;
NCP_FINFO(ino)->dirEntNum = dirEntNum; NCP_FINFO(ino)->dirEntNum = dirEntNum;
NCP_FINFO(ino)->DosDirNum = DosDirNum; NCP_FINFO(ino)->DosDirNum = DosDirNum;
result = 0;
} else { } else {
DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n"); DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n");
} }
} else { } else {
DPRINTK("ncpfs: sb->s_root == NULL!\n"); DPRINTK("ncpfs: sb->s_root == NULL!\n");
} }
} } else
result = 0; result = 0;
out: out:
return result; return result;
@ -799,7 +865,6 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc
int error, res, len; int error, res, len;
__u8 __name[NCP_MAXPATHLEN + 1]; __u8 __name[NCP_MAXPATHLEN + 1];
lock_kernel();
error = -EIO; error = -EIO;
if (!ncp_conn_valid(server)) if (!ncp_conn_valid(server))
goto finished; goto finished;
@ -813,6 +878,8 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc
dentry->d_name.len, 1); dentry->d_name.len, 1);
if (!res) if (!res)
res = ncp_lookup_volume(server, __name, &(finfo.i)); res = ncp_lookup_volume(server, __name, &(finfo.i));
if (!res)
ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
} else { } else {
res = ncp_io2vol(server, __name, &len, dentry->d_name.name, res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
dentry->d_name.len, !ncp_preserve_case(dir)); dentry->d_name.len, !ncp_preserve_case(dir));
@ -846,7 +913,6 @@ add_entry:
finished: finished:
PPRINTK("ncp_lookup: result=%d\n", error); PPRINTK("ncp_lookup: result=%d\n", error);
unlock_kernel();
return ERR_PTR(error); 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", PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n",
dentry->d_parent->d_name.name, dentry->d_name.name, mode); 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); ncp_age_dentry(server, dentry);
len = sizeof(__name); len = sizeof(__name);
error = ncp_io2vol(server, __name, &len, dentry->d_name.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) {
if (result == 0x87) if (result == 0x87)
error = -ENAMETOOLONG; error = -ENAMETOOLONG;
else if (result < 0)
error = result;
DPRINTK("ncp_create: %s/%s failed\n", DPRINTK("ncp_create: %s/%s failed\n",
dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
goto out; goto out;
@ -935,7 +998,6 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
error = ncp_instantiate(dir, dentry, &finfo); error = ncp_instantiate(dir, dentry, &finfo);
out: out:
unlock_kernel();
return error; 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", DPRINTK("ncp_mkdir: making %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name); 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); ncp_age_dentry(server, dentry);
len = sizeof(__name); len = sizeof(__name);
error = ncp_io2vol(server, __name, &len, dentry->d_name.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) if (error)
goto out; goto out;
error = -EACCES; error = ncp_open_create_file_or_subdir(server, dir, __name,
if (ncp_open_create_file_or_subdir(server, dir, __name,
OC_MODE_CREATE, aDIR, OC_MODE_CREATE, aDIR,
cpu_to_le16(0xffff), cpu_to_le16(0xffff),
&finfo) == 0) &finfo);
{ if (error == 0) {
if (ncp_is_nfs_extras(server, finfo.volume)) { if (ncp_is_nfs_extras(server, finfo.volume)) {
mode |= S_IFDIR; mode |= S_IFDIR;
finfo.i.nfs.mode = mode; finfo.i.nfs.mode = mode;
@ -983,9 +1039,10 @@ static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
goto out; goto out;
} }
error = ncp_instantiate(dir, dentry, &finfo); error = ncp_instantiate(dir, dentry, &finfo);
} else if (error > 0) {
error = -EACCES;
} }
out: out:
unlock_kernel();
return error; return error;
} }
@ -998,11 +1055,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
DPRINTK("ncp_rmdir: removing %s/%s\n", DPRINTK("ncp_rmdir: removing %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
error = -EIO;
lock_kernel();
if (!ncp_conn_valid(server))
goto out;
error = -EBUSY; error = -EBUSY;
if (!d_unhashed(dentry)) if (!d_unhashed(dentry))
goto out; goto out;
@ -1036,11 +1088,10 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
error = -ENOENT; error = -ENOENT;
break; break;
default: default:
error = -EACCES; error = result < 0 ? result : -EACCES;
break; break;
} }
out: out:
unlock_kernel();
return error; return error;
} }
@ -1050,15 +1101,10 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry)
struct ncp_server *server; struct ncp_server *server;
int error; int error;
lock_kernel();
server = NCP_SERVER(dir); server = NCP_SERVER(dir);
DPRINTK("ncp_unlink: unlinking %s/%s\n", DPRINTK("ncp_unlink: unlinking %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name); 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 ... * Check whether to close the file ...
*/ */
@ -1097,12 +1143,9 @@ static int ncp_unlink(struct inode *dir, struct dentry *dentry)
error = -ENOENT; error = -ENOENT;
break; break;
default: default:
error = -EACCES; error = error < 0 ? error : -EACCES;
break; break;
} }
out:
unlock_kernel();
return error; 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, old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
new_dentry->d_parent->d_name.name, new_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, old_dentry);
ncp_age_dentry(server, new_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; error = -ENOENT;
break; break;
default: default:
error = -EACCES; error = error < 0 ? error : -EACCES;
break; break;
} }
out: out:
unlock_kernel();
return error; return error;
} }

View 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", DPRINTK("ncp_file_read: enter %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
if (!ncp_conn_valid(NCP_SERVER(inode)))
return -EIO;
pos = *ppos; pos = *ppos;
if ((ssize_t) count < 0) { 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", DPRINTK("ncp_file_write: enter %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
if (!ncp_conn_valid(NCP_SERVER(inode)))
return -EIO;
if ((ssize_t) count < 0) if ((ssize_t) count < 0)
return -EINVAL; return -EINVAL;
pos = *ppos; pos = *ppos;
if (file->f_flags & O_APPEND) { 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)) { 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; *ppos = pos;
if (pos > inode->i_size) { if (pos > i_size_read(inode)) {
inode->i_size = pos; 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", DPRINTK("ncp_file_write: exit %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name); 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; 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 = const struct file_operations ncp_file_operations =
{ {
.llseek = ncp_remote_llseek, .llseek = generic_file_llseek,
.read = ncp_file_read, .read = ncp_file_read,
.write = ncp_file_write, .write = ncp_file_write,
.unlocked_ioctl = ncp_ioctl, .unlocked_ioctl = ncp_ioctl,

View 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_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_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate); 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; inode->i_mode = server->m.dir_mode;
/* for directories dataStreamSize seems to be some /* for directories dataStreamSize seems to be some
Object ID ??? */ Object ID ??? */
inode->i_size = NCP_BLOCK_SIZE; i_size_write(inode, NCP_BLOCK_SIZE);
} else { } else {
u32 size;
inode->i_mode = server->m.file_mode; 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 #ifdef CONFIG_NCPFS_EXTRAS
if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
&& (nwi->attributes & aSHARED)) { && (nwi->attributes & aSHARED)) {
switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
case aHIDDEN: case aHIDDEN:
if (server->m.flags & NCP_MOUNT_SYMLINKS) { if (server->m.flags & NCP_MOUNT_SYMLINKS) {
if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE) if (/* (size >= NCP_MIN_SYMLINK_SIZE)
&& */ (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) { && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK; NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
break; 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) 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) { if (inode) {
atomic_set(&NCP_FINFO(inode)->opened, info->opened); atomic_set(&NCP_FINFO(inode)->opened, info->opened);
inode->i_mapping->backing_dev_info = sb->s_bdi;
inode->i_ino = info->ino; inode->i_ino = info->ino;
ncp_set_attr(inode, info); ncp_set_attr(inode, info);
if (S_ISREG(inode->i_mode)) { 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) { static void ncp_stop_tasks(struct ncp_server *server) {
struct sock* sk = server->ncp_sock->sk; struct sock* sk = server->ncp_sock->sk;
lock_sock(sk);
sk->sk_error_report = server->error_report; sk->sk_error_report = server->error_report;
sk->sk_data_ready = server->data_ready; sk->sk_data_ready = server->data_ready;
sk->sk_write_space = server->write_space; sk->sk_write_space = server->write_space;
release_sock(sk);
del_timer_sync(&server->timeout_tm); del_timer_sync(&server->timeout_tm);
flush_scheduled_work(); 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->conn_status = 0; */
/* server->root_dentry = NULL; */ /* server->root_dentry = NULL; */
/* server->root_setuped = 0; */ /* server->root_setuped = 0; */
mutex_init(&server->root_setup_lock);
#ifdef CONFIG_NCPFS_PACKET_SIGNING #ifdef CONFIG_NCPFS_PACKET_SIGNING
/* server->sign_wanted = 0; */ /* server->sign_wanted = 0; */
/* server->sign_active = 0; */ /* server->sign_active = 0; */
#endif #endif
init_rwsem(&server->auth_rwsem);
server->auth.auth_type = NCP_AUTH_NONE; server->auth.auth_type = NCP_AUTH_NONE;
/* server->auth.object_name_len = 0; */ /* server->auth.object_name_len = 0; */
/* server->auth.object_name = NULL; */ /* 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(); server->nls_io = load_nls_default();
#endif /* CONFIG_NCPFS_NLS */ #endif /* CONFIG_NCPFS_NLS */
server->dentry_ttl = 0; /* no caching */ atomic_set(&server->dentry_ttl, 0); /* no caching */
INIT_LIST_HEAD(&server->tx.requests); INIT_LIST_HEAD(&server->tx.requests);
mutex_init(&server->rcv.creq_mutex); mutex_init(&server->rcv.creq_mutex);
server->tx.creq = NULL; server->tx.creq = NULL;
server->rcv.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); init_timer(&server->timeout_tm);
#undef NCP_PACKET_SIZE #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) if (server->rxbuf == NULL)
goto out_txbuf; 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_data_ready = ncp_tcp_data_ready;
sock->sk->sk_error_report = ncp_tcp_error_report; sock->sk->sk_error_report = ncp_tcp_error_report;
if (sock->type == SOCK_STREAM) { 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.data = (unsigned long)server;
server->timeout_tm.function = ncpdgram_timeout_call; server->timeout_tm.function = ncpdgram_timeout_call;
} }
release_sock(sock->sk);
ncp_lock_server(server); ncp_lock_server(server);
error = ncp_connect(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; goto out_disconnect;
} }
} }
ncp_lock_server(server);
if (options & 2) if (options & 2)
server->sign_wanted = 1; server->sign_wanted = 1;
ncp_unlock_server(server);
} }
else else
#endif /* CONFIG_NCPFS_PACKET_SIGNING */ #endif /* CONFIG_NCPFS_PACKET_SIGNING */
@ -720,6 +732,9 @@ out_nls:
unload_nls(server->nls_io); unload_nls(server->nls_io);
unload_nls(server->nls_vol); unload_nls(server->nls_vol);
#endif #endif
mutex_destroy(&server->rcv.creq_mutex);
mutex_destroy(&server->root_setup_lock);
mutex_destroy(&server->mutex);
out_fput2: out_fput2:
if (server->info_filp) if (server->info_filp)
fput(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); struct ncp_server *server = NCP_SBP(sb);
lock_kernel();
ncp_lock_server(server); ncp_lock_server(server);
ncp_disconnect(server); ncp_disconnect(server);
ncp_unlock_server(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_vol);
unload_nls(server->nls_io); unload_nls(server->nls_io);
#endif /* CONFIG_NCPFS_NLS */ #endif /* CONFIG_NCPFS_NLS */
mutex_destroy(&server->rcv.creq_mutex);
mutex_destroy(&server->root_setup_lock);
mutex_destroy(&server->mutex);
if (server->info_filp) if (server->info_filp)
fput(server->info_filp); fput(server->info_filp);
@ -771,8 +787,6 @@ static void ncp_put_super(struct super_block *sb)
vfree(server->packet); vfree(server->packet);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(server); kfree(server);
unlock_kernel();
} }
static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) 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; result = -EIO;
lock_kernel();
server = NCP_SERVER(inode); server = NCP_SERVER(inode);
if ((!server) || !ncp_conn_valid(server)) if (!server) /* How this could happen? */
goto out; goto out;
/* ageing the dentry to force validation */ /* 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), result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
inode, info_mask, &info); inode, info_mask, &info);
if (result != 0) { if (result != 0) {
result = -EACCES;
if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) { if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
/* NetWare seems not to allow this. I /* NetWare seems not to allow this. I
do not know why. So, just tell the 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); mark_inode_dirty(inode);
out: out:
unlock_kernel(); if (result > 0)
result = -EACCES;
return result; return result;
} }

View File

@ -35,16 +35,11 @@
#define NCP_PACKET_SIZE_INTERNAL 65536 #define NCP_PACKET_SIZE_INTERNAL 65536
static int 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 ncp_fs_info __user *arg)
{ {
struct inode *inode = file->f_path.dentry->d_inode;
struct ncp_fs_info info; 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))) if (copy_from_user(&info, arg, sizeof(info)))
return -EFAULT; return -EFAULT;
@ -65,16 +60,11 @@ ncp_get_fs_info(struct ncp_server * server, struct file *file,
} }
static int 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 ncp_fs_info_v2 __user * arg)
{ {
struct inode *inode = file->f_path.dentry->d_inode;
struct ncp_fs_info_v2 info2; 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))) if (copy_from_user(&info2, arg, sizeof(info2)))
return -EFAULT; return -EFAULT;
@ -136,16 +126,11 @@ struct compat_ncp_privatedata_ioctl
#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl) #define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl)
static int 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 compat_ncp_fs_info_v2 __user * arg)
{ {
struct inode *inode = file->f_path.dentry->d_inode;
struct compat_ncp_fs_info_v2 info2; 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))) if (copy_from_user(&info2, arg, sizeof(info2)))
return -EFAULT; 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 *iocharset;
struct nls_table *oldset_io; struct nls_table *oldset_io;
struct nls_table *oldset_cp; struct nls_table *oldset_cp;
int utf8;
if (!capable(CAP_SYS_ADMIN)) int err;
return -EACCES;
if (server->root_setuped)
return -EBUSY;
if (copy_from_user(&user, arg, sizeof(user))) if (copy_from_user(&user, arg, sizeof(user)))
return -EFAULT; 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; user.iocharset[NCP_IOCSNAME_LEN] = 0;
if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) { if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) {
iocharset = load_nls_default(); iocharset = load_nls_default();
NCP_CLR_FLAG(server, NCP_FLAG_UTF8); utf8 = 0;
} else if (!strcmp(user.iocharset, "utf8")) { } else if (!strcmp(user.iocharset, "utf8")) {
iocharset = load_nls_default(); iocharset = load_nls_default();
NCP_SET_FLAG(server, NCP_FLAG_UTF8); utf8 = 1;
} else { } else {
iocharset = load_nls(user.iocharset); iocharset = load_nls(user.iocharset);
if (!iocharset) { if (!iocharset) {
unload_nls(codepage); unload_nls(codepage);
return -EBADRQC; return -EBADRQC;
} }
NCP_CLR_FLAG(server, NCP_FLAG_UTF8); utf8 = 0;
} }
oldset_cp = server->nls_vol; mutex_lock(&server->root_setup_lock);
server->nls_vol = codepage; if (server->root_setuped) {
oldset_io = server->nls_io; oldset_cp = codepage;
server->nls_io = iocharset; 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_cp);
unload_nls(oldset_io); unload_nls(oldset_io);
return 0; return err;
} }
static int static int
@ -237,6 +231,7 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
int len; int len;
memset(&user, 0, sizeof(user)); memset(&user, 0, sizeof(user));
mutex_lock(&server->root_setup_lock);
if (server->nls_vol && server->nls_vol->charset) { if (server->nls_vol && server->nls_vol->charset) {
len = strlen(server->nls_vol->charset); len = strlen(server->nls_vol->charset);
if (len > NCP_IOCSNAME_LEN) 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); strncpy(user.iocharset, server->nls_io->charset, len);
user.iocharset[len] = 0; user.iocharset[len] = 0;
} }
mutex_unlock(&server->root_setup_lock);
if (copy_to_user(arg, &user, sizeof(user))) if (copy_to_user(arg, &user, sizeof(user)))
return -EFAULT; return -EFAULT;
@ -261,25 +257,19 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
} }
#endif /* CONFIG_NCPFS_NLS */ #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); struct ncp_server *server = NCP_SERVER(inode);
int result; int result;
struct ncp_ioctl_request request; struct ncp_ioctl_request request;
char* bouncebuffer; char* bouncebuffer;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
uid_t uid = current_uid();
switch (cmd) { switch (cmd) {
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
case NCP_IOC_NCPREQUEST_32: case NCP_IOC_NCPREQUEST_32:
#endif #endif
case NCP_IOC_NCPREQUEST: case NCP_IOC_NCPREQUEST:
if (file_permission(filp, MAY_WRITE) != 0
&& uid != server->m.mounted_uid)
return -EACCES;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
if (cmd == NCP_IOC_NCPREQUEST_32) { if (cmd == NCP_IOC_NCPREQUEST_32) {
struct compat_ncp_ioctl_request request32; 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; server->current_size = request.size;
memcpy(server->packet, bouncebuffer, 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); bouncebuffer, NCP_PACKET_SIZE_INTERNAL);
if (result < 0) if (result < 0)
result = -EIO; 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: case NCP_IOC_CONN_LOGGED_IN:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE)) if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE))
return -EINVAL; return -EINVAL;
mutex_lock(&server->root_setup_lock);
if (server->root_setuped) if (server->root_setuped)
return -EBUSY; result = -EBUSY;
server->root_setuped = 1; else {
return ncp_conn_logged_in(inode->i_sb); 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: 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: 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 #ifdef CONFIG_COMPAT
case NCP_IOC_GET_FS_INFO_V2_32: 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 #endif
/* we have too many combinations of CONFIG_COMPAT, /* we have too many combinations of CONFIG_COMPAT,
* CONFIG_64BIT and CONFIG_UID16, so just handle * CONFIG_64BIT and CONFIG_UID16, so just handle
* any of the possible ioctls */ * any of the possible ioctls */
case NCP_IOC_GETMOUNTUID16: 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; u16 uid;
SET_UID(uid, server->m.mounted_uid); SET_UID(uid, server->m.mounted_uid);
if (put_user(uid, (u16 __user *)argp)) if (put_user(uid, (u16 __user *)argp))
return -EFAULT; return -EFAULT;
} else if (cmd == NCP_IOC_GETMOUNTUID32) { return 0;
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;
} }
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; return 0;
case NCP_IOC_GETROOT: case NCP_IOC_GETROOT:
{ {
struct ncp_setroot_ioctl sr; struct ncp_setroot_ioctl sr;
if (file_permission(filp, MAY_READ) != 0 result = -EACCES;
&& uid != server->m.mounted_uid) mutex_lock(&server->root_setup_lock);
return -EACCES;
if (server->m.mounted_vol[0]) { if (server->m.mounted_vol[0]) {
struct dentry* dentry = inode->i_sb->s_root; struct dentry* dentry = inode->i_sb->s_root;
if (dentry) { if (dentry) {
struct inode* s_inode = dentry->d_inode; struct inode* s_inode = dentry->d_inode;
if (s_inode) { if (s_inode) {
sr.volNumber = NCP_FINFO(s_inode)->volNumber; sr.volNumber = NCP_FINFO(s_inode)->volNumber;
sr.dirEntNum = NCP_FINFO(s_inode)->dirEntNum; sr.dirEntNum = NCP_FINFO(s_inode)->dirEntNum;
sr.namespace = server->name_space[sr.volNumber]; sr.namespace = server->name_space[sr.volNumber];
result = 0;
} else } else
DPRINTK("ncpfs: s_root->d_inode==NULL\n"); DPRINTK("ncpfs: s_root->d_inode==NULL\n");
} else } else
@ -402,10 +392,12 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
sr.volNumber = -1; sr.volNumber = -1;
sr.namespace = 0; sr.namespace = 0;
sr.dirEntNum = 0; sr.dirEntNum = 0;
result = 0;
} }
if (copy_to_user(argp, &sr, sizeof(sr))) mutex_unlock(&server->root_setup_lock);
return -EFAULT; if (!result && copy_to_user(argp, &sr, sizeof(sr)))
return 0; result = -EFAULT;
return result;
} }
case NCP_IOC_SETROOT: case NCP_IOC_SETROOT:
@ -416,103 +408,114 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
__le32 dosde; __le32 dosde;
struct dentry* dentry; struct dentry* dentry;
if (!capable(CAP_SYS_ADMIN))
{
return -EACCES;
}
if (server->root_setuped) return -EBUSY;
if (copy_from_user(&sr, argp, sizeof(sr))) if (copy_from_user(&sr, argp, sizeof(sr)))
return -EFAULT; return -EFAULT;
if (sr.volNumber < 0) { mutex_lock(&server->root_setup_lock);
server->m.mounted_vol[0] = 0; if (server->root_setuped)
vnum = NCP_NUMBER_OF_VOLUMES; result = -EBUSY;
de = 0; else {
dosde = 0; if (sr.volNumber < 0) {
} else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) { server->m.mounted_vol[0] = 0;
return -EINVAL; vnum = NCP_NUMBER_OF_VOLUMES;
} else if (ncp_mount_subdir(server, sr.volNumber, de = 0;
sr.namespace, sr.dirEntNum, dosde = 0;
&vnum, &de, &dosde)) { result = 0;
return -ENOENT; } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
} result = -EINVAL;
} else if (ncp_mount_subdir(server, sr.volNumber,
dentry = inode->i_sb->s_root; sr.namespace, sr.dirEntNum,
server->root_setuped = 1; &vnum, &de, &dosde)) {
if (dentry) { result = -ENOENT;
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;
} else } else
DPRINTK("ncpfs: s_root->d_inode==NULL\n"); result = 0;
} else
DPRINTK("ncpfs: s_root==NULL\n");
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 result;
}
#ifdef CONFIG_NCPFS_PACKET_SIGNING
case NCP_IOC_SIGN_INIT:
{
struct ncp_sign_init sign;
if (argp)
if (copy_from_user(&sign, argp, sizeof(sign)))
return -EFAULT;
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;
}
mutex_unlock(&server->rcv.creq_mutex);
ncp_unlock_server(server);
return 0; return 0;
} }
#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;
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;
}
/* ignore when signatures not wanted */
} else {
server->sign_active = 0;
}
return 0;
case NCP_IOC_SIGN_WANTED: case NCP_IOC_SIGN_WANTED:
if (file_permission(filp, MAY_READ) != 0 {
&& uid != server->m.mounted_uid) int state;
return -EACCES;
ncp_lock_server(server);
if (put_user(server->sign_wanted, (int __user *)argp)) state = server->sign_wanted;
return -EFAULT; ncp_unlock_server(server);
return 0; if (put_user(state, (int __user *)argp))
return -EFAULT;
return 0;
}
case NCP_IOC_SET_SIGN_WANTED: case NCP_IOC_SET_SIGN_WANTED:
{ {
int newstate; int newstate;
if (file_permission(filp, MAY_WRITE) != 0
&& uid != server->m.mounted_uid)
return -EACCES;
/* get only low 8 bits... */ /* get only low 8 bits... */
if (get_user(newstate, (unsigned char __user *)argp)) if (get_user(newstate, (unsigned char __user *)argp))
return -EFAULT; return -EFAULT;
result = 0;
ncp_lock_server(server);
if (server->sign_active) { if (server->sign_active) {
/* cannot turn signatures OFF when active */ /* cannot turn signatures OFF when active */
if (!newstate) return -EINVAL; if (!newstate)
result = -EINVAL;
} else { } else {
server->sign_wanted = newstate != 0; server->sign_wanted = newstate != 0;
} }
return 0; ncp_unlock_server(server);
return result;
} }
#endif /* CONFIG_NCPFS_PACKET_SIGNING */ #endif /* CONFIG_NCPFS_PACKET_SIGNING */
#ifdef CONFIG_NCPFS_IOCTL_LOCKING #ifdef CONFIG_NCPFS_IOCTL_LOCKING
case NCP_IOC_LOCKUNLOCK: case NCP_IOC_LOCKUNLOCK:
if (file_permission(filp, MAY_WRITE) != 0
&& uid != server->m.mounted_uid)
return -EACCES;
{ {
struct ncp_lock_ioctl rqdata; struct ncp_lock_ioctl rqdata;
@ -541,16 +544,13 @@ static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ {
return result; return result;
} }
result = -EIO;
if (!ncp_conn_valid(server))
goto outrel;
result = -EISDIR; result = -EISDIR;
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->i_mode))
goto outrel; goto outrel;
if (rqdata.cmd == NCP_LOCK_CLEAR) if (rqdata.cmd == NCP_LOCK_CLEAR)
{ {
result = ncp_ClearPhysicalRecord(NCP_SERVER(inode), result = ncp_ClearPhysicalRecord(NCP_SERVER(inode),
NCP_FINFO(inode)->file_handle, NCP_FINFO(inode)->file_handle,
rqdata.offset, rqdata.offset,
rqdata.length); rqdata.length);
if (result > 0) result = 0; /* no such lock */ 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); rqdata.timeout);
if (result > 0) result = -EAGAIN; if (result > 0) result = -EAGAIN;
} }
outrel: outrel:
ncp_inode_close(inode); ncp_inode_close(inode);
return result; return result;
} }
@ -581,60 +581,62 @@ outrel:
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
case NCP_IOC_GETOBJECTNAME_32: case NCP_IOC_GETOBJECTNAME_32:
if (uid != server->m.mounted_uid)
return -EACCES;
{ {
struct compat_ncp_objectname_ioctl user; struct compat_ncp_objectname_ioctl user;
size_t outl; size_t outl;
if (copy_from_user(&user, argp, sizeof(user))) if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT; return -EFAULT;
down_read(&server->auth_rwsem);
user.auth_type = server->auth.auth_type; user.auth_type = server->auth.auth_type;
outl = user.object_name_len; outl = user.object_name_len;
user.object_name_len = server->auth.object_name_len; user.object_name_len = server->auth.object_name_len;
if (outl > user.object_name_len) if (outl > user.object_name_len)
outl = user.object_name_len; outl = user.object_name_len;
result = 0;
if (outl) { if (outl) {
if (copy_to_user(compat_ptr(user.object_name), if (copy_to_user(compat_ptr(user.object_name),
server->auth.object_name, server->auth.object_name,
outl)) return -EFAULT; outl))
result = -EFAULT;
} }
if (copy_to_user(argp, &user, sizeof(user))) up_read(&server->auth_rwsem);
return -EFAULT; if (!result && copy_to_user(argp, &user, sizeof(user)))
return 0; result = -EFAULT;
return result;
} }
#endif #endif
case NCP_IOC_GETOBJECTNAME: case NCP_IOC_GETOBJECTNAME:
if (uid != server->m.mounted_uid)
return -EACCES;
{ {
struct ncp_objectname_ioctl user; struct ncp_objectname_ioctl user;
size_t outl; size_t outl;
if (copy_from_user(&user, argp, sizeof(user))) if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT; return -EFAULT;
down_read(&server->auth_rwsem);
user.auth_type = server->auth.auth_type; user.auth_type = server->auth.auth_type;
outl = user.object_name_len; outl = user.object_name_len;
user.object_name_len = server->auth.object_name_len; user.object_name_len = server->auth.object_name_len;
if (outl > user.object_name_len) if (outl > user.object_name_len)
outl = user.object_name_len; outl = user.object_name_len;
result = 0;
if (outl) { if (outl) {
if (copy_to_user(user.object_name, if (copy_to_user(user.object_name,
server->auth.object_name, server->auth.object_name,
outl)) return -EFAULT; outl))
result = -EFAULT;
} }
if (copy_to_user(argp, &user, sizeof(user))) up_read(&server->auth_rwsem);
return -EFAULT; if (!result && copy_to_user(argp, &user, sizeof(user)))
return 0; result = -EFAULT;
return result;
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
case NCP_IOC_SETOBJECTNAME_32: case NCP_IOC_SETOBJECTNAME_32:
#endif #endif
case NCP_IOC_SETOBJECTNAME: case NCP_IOC_SETOBJECTNAME:
if (uid != server->m.mounted_uid)
return -EACCES;
{ {
struct ncp_objectname_ioctl user; struct ncp_objectname_ioctl user;
void* newname; void* newname;
@ -666,9 +668,7 @@ outrel:
} else { } else {
newname = NULL; newname = NULL;
} }
/* enter critical section */ down_write(&server->auth_rwsem);
/* maybe that kfree can sleep so do that this way */
/* it is at least more SMP friendly (in future...) */
oldname = server->auth.object_name; oldname = server->auth.object_name;
oldnamelen = server->auth.object_name_len; oldnamelen = server->auth.object_name_len;
oldprivate = server->priv.data; oldprivate = server->priv.data;
@ -678,7 +678,7 @@ outrel:
server->auth.object_name = newname; server->auth.object_name = newname;
server->priv.len = 0; server->priv.len = 0;
server->priv.data = NULL; server->priv.data = NULL;
/* leave critical section */ up_write(&server->auth_rwsem);
kfree(oldprivate); kfree(oldprivate);
kfree(oldname); kfree(oldname);
return 0; return 0;
@ -688,8 +688,6 @@ outrel:
case NCP_IOC_GETPRIVATEDATA_32: case NCP_IOC_GETPRIVATEDATA_32:
#endif #endif
case NCP_IOC_GETPRIVATEDATA: case NCP_IOC_GETPRIVATEDATA:
if (uid != server->m.mounted_uid)
return -EACCES;
{ {
struct ncp_privatedata_ioctl user; struct ncp_privatedata_ioctl user;
size_t outl; size_t outl;
@ -706,14 +704,20 @@ outrel:
if (copy_from_user(&user, argp, sizeof(user))) if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT; return -EFAULT;
down_read(&server->auth_rwsem);
outl = user.len; outl = user.len;
user.len = server->priv.len; user.len = server->priv.len;
if (outl > user.len) outl = user.len; if (outl > user.len) outl = user.len;
result = 0;
if (outl) { if (outl) {
if (copy_to_user(user.data, if (copy_to_user(user.data,
server->priv.data, server->priv.data,
outl)) return -EFAULT; outl))
result = -EFAULT;
} }
up_read(&server->auth_rwsem);
if (result)
return result;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
if (cmd == NCP_IOC_GETPRIVATEDATA_32) { if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
struct compat_ncp_privatedata_ioctl user32; struct compat_ncp_privatedata_ioctl user32;
@ -733,8 +737,6 @@ outrel:
case NCP_IOC_SETPRIVATEDATA_32: case NCP_IOC_SETPRIVATEDATA_32:
#endif #endif
case NCP_IOC_SETPRIVATEDATA: case NCP_IOC_SETPRIVATEDATA:
if (uid != server->m.mounted_uid)
return -EACCES;
{ {
struct ncp_privatedata_ioctl user; struct ncp_privatedata_ioctl user;
void* new; void* new;
@ -762,12 +764,12 @@ outrel:
} else { } else {
new = NULL; new = NULL;
} }
/* enter critical section */ down_write(&server->auth_rwsem);
old = server->priv.data; old = server->priv.data;
oldlen = server->priv.len; oldlen = server->priv.len;
server->priv.len = user.len; server->priv.len = user.len;
server->priv.data = new; server->priv.data = new;
/* leave critical section */ up_write(&server->auth_rwsem);
kfree(old); kfree(old);
return 0; return 0;
} }
@ -775,17 +777,13 @@ outrel:
#ifdef CONFIG_NCPFS_NLS #ifdef CONFIG_NCPFS_NLS
case NCP_IOC_SETCHARSETS: case NCP_IOC_SETCHARSETS:
return ncp_set_charsets(server, argp); return ncp_set_charsets(server, argp);
case NCP_IOC_GETCHARSETS: case NCP_IOC_GETCHARSETS:
return ncp_get_charsets(server, argp); return ncp_get_charsets(server, argp);
#endif /* CONFIG_NCPFS_NLS */ #endif /* CONFIG_NCPFS_NLS */
case NCP_IOC_SETDENTRYTTL: case NCP_IOC_SETDENTRYTTL:
if (file_permission(filp, MAY_WRITE) != 0 &&
uid != server->m.mounted_uid)
return -EACCES;
{ {
u_int32_t user; u_int32_t user;
@ -795,13 +793,13 @@ outrel:
if (user > 20000) if (user > 20000)
return -EINVAL; return -EINVAL;
user = (user * HZ) / 1000; user = (user * HZ) / 1000;
server->dentry_ttl = user; atomic_set(&server->dentry_ttl, user);
return 0; return 0;
} }
case NCP_IOC_GETDENTRYTTL: 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))) if (copy_to_user(argp, &user, sizeof(user)))
return -EFAULT; return -EFAULT;
return 0; return 0;
@ -811,59 +809,103 @@ outrel:
return -EINVAL; return -EINVAL;
} }
static int ncp_ioctl_need_write(unsigned int cmd)
{
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;
}
}
long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 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; long ret;
lock_kernel(); switch (cmd) {
if (ncp_ioctl_need_write(cmd)) { case NCP_IOC_SETCHARSETS:
/* case NCP_IOC_CONN_LOGGED_IN:
* inside the ioctl(), any failures which case NCP_IOC_SETROOT:
* are because of file_permission() are if (!capable(CAP_SYS_ADMIN)) {
* -EACCESS, so it seems consistent to keep
* that here.
*/
if (mnt_want_write(filp->f_path.mnt)) {
ret = -EACCES; ret = -EACCES;
goto out; goto out;
} }
break;
} }
ret = __ncp_ioctl(filp, cmd, arg); if (server->m.mounted_uid != uid) {
if (ncp_ioctl_need_write(cmd)) switch (cmd) {
/*
* Only mount owner can issue these ioctls. Information
* necessary to authenticate to other NDS servers are
* stored here.
*/
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(inode, cmd, arg);
outDropWrite:
if (need_drop_write)
mnt_drop_write(filp->f_path.mnt); mnt_drop_write(filp->f_path.mnt);
out: out:
unlock_kernel();
return ret; return ret;
} }
@ -872,10 +914,8 @@ long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
long ret; long ret;
lock_kernel();
arg = (unsigned long) compat_ptr(arg); arg = (unsigned long) compat_ptr(arg);
ret = ncp_ioctl(file, cmd, arg); ret = ncp_ioctl(file, cmd, arg);
unlock_kernel();
return ret; return ret;
} }
#endif #endif

View File

@ -107,17 +107,17 @@ ncp_reply_data(struct ncp_server *server, int offset)
return &(server->packet[sizeof(struct ncp_reply_header) + 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) 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); 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)); 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); return get_unaligned_le32(data);
} }
@ -349,9 +349,9 @@ int ncp_dirhandle_free(struct ncp_server* server, __u8 dirhandle) {
return result; 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); const int info_struct_size = offsetof(struct nw_info_struct, nameLen);
memcpy(target, structure, info_struct_size); 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 #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) struct nw_nfs_info *target)
{ {
target->mode = DVAL_LH(structure); 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 * Returns information for a (one-component) name relative to
* the specified directory. * 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) struct nw_info_struct *target)
{ {
__u8 volnum = NCP_FINFO(dir)->volNumber; __u8 volnum = NCP_FINFO(dir)->volNumber;
@ -452,16 +452,16 @@ out:
#ifdef CONFIG_NCPFS_NFS_NS #ifdef CONFIG_NCPFS_NFS_NS
static int static int
ncp_obtain_DOS_dir_base(struct ncp_server *server, ncp_obtain_DOS_dir_base(struct ncp_server *server,
__u8 volnum, __le32 dirent, __u8 ns, __u8 volnum, __le32 dirent,
char *path, /* At most 1 component */ const char *path, /* At most 1 component */
__le32 *DOS_dir_base) __le32 *DOS_dir_base)
{ {
int result; int result;
ncp_init_request(server); ncp_init_request(server);
ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, 6); /* subfunction */
ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, ns);
ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, ns);
ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */
ncp_add_dword(server, RIM_DIRECTORY); ncp_add_dword(server, RIM_DIRECTORY);
ncp_add_handle_path(server, volnum, dirent, 1, path); 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) */ #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 static int
ncp_ObtainSpecificDirBase(struct ncp_server *server, ncp_ObtainSpecificDirBase(struct ncp_server *server,
__u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, __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) __le32 *dirEntNum, __le32 *DosDirNum)
{ {
int result; int result;
@ -560,14 +577,13 @@ ncp_mount_subdir(struct ncp_server *server,
{ {
int dstNS; int dstNS;
int result; int result;
dstNS = ncp_get_known_namespace(server, volNumber); ncp_update_known_namespace(server, volNumber, &dstNS);
if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber,
dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) dirEntNum, NULL, newDirEnt, newDosEnt)) != 0)
{ {
return result; return result;
} }
server->name_space[volNumber] = dstNS;
*volume = volNumber; *volume = volNumber;
server->m.mounted_vol[1] = 0; server->m.mounted_vol[1] = 0;
server->m.mounted_vol[0] = 'X'; server->m.mounted_vol[0] = 'X';
@ -575,11 +591,10 @@ ncp_mount_subdir(struct ncp_server *server,
} }
int int
ncp_get_volume_root(struct ncp_server *server, const char *volname, ncp_get_volume_root(struct ncp_server *server,
__u32* volume, __le32* dirent, __le32* dosdirent) const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent)
{ {
int result; int result;
__u8 volnum;
DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname); 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; return result;
} }
*dirent = *dosdirent = ncp_reply_dword(server, 4); *dirent = *dosdirent = ncp_reply_dword(server, 4);
volnum = ncp_reply_byte(server, 8); *volume = ncp_reply_byte(server, 8);
ncp_unlock_server(server); 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; return 0;
} }
int int
ncp_lookup_volume(struct ncp_server *server, const char *volname, ncp_lookup_volume(struct ncp_server *server,
struct nw_info_struct *target) const char *volname, struct nw_info_struct *target)
{ {
int result; int result;
@ -625,6 +633,7 @@ ncp_lookup_volume(struct ncp_server *server, const char *volname,
if (result) { if (result) {
return result; return result;
} }
ncp_update_known_namespace(server, target->volNumber, NULL);
target->nameLen = strlen(volname); target->nameLen = strlen(volname);
memcpy(target->entryName, volname, target->nameLen+1); memcpy(target->entryName, volname, target->nameLen+1);
target->attributes = aDIR; target->attributes = aDIR;
@ -676,8 +685,8 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
{ {
int result = 0; int result = 0;
ncp_init_request(server);
if (server->name_space[volnum] == NW_NS_NFS) { if (server->name_space[volnum] == NW_NS_NFS) {
ncp_init_request(server);
ncp_add_byte(server, 25); /* subfunction */ ncp_add_byte(server, 25); /* subfunction */
ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, server->name_space[volnum]);
ncp_add_byte(server, NW_NS_NFS); 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, 1); /* nlinks */
ncp_add_dword_lh(server, rdev); ncp_add_dword_lh(server, rdev);
result = ncp_request(server, 87); result = ncp_request(server, 87);
ncp_unlock_server(server);
} }
ncp_unlock_server(server);
return result; return result;
} }
#endif #endif
@ -700,7 +709,7 @@ int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent,
static int static int
ncp_DeleteNSEntry(struct ncp_server *server, ncp_DeleteNSEntry(struct ncp_server *server,
__u8 have_dir_base, __u8 volnum, __le32 dirent, __u8 have_dir_base, __u8 volnum, __le32 dirent,
char* name, __u8 ns, __le16 attr) const char* name, __u8 ns, __le16 attr)
{ {
int result; int result;
@ -734,23 +743,25 @@ ncp_del_file_or_subdir2(struct ncp_server *server,
int int
ncp_del_file_or_subdir(struct ncp_server *server, 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; __u8 volnum = NCP_FINFO(dir)->volNumber;
__le32 dirent = NCP_FINFO(dir)->dirEntNum; __le32 dirent = NCP_FINFO(dir)->dirEntNum;
int name_space;
name_space = server->name_space[volnum];
#ifdef CONFIG_NCPFS_NFS_NS #ifdef CONFIG_NCPFS_NFS_NS
if (server->name_space[volnum]==NW_NS_NFS) if (name_space == NW_NS_NFS)
{ {
int result; 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; 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 */ #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]) 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 /* If both dir and name are NULL, then in target there's already a
looked-up entry that wants to be opened. */ looked-up entry that wants to be opened. */
int ncp_open_create_file_or_subdir(struct ncp_server *server, 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, int open_create_mode,
__le32 create_attributes, __le32 create_attributes,
__le16 desired_acc_rights, __le16 desired_acc_rights,
@ -890,8 +901,8 @@ int ncp_search_for_fileset(struct ncp_server *server,
static int static int
ncp_RenameNSEntry(struct ncp_server *server, ncp_RenameNSEntry(struct ncp_server *server,
struct inode *old_dir, char *old_name, __le16 old_type, struct inode *old_dir, const char *old_name, __le16 old_type,
struct inode *new_dir, char *new_name) struct inode *new_dir, const char *new_name)
{ {
int result = -EINVAL; int result = -EINVAL;
@ -929,8 +940,8 @@ out:
} }
int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
struct inode *old_dir, char *old_name, struct inode *old_dir, const char *old_name,
struct inode *new_dir, char *new_name) struct inode *new_dir, const char *new_name)
{ {
int result; int result;
__le16 old_type = cpu_to_le16(0x06); __le16 old_type = cpu_to_le16(0x06);
@ -958,7 +969,7 @@ int
ncp_read_kernel(struct ncp_server *server, const char *file_id, ncp_read_kernel(struct ncp_server *server, const char *file_id,
__u32 offset, __u16 to_read, char *target, int *bytes_read) __u32 offset, __u16 to_read, char *target, int *bytes_read)
{ {
char *source; const char *source;
int result; int result;
ncp_init_request(server); ncp_init_request(server);

View File

@ -65,10 +65,11 @@ static inline void ncp_inode_close(struct inode *inode) {
atomic_dec(&NCP_FINFO(inode)->opened); atomic_dec(&NCP_FINFO(inode)->opened);
} }
void ncp_extract_file_info(void* src, struct nw_info_struct* target); void ncp_extract_file_info(const void* src, struct nw_info_struct* target);
int ncp_obtain_info(struct ncp_server *server, struct inode *, char *, int ncp_obtain_info(struct ncp_server *server, struct inode *, const char *,
struct nw_info_struct *target); struct nw_info_struct *target);
int ncp_obtain_nfs_info(struct ncp_server *server, 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, int ncp_get_volume_root(struct ncp_server *server, const char *volname,
__u32 *volume, __le32 *dirent, __le32 *dosdirent); __u32 *volume, __le32 *dirent, __le32 *dosdirent);
int ncp_lookup_volume(struct ncp_server *, const char *, struct nw_info_struct *); 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); __u32 mode, __u32 rdev);
int ncp_del_file_or_subdir2(struct ncp_server *, struct dentry*); 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_del_file_or_subdir(struct ncp_server *, struct inode *, const char *);
int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, char *, int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, const char *,
int, __le32, __le16, struct ncp_entry_info *); int, __le32, __le16, struct ncp_entry_info *);
int ncp_initialize_search(struct ncp_server *, struct inode *, 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); char** rbuf, size_t* rsize);
int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, 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 int
@ -170,13 +171,13 @@ static inline int ncp_strnicmp(struct nls_table *t, const unsigned char *s1,
#endif /* CONFIG_NCPFS_NLS */ #endif /* CONFIG_NCPFS_NLS */
#define NCP_GET_AGE(dentry) (jiffies - (dentry)->d_time) #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)) #define NCP_TEST_AGE(server,dentry) (NCP_GET_AGE(dentry) < NCP_MAX_AGE(server))
static inline void static inline void
ncp_age_dentry(struct ncp_server* server, struct dentry* dentry) 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 static inline void

View File

@ -15,21 +15,21 @@
/* i386: 32-bit, little endian, handles mis-alignment */ /* i386: 32-bit, little endian, handles mis-alignment */
#ifdef __i386__ #ifdef __i386__
#define GET_LE32(p) (*(int *)(p)) #define GET_LE32(p) (*(const int *)(p))
#define PUT_LE32(p,v) { *(int *)(p)=v; } #define PUT_LE32(p,v) { *(int *)(p)=v; }
#else #else
/* from include/ncplib.h */ /* 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 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 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; return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8;
} }
static inline __u32 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; return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16;
} }

View File

@ -746,7 +746,6 @@ static int ncp_do_request(struct ncp_server *server, int size,
return -EIO; return -EIO;
} }
if (!ncp_conn_valid(server)) { if (!ncp_conn_valid(server)) {
printk(KERN_ERR "ncpfs: Connection invalid!\n");
return -EIO; return -EIO;
} }
{ {

View File

@ -71,20 +71,20 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
if (inode->i_flock == NULL) if (inode->i_flock == NULL)
goto out; goto out;
/* Protect inode->i_flock using the BKL */ /* Protect inode->i_flock using the file locks lock */
lock_kernel(); lock_flocks();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue; continue;
if (nfs_file_open_context(fl->fl_file) != ctx) if (nfs_file_open_context(fl->fl_file) != ctx)
continue; continue;
unlock_kernel(); unlock_flocks();
status = nfs4_lock_delegation_recall(state, fl); status = nfs4_lock_delegation_recall(state, fl);
if (status < 0) if (status < 0)
goto out; goto out;
lock_kernel(); lock_flocks();
} }
unlock_kernel(); unlock_flocks();
out: out:
return status; return status;
} }

View File

@ -40,7 +40,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h> #include <linux/fs.h>
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
#include <linux/nfs_idmap.h> #include <linux/nfs_idmap.h>
#include <linux/kthread.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 */ /* Guard against delegation returns and new lock/unlock calls */
down_write(&nfsi->rwsem); down_write(&nfsi->rwsem);
/* Protect inode->i_flock using the BKL */ /* Protect inode->i_flock using the BKL */
lock_kernel(); lock_flocks();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue; continue;
if (nfs_file_open_context(fl->fl_file)->state != state) if (nfs_file_open_context(fl->fl_file)->state != state)
continue; continue;
unlock_kernel(); unlock_flocks();
status = ops->recover_lock(state, fl); status = ops->recover_lock(state, fl);
switch (status) { switch (status) {
case 0: 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); */ /* kill_proc(fl->fl_pid, SIGLOST, 1); */
status = 0; status = 0;
} }
lock_kernel(); lock_flocks();
} }
unlock_kernel(); unlock_flocks();
out: out:
up_write(&nfsi->rwsem); up_write(&nfsi->rwsem);
return status; return status;

View File

@ -33,7 +33,7 @@
*/ */
#include <linux/file.h> #include <linux/file.h>
#include <linux/smp_lock.h> #include <linux/fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/swap.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; struct inode *inode = filp->fi_inode;
int status = 0; int status = 0;
lock_kernel(); lock_flocks();
for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
if ((*flpp)->fl_owner == (fl_owner_t)lowner) { if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
status = 1; status = 1;
@ -3903,7 +3903,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner)
} }
} }
out: out:
unlock_kernel(); unlock_flocks();
return status; return status;
} }

View File

@ -22,7 +22,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/capability.h> /* capable() */ #include <linux/capability.h> /* capable() */
#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */ #include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */

View File

@ -45,7 +45,6 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/smp_lock.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/kobject.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 nilfs_sb_info *sbi = NILFS_SB(sb);
struct the_nilfs *nilfs = sbi->s_nilfs; struct the_nilfs *nilfs = sbi->s_nilfs;
lock_kernel();
nilfs_detach_segment_constructor(sbi); nilfs_detach_segment_constructor(sbi);
if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->s_flags & MS_RDONLY)) {
@ -361,8 +358,6 @@ static void nilfs_put_super(struct super_block *sb)
sbi->s_super = NULL; sbi->s_super = NULL;
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
nilfs_put_sbinfo(sbi); nilfs_put_sbinfo(sbi);
unlock_kernel();
} }
static int nilfs_sync_fs(struct super_block *sb, int wait) 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; struct nilfs_mount_options old_opts;
int was_snapshot, err; int was_snapshot, err;
lock_kernel();
down_write(&nilfs->ns_super_sem); down_write(&nilfs->ns_super_sem);
old_sb_flags = sb->s_flags; old_sb_flags = sb->s_flags;
old_opts.mount_opt = sbi->s_mount_opt; 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: out:
up_write(&nilfs->ns_super_sem); up_write(&nilfs->ns_super_sem);
unlock_kernel();
return 0; return 0;
restore_opts: 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_mount_opt = old_opts.mount_opt;
sbi->s_snapshot_cno = old_opts.snapshot_cno; sbi->s_snapshot_cno = old_opts.snapshot_cno;
up_write(&nilfs->ns_super_sem); up_write(&nilfs->ns_super_sem);
unlock_kernel();
return err; return err;
} }
@ -1205,7 +1196,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
put_nilfs(nilfs); put_nilfs(nilfs);
failed: failed:
close_bdev_exclusive(sd.bdev, mode); close_bdev_exclusive(sd.bdev, mode);
return err; return err;
cancel_new: cancel_new:

View File

@ -30,7 +30,6 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/smp_lock.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include "sysctl.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); ntfs_debug("Entering with remount options string: %s", opt);
lock_kernel();
#ifndef NTFS_RW #ifndef NTFS_RW
/* For read-only compiled driver, enforce read-only flag. */ /* For read-only compiled driver, enforce read-only flag. */
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
@ -469,18 +467,15 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
if (NVolErrors(vol)) { if (NVolErrors(vol)) {
ntfs_error(sb, "Volume has errors and is read-only%s", ntfs_error(sb, "Volume has errors and is read-only%s",
es); es);
unlock_kernel();
return -EROFS; return -EROFS;
} }
if (vol->vol_flags & VOLUME_IS_DIRTY) { if (vol->vol_flags & VOLUME_IS_DIRTY) {
ntfs_error(sb, "Volume is dirty and read-only%s", es); ntfs_error(sb, "Volume is dirty and read-only%s", es);
unlock_kernel();
return -EROFS; return -EROFS;
} }
if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) { if (vol->vol_flags & VOLUME_MODIFIED_BY_CHKDSK) {
ntfs_error(sb, "Volume has been modified by chkdsk " ntfs_error(sb, "Volume has been modified by chkdsk "
"and is read-only%s", es); "and is read-only%s", es);
unlock_kernel();
return -EROFS; return -EROFS;
} }
if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { 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", "(0x%x) and is read-only%s",
(unsigned)le16_to_cpu(vol->vol_flags), (unsigned)le16_to_cpu(vol->vol_flags),
es); es);
unlock_kernel();
return -EROFS; return -EROFS;
} }
if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
ntfs_error(sb, "Failed to set dirty bit in volume " ntfs_error(sb, "Failed to set dirty bit in volume "
"information flags%s", es); "information flags%s", es);
unlock_kernel();
return -EROFS; return -EROFS;
} }
#if 0 #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", ntfs_error(sb, "Failed to empty journal $LogFile%s",
es); es);
NVolSetErrors(vol); NVolSetErrors(vol);
unlock_kernel();
return -EROFS; return -EROFS;
} }
if (!ntfs_mark_quotas_out_of_date(vol)) { if (!ntfs_mark_quotas_out_of_date(vol)) {
ntfs_error(sb, "Failed to mark quotas out of date%s", ntfs_error(sb, "Failed to mark quotas out of date%s",
es); es);
NVolSetErrors(vol); NVolSetErrors(vol);
unlock_kernel();
return -EROFS; return -EROFS;
} }
if (!ntfs_stamp_usnjrnl(vol)) { if (!ntfs_stamp_usnjrnl(vol)) {
ntfs_error(sb, "Failed to stamp transation log " ntfs_error(sb, "Failed to stamp transation log "
"($UsnJrnl)%s", es); "($UsnJrnl)%s", es);
NVolSetErrors(vol); NVolSetErrors(vol);
unlock_kernel();
return -EROFS; return -EROFS;
} }
} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { } 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. // TODO: Deal with *flags.
if (!parse_options(vol, opt)) { if (!parse_options(vol, opt))
unlock_kernel();
return -EINVAL; return -EINVAL;
}
unlock_kernel();
ntfs_debug("Done."); ntfs_debug("Done.");
return 0; return 0;
} }
@ -2261,8 +2249,6 @@ static void ntfs_put_super(struct super_block *sb)
ntfs_debug("Entering."); ntfs_debug("Entering.");
lock_kernel();
#ifdef NTFS_RW #ifdef NTFS_RW
/* /*
* Commit all inodes while they are still open in case some of them * 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; sb->s_fs_info = NULL;
kfree(vol); 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->mftbmp_lock);
init_rwsem(&vol->lcnbmp_lock); init_rwsem(&vol->lcnbmp_lock);
unlock_kernel();
/* By default, enable sparse support. */ /* By default, enable sparse support. */
NVolSetSparseEnabled(vol); NVolSetSparseEnabled(vol);
@ -2940,7 +2922,6 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
} }
mutex_unlock(&ntfs_lock); mutex_unlock(&ntfs_lock);
sb->s_export_op = &ntfs_export_ops; sb->s_export_op = &ntfs_export_ops;
lock_kernel();
lockdep_on(); lockdep_on();
return 0; return 0;
} }
@ -3057,7 +3038,6 @@ iput_tmp_ino_err_out_now:
} }
/* Errors at this stage are irrelevant. */ /* Errors at this stage are irrelevant. */
err_out_now: err_out_now:
lock_kernel();
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(vol); kfree(vol);
ntfs_debug("Failed, returning -EINVAL."); ntfs_debug("Failed, returning -EINVAL.");

View File

@ -22,7 +22,6 @@
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -612,12 +611,10 @@ static int ocfs2_control_open(struct inode *inode, struct file *file)
return -ENOMEM; return -ENOMEM;
p->op_this_node = -1; p->op_this_node = -1;
lock_kernel();
mutex_lock(&ocfs2_control_lock); mutex_lock(&ocfs2_control_lock);
file->private_data = p; file->private_data = p;
list_add(&p->op_list, &ocfs2_control_private_list); list_add(&p->op_list, &ocfs2_control_private_list);
mutex_unlock(&ocfs2_control_lock); mutex_unlock(&ocfs2_control_lock);
unlock_kernel();
return 0; return 0;
} }

View File

@ -630,8 +630,6 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
struct ocfs2_super *osb = OCFS2_SB(sb); struct ocfs2_super *osb = OCFS2_SB(sb);
u32 tmp; u32 tmp;
lock_kernel();
if (!ocfs2_parse_options(sb, data, &parsed_options, 1) || if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
!ocfs2_check_set_options(sb, &parsed_options)) { !ocfs2_check_set_options(sb, &parsed_options)) {
ret = -EINVAL; ret = -EINVAL;
@ -739,7 +737,6 @@ unlock_osb:
MS_POSIXACL : 0); MS_POSIXACL : 0);
} }
out: out:
unlock_kernel();
return ret; return ret;
} }
@ -1696,13 +1693,9 @@ static void ocfs2_put_super(struct super_block *sb)
{ {
mlog_entry("(0x%p)\n", sb); mlog_entry("(0x%p)\n", sb);
lock_kernel();
ocfs2_sync_blockdev(sb); ocfs2_sync_blockdev(sb);
ocfs2_dismount_volume(sb, 0); ocfs2_dismount_volume(sb, 0);
unlock_kernel();
mlog_exit_void(); mlog_exit_void();
} }

View File

@ -11,7 +11,6 @@
* 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support. * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support.
*/ */
#include <linux/smp_lock.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include "qnx4.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 "qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
QNX4DEBUG((KERN_INFO "filp->f_pos = %ld\n", (long) filp->f_pos)); QNX4DEBUG((KERN_INFO "filp->f_pos = %ld\n", (long) filp->f_pos));
lock_kernel();
while (filp->f_pos < inode->i_size) { while (filp->f_pos < inode->i_size) {
blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS ); blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS );
bh = sb_bread(inode->i_sb, blknum); 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); brelse(bh);
} }
out: out:
unlock_kernel();
return 0; return 0;
} }

View File

@ -16,7 +16,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/highuid.h> #include <linux/highuid.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/writeback.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; struct super_block *sb = dentry->d_sb;
u64 id = huge_encode_dev(sb->s_bdev->bd_dev); u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
lock_kernel();
buf->f_type = sb->s_magic; buf->f_type = sb->s_magic;
buf->f_bsize = sb->s_blocksize; buf->f_bsize = sb->s_blocksize;
buf->f_blocks = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size) * 8; 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[0] = (u32)id;
buf->f_fsid.val[1] = (u32)(id >> 32); buf->f_fsid.val[1] = (u32)(id >> 32);
unlock_kernel();
return 0; return 0;
} }
@ -283,7 +278,6 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
goto outi; goto outi;
brelse(bh); brelse(bh);
return 0; return 0;
outi: outi:

View File

@ -12,7 +12,6 @@
* 04-07-1998 by Frank Denis : first step for rmdir/unlink. * 04-07-1998 by Frank Denis : first step for rmdir/unlink.
*/ */
#include <linux/smp_lock.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include "qnx4.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; int len = dentry->d_name.len;
struct inode *foundinode = NULL; struct inode *foundinode = NULL;
lock_kernel();
if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino))) if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
goto out; goto out;
/* The entry is linked, let's get the real info */ /* 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); foundinode = qnx4_iget(dir->i_sb, ino);
if (IS_ERR(foundinode)) { if (IS_ERR(foundinode)) {
unlock_kernel();
QNX4DEBUG((KERN_ERR "qnx4: lookup->iget -> error %ld\n", QNX4DEBUG((KERN_ERR "qnx4: lookup->iget -> error %ld\n",
PTR_ERR(foundinode))); PTR_ERR(foundinode)));
return ERR_CAST(foundinode); return ERR_CAST(foundinode);
} }
out: out:
unlock_kernel();
d_add(dentry, foundinode); d_add(dentry, foundinode);
return NULL; return NULL;

View File

@ -501,6 +501,8 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
void *mem; void *mem;
static int warn_count; static int warn_count;
lock_kernel();
if (warn_count < 5) { if (warn_count < 5) {
warn_count++; warn_count++;
printk(KERN_EMERG "smbfs is deprecated and will be removed" 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); smb_new_dentry(sb->s_root);
unlock_kernel();
return 0; return 0;
out_no_root: out_no_root:
@ -643,9 +646,11 @@ out_wrong_data:
out_no_data: out_no_data:
printk(KERN_ERR "smb_fill_super: missing data argument\n"); printk(KERN_ERR "smb_fill_super: missing data argument\n");
out_fail: out_fail:
unlock_kernel();
return -EINVAL; return -EINVAL;
out_no_server: out_no_server:
printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n"); printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n");
unlock_kernel();
return -ENOMEM; return -ENOMEM;
} }

View File

@ -30,7 +30,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/init.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) static void squashfs_put_super(struct super_block *sb)
{ {
lock_kernel();
if (sb->s_fs_info) { if (sb->s_fs_info) {
struct squashfs_sb_info *sbi = sb->s_fs_info; struct squashfs_sb_info *sbi = sb->s_fs_info;
squashfs_cache_delete(sbi->block_cache); squashfs_cache_delete(sbi->block_cache);
@ -370,8 +367,6 @@ static void squashfs_put_super(struct super_block *sb)
kfree(sb->s_fs_info); kfree(sb->s_fs_info);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
} }
unlock_kernel();
} }

View 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 kernel_lb_addr rootdir, fileset;
struct udf_sb_info *sbi; struct udf_sb_info *sbi;
lock_kernel();
uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
uopt.uid = -1; uopt.uid = -1;
uopt.gid = -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; uopt.dmode = UDF_INVALID_MODE;
sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi) {
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
sb->s_fs_info = sbi; 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; goto error_out;
} }
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
unlock_kernel();
return 0; return 0;
error_out: error_out:
@ -2055,6 +2060,7 @@ error_out:
kfree(sbi); kfree(sbi);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
unlock_kernel();
return -EINVAL; return -EINVAL;
} }

View File

@ -696,6 +696,8 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
unsigned maxsymlen; unsigned maxsymlen;
int ret = -EINVAL; int ret = -EINVAL;
lock_kernel();
uspi = NULL; uspi = NULL;
ubh = NULL; ubh = NULL;
flags = 0; flags = 0;
@ -1163,6 +1165,7 @@ magic_found:
goto failed; goto failed;
UFSD("EXIT\n"); UFSD("EXIT\n");
unlock_kernel();
return 0; return 0;
dalloc_failed: dalloc_failed:
@ -1174,10 +1177,12 @@ failed:
kfree(sbi); kfree(sbi);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
UFSD("EXIT (FAILED)\n"); UFSD("EXIT (FAILED)\n");
unlock_kernel();
return ret; return ret;
failed_nomem: failed_nomem:
UFSD("EXIT (NOMEM)\n"); UFSD("EXIT (NOMEM)\n");
unlock_kernel();
return -ENOMEM; return -ENOMEM;
} }

View File

@ -1093,10 +1093,6 @@ struct file_lock {
#include <linux/fcntl.h> #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); extern void send_sigio(struct fown_struct *fown, int fd, int band);
#ifdef CONFIG_FILE_LOCKING #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 lease_modify(struct file_lock **, int);
extern int lock_may_read(struct inode *, loff_t start, unsigned long count); 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 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 */ #else /* !CONFIG_FILE_LOCKING */
static inline int fcntl_getlk(struct file *file, struct flock __user *user) 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; return 1;
} }
static inline void lock_flocks(void)
{
}
static inline void unlock_flocks(void)
{
}
#endif /* !CONFIG_FILE_LOCKING */ #endif /* !CONFIG_FILE_LOCKING */

View File

@ -241,34 +241,6 @@ int ncp_mmap(struct file *, struct vm_area_struct *);
/* linux/fs/ncpfs/ncplib_kernel.c */ /* linux/fs/ncpfs/ncplib_kernel.c */
int ncp_make_closed(struct inode *); 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 /* __KERNEL__ */
#endif /* _LINUX_NCP_FS_H */ #endif /* _LINUX_NCP_FS_H */

View File

@ -62,6 +62,7 @@ struct ncp_server {
int ncp_reply_size; int ncp_reply_size;
int root_setuped; int root_setuped;
struct mutex root_setup_lock;
/* info for packet signing */ /* info for packet signing */
int sign_wanted; /* 1=Server needs signed packets */ int sign_wanted; /* 1=Server needs signed packets */
@ -81,13 +82,14 @@ struct ncp_server {
size_t len; size_t len;
void* data; void* data;
} priv; } priv;
struct rw_semaphore auth_rwsem;
/* nls info: codepage for volume and charset for I/O */ /* nls info: codepage for volume and charset for I/O */
struct nls_table *nls_vol; struct nls_table *nls_vol;
struct nls_table *nls_io; struct nls_table *nls_io;
/* maximum age in jiffies */ /* maximum age in jiffies */
int dentry_ttl; atomic_t dentry_ttl;
/* miscellaneous */ /* miscellaneous */
unsigned int flags; unsigned int flags;

View File

@ -52,7 +52,6 @@
#include <linux/cgroupstats.h> #include <linux/cgroupstats.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/smp_lock.h>
#include <linux/pid_namespace.h> #include <linux/pid_namespace.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */ #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 *cgrp = &root->top_cgroup;
struct cgroup_sb_opts opts; struct cgroup_sb_opts opts;
lock_kernel();
mutex_lock(&cgrp->dentry->d_inode->i_mutex); mutex_lock(&cgrp->dentry->d_inode->i_mutex);
mutex_lock(&cgroup_mutex); mutex_lock(&cgroup_mutex);
@ -1255,7 +1253,6 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
kfree(opts.name); kfree(opts.name);
mutex_unlock(&cgroup_mutex); mutex_unlock(&cgroup_mutex);
mutex_unlock(&cgrp->dentry->d_inode->i_mutex); mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
unlock_kernel();
return ret; return ret;
} }
@ -1568,7 +1565,6 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
out_err: out_err:
kfree(opts.release_agent); kfree(opts.release_agent);
kfree(opts.name); kfree(opts.name);
return ret; return ret;
} }