Commit 9a41fe34 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
  reiserfs: fix j_last_flush_trans_id type
  fs: Mark get_filesystem_list() as __init function.
  kill vfs_stat_fd / vfs_lstat_fd
  Separate out common fstatat code into vfs_fstatat
  ecryptfs: use memdup_user()
  ncpfs: use memdup_user()
  xfs: use memdup_user()
  sysfs: use memdup_user()
  btrfs: use memdup_user()
  xattr: use memdup_user()
  autofs4: use memchr() in invalid_string()
  Documentation/filesystems: remove out of date reference to BKL being held
  Fix i_mutex vs. readdir handling in nfsd
  fs/compat_ioctl: fix build when !BLOCK
  Fix autofs_expire()
  No need for crossing to mountpoint in audit_tag_tree()
  Safer nfsd_cross_mnt()
  Touch all affected namespaces on propagation of mount
  Fix AUTOFS_DEV_IOCTL_REQUESTER_CMD
parents 8b9cf76d be9208df
...@@ -277,8 +277,7 @@ or bottom half). ...@@ -277,8 +277,7 @@ or bottom half).
unfreeze_fs: called when VFS is unlocking a filesystem and making it writable unfreeze_fs: called when VFS is unlocking a filesystem and making it writable
again. again.
statfs: called when the VFS needs to get filesystem statistics. This statfs: called when the VFS needs to get filesystem statistics.
is called with the kernel lock held
remount_fs: called when the filesystem is remounted. This is called remount_fs: called when the filesystem is remounted. This is called
with the kernel lock held with the kernel lock held
......
...@@ -177,21 +177,12 @@ asmlinkage long sys_oabi_fstatat64(int dfd, ...@@ -177,21 +177,12 @@ asmlinkage long sys_oabi_fstatat64(int dfd,
int flag) int flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) error = vfs_fstatat(dfd, filename, &stat, flag);
goto out; if (error)
return error;
if (flag & AT_SYMLINK_NOFOLLOW) return cp_oldabi_stat64(&stat, statbuf);
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error)
error = cp_oldabi_stat64(&stat, statbuf);
out:
return error;
} }
struct oabi_flock64 { struct oabi_flock64 {
......
...@@ -702,20 +702,12 @@ asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename, ...@@ -702,20 +702,12 @@ asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename,
struct stat64_emu31 __user* statbuf, int flag) struct stat64_emu31 __user* statbuf, int flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error) error = vfs_fstatat(dfd, filename, &stat, flag);
error = cp_stat64(statbuf, &stat); if (error)
out: return error;
return error; return cp_stat64(statbuf, &stat);
} }
/* /*
......
...@@ -206,21 +206,12 @@ asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename, ...@@ -206,21 +206,12 @@ asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename,
struct compat_stat64 __user * statbuf, int flag) struct compat_stat64 __user * statbuf, int flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error)
error = cp_compat_stat64(&stat, statbuf);
out: error = vfs_fstatat(dfd, filename, &stat, flag);
return error; if (error)
return error;
return cp_compat_stat64(&stat, statbuf);
} }
asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
......
...@@ -129,21 +129,12 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename, ...@@ -129,21 +129,12 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
struct stat64 __user *statbuf, int flag) struct stat64 __user *statbuf, int flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) error = vfs_fstatat(dfd, filename, &stat, flag);
goto out; if (error)
return error;
if (flag & AT_SYMLINK_NOFOLLOW) return cp_stat64(statbuf, &stat);
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error)
error = cp_stat64(statbuf, &stat);
out:
return error;
} }
/* /*
......
...@@ -39,10 +39,12 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, ...@@ -39,10 +39,12 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
{ {
struct autofs_dirhash *dh = &sbi->dirhash; struct autofs_dirhash *dh = &sbi->dirhash;
struct autofs_dir_ent *ent; struct autofs_dir_ent *ent;
struct dentry *dentry;
unsigned long timeout = sbi->exp_timeout; unsigned long timeout = sbi->exp_timeout;
while (1) { while (1) {
struct path path;
int umount_ok;
if ( list_empty(&dh->expiry_head) || sbi->catatonic ) if ( list_empty(&dh->expiry_head) || sbi->catatonic )
return NULL; /* No entries */ return NULL; /* No entries */
/* We keep the list sorted by last_usage and want old stuff */ /* We keep the list sorted by last_usage and want old stuff */
...@@ -57,17 +59,17 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, ...@@ -57,17 +59,17 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
return ent; /* Symlinks are always expirable */ return ent; /* Symlinks are always expirable */
/* Get the dentry for the autofs subdirectory */ /* Get the dentry for the autofs subdirectory */
dentry = ent->dentry; path.dentry = ent->dentry;
if ( !dentry ) { if (!path.dentry) {
/* Should only happen in catatonic mode */ /* Should only happen in catatonic mode */
printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name); printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
autofs_delete_usage(ent); autofs_delete_usage(ent);
continue; continue;
} }
if ( !dentry->d_inode ) { if (!path.dentry->d_inode) {
dput(dentry); dput(path.dentry);
printk("autofs: negative dentry on expiry queue: %s\n", printk("autofs: negative dentry on expiry queue: %s\n",
ent->name); ent->name);
autofs_delete_usage(ent); autofs_delete_usage(ent);
...@@ -76,29 +78,29 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, ...@@ -76,29 +78,29 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
/* Make sure entry is mounted and unused; note that dentry will /* Make sure entry is mounted and unused; note that dentry will
point to the mounted-on-top root. */ point to the mounted-on-top root. */
if (!S_ISDIR(dentry->d_inode->i_mode)||!d_mountpoint(dentry)) { if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
!d_mountpoint(path.dentry)) {
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
continue; continue;
} }
mntget(mnt); path.mnt = mnt;
dget(dentry); path_get(&path);
if (!follow_down(&mnt, &dentry)) { if (!follow_down(&path.mnt, &path.dentry)) {
dput(dentry); path_put(&path);
mntput(mnt);
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
continue; continue;
} }
while (d_mountpoint(dentry) && follow_down(&mnt, &dentry)) while (d_mountpoint(path.dentry) &&
follow_down(&path.mnt, &path.dentry))
; ;
dput(dentry); umount_ok = may_umount(path.mnt);
path_put(&path);
if ( may_umount(mnt) ) { if (umount_ok) {
mntput(mnt);
DPRINTK(("autofs: signaling expire on %s\n", ent->name)); DPRINTK(("autofs: signaling expire on %s\n", ent->name));
return ent; /* Expirable! */ return ent; /* Expirable! */
} }
DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name)); DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
mntput(mnt);
} }
return NULL; /* No expirable entries */ return NULL; /* No expirable entries */
} }
......
...@@ -54,11 +54,10 @@ static int check_name(const char *name) ...@@ -54,11 +54,10 @@ static int check_name(const char *name)
* Check a string doesn't overrun the chunk of * Check a string doesn't overrun the chunk of
* memory we copied from user land. * memory we copied from user land.
*/ */
static int invalid_str(char *str, void *end) static int invalid_str(char *str, size_t size)
{ {
while ((void *) str <= end) if (memchr(str, 0, size))
if (!*str++) return 0;
return 0;
return -EINVAL; return -EINVAL;
} }
...@@ -138,8 +137,7 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) ...@@ -138,8 +137,7 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
} }
if (param->size > sizeof(*param)) { if (param->size > sizeof(*param)) {
err = invalid_str(param->path, err = invalid_str(param->path, param->size - sizeof(*param));
(void *) ((size_t) param + param->size));
if (err) { if (err) {
AUTOFS_WARN( AUTOFS_WARN(
"path string terminator missing for cmd(0x%08x)", "path string terminator missing for cmd(0x%08x)",
...@@ -488,7 +486,7 @@ static int autofs_dev_ioctl_requester(struct file *fp, ...@@ -488,7 +486,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
} }
path = param->path; path = param->path;
devid = sbi->sb->s_dev; devid = new_encode_dev(sbi->sb->s_dev);
param->requester.uid = param->requester.gid = -1; param->requester.uid = param->requester.gid = -1;
......
...@@ -461,15 +461,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) ...@@ -461,15 +461,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
if (!vol_args) return PTR_ERR(vol_args);
return -ENOMEM;
if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
ret = -EFAULT;
goto out;
}
vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
namelen = strlen(vol_args->name); namelen = strlen(vol_args->name);
...@@ -545,7 +539,6 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) ...@@ -545,7 +539,6 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
out_unlock: out_unlock:
mutex_unlock(&root->fs_info->volume_mutex); mutex_unlock(&root->fs_info->volume_mutex);
out:
kfree(vol_args); kfree(vol_args);
return ret; return ret;
} }
...@@ -565,15 +558,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, ...@@ -565,15 +558,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
if (root->fs_info->sb->s_flags & MS_RDONLY) if (root->fs_info->sb->s_flags & MS_RDONLY)
return -EROFS; return -EROFS;
vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
if (!vol_args) return PTR_ERR(vol_args);
return -ENOMEM;
if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
ret = -EFAULT;
goto out;
}
vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
namelen = strlen(vol_args->name); namelen = strlen(vol_args->name);
...@@ -675,19 +662,13 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) ...@@ -675,19 +662,13 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
return PTR_ERR(vol_args);
if (!vol_args)
return -ENOMEM;
if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
ret = -EFAULT;
goto out;
}
vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
ret = btrfs_init_new_device(root, vol_args->name); ret = btrfs_init_new_device(root, vol_args->name);
out:
kfree(vol_args); kfree(vol_args);
return ret; return ret;
} }
...@@ -703,19 +684,13 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) ...@@ -703,19 +684,13 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
if (root->fs_info->sb->s_flags & MS_RDONLY) if (root->fs_info->sb->s_flags & MS_RDONLY)
return -EROFS; return -EROFS;
vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
return PTR_ERR(vol_args);
if (!vol_args)
return -ENOMEM;
if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
ret = -EFAULT;
goto out;
}
vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
ret = btrfs_rm_device(root, vol_args->name); ret = btrfs_rm_device(root, vol_args->name);
out:
kfree(vol_args); kfree(vol_args);
return ret; return ret;
} }
......
...@@ -635,14 +635,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, ...@@ -635,14 +635,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
vol = kmalloc(sizeof(*vol), GFP_KERNEL); vol = memdup_user((void __user *)arg, sizeof(*vol));
if (!vol) if (IS_ERR(vol))
return -ENOMEM; return PTR_ERR(vol);
if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
ret = -EFAULT;
goto out;
}
switch (cmd) { switch (cmd) {
case BTRFS_IOC_SCAN_DEV: case BTRFS_IOC_SCAN_DEV:
...@@ -650,7 +645,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, ...@@ -650,7 +645,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
&btrfs_fs_type, &fs_devices); &btrfs_fs_type, &fs_devices);
break; break;
} }
out:
kfree(vol); kfree(vol);
return ret; return ret;
} }
......
...@@ -181,22 +181,24 @@ asmlinkage long compat_sys_newstat(char __user * filename, ...@@ -181,22 +181,24 @@ asmlinkage long compat_sys_newstat(char __user * filename,
struct compat_stat __user *statbuf) struct compat_stat __user *statbuf)
{ {
struct kstat stat; struct kstat stat;
int error = vfs_stat_fd(AT_FDCWD, filename, &stat); int error;
if (!error) error = vfs_stat(filename, &stat);
error = cp_compat_stat(&stat, statbuf); if (error)
return error; return error;
return cp_compat_stat(&stat, statbuf);
} }
asmlinkage long compat_sys_newlstat(char __user * filename, asmlinkage long compat_sys_newlstat(char __user * filename,
struct compat_stat __user *statbuf) struct compat_stat __user *statbuf)
{ {
struct kstat stat; struct kstat stat;
int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); int error;
if (!error) error = vfs_lstat(filename, &stat);
error = cp_compat_stat(&stat, statbuf); if (error)
return error; return error;
return cp_compat_stat(&stat, statbuf);
} }
#ifndef __ARCH_WANT_STAT64 #ifndef __ARCH_WANT_STAT64
...@@ -204,21 +206,12 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename, ...@@ -204,21 +206,12 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename,
struct compat_stat __user *statbuf, int flag) struct compat_stat __user *statbuf, int flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error)
error = cp_compat_stat(&stat, statbuf);
out: error = vfs_fstatat(dfd, filename, &stat, flag);
return error; if (error)
return error;
return cp_compat_stat(&stat, statbuf);
} }
#endif #endif
......
...@@ -58,7 +58,6 @@ ...@@ -58,7 +58,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-dev.h> #include <linux/i2c-dev.h>
#include <linux/atalk.h> #include <linux/atalk.h>
#include <linux/loop.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h> #include <net/bluetooth/hci.h>
...@@ -68,6 +67,7 @@ ...@@ -68,6 +67,7 @@
#include <linux/gigaset_dev.h> #include <linux/gigaset_dev.h>
#ifdef CONFIG_BLOCK #ifdef CONFIG_BLOCK
#include <linux/loop.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/sg.h> #include <scsi/sg.h>
...@@ -2660,6 +2660,8 @@ HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) ...@@ -2660,6 +2660,8 @@ HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
/* block stuff */ /* block stuff */
#ifdef CONFIG_BLOCK #ifdef CONFIG_BLOCK
/* loop */
IGNORE_IOCTL(LOOP_CLR_FD)
/* Raw devices */ /* Raw devices */
HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
...@@ -2728,9 +2730,6 @@ HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) ...@@ -2728,9 +2730,6 @@ HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans)
IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32) IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32)
IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32) IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32)
/* loop */
IGNORE_IOCTL(LOOP_CLR_FD)
#ifdef CONFIG_SPARC #ifdef CONFIG_SPARC
/* Sparc framebuffers, handled in sbusfb_compat_ioctl() */ /* Sparc framebuffers, handled in sbusfb_compat_ioctl() */
IGNORE_IOCTL(FBIOGTYPE) IGNORE_IOCTL(FBIOGTYPE)
......
...@@ -2149,7 +2149,6 @@ int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry) ...@@ -2149,7 +2149,6 @@ int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
int result; int result;
unsigned long seq; unsigned long seq;
/* FIXME: This is old behavior, needed? Please check callers. */
if (new_dentry == old_dentry) if (new_dentry == old_dentry)
return 1; return 1;
......
...@@ -418,18 +418,13 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, ...@@ -418,18 +418,13 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
if (count == 0) if (count == 0)
goto out; goto out;
data = kmalloc(count, GFP_KERNEL);
if (!data) { data = memdup_user(buf, count);
printk(KERN_ERR "%s: Out of memory whilst attempting to " if (IS_ERR(data)) {
"kmalloc([%zd], GFP_KERNEL)\n", __func__, count); printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
__func__, PTR_ERR(data));
goto out; goto out;
} }
rc = copy_from_user(data, buf, count);
if (rc) {
printk(KERN_ERR "%s: copy_from_user returned error [%d]\n",
__func__, rc);
goto out_free;
}
sz = count; sz = count;
i = 0; i = 0;
switch (data[i++]) { switch (data[i++]) {
......
...@@ -199,7 +199,7 @@ SYSCALL_DEFINE3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2) ...@@ -199,7 +199,7 @@ SYSCALL_DEFINE3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2)
return retval; return retval;
} }
int get_filesystem_list(char * buf) int __init get_filesystem_list(char *buf)
{ {
int len = 0; int len = 0;
struct file_system_type * tmp; struct file_system_type * tmp;
......
...@@ -1248,6 +1248,8 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) ...@@ -1248,6 +1248,8 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
int err; int err;
struct qstr this; struct qstr this;
WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
err = __lookup_one_len(name, &this, base, len); err = __lookup_one_len(name, &this, base, len);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
......
...@@ -1377,7 +1377,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, ...@@ -1377,7 +1377,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
if (parent_path) { if (parent_path) {
detach_mnt(source_mnt, parent_path); detach_mnt(source_mnt, parent_path);
attach_mnt(source_mnt, path); attach_mnt(source_mnt, path);
touch_mnt_namespace(current->nsproxy->mnt_ns); touch_mnt_namespace(parent_path->mnt->mnt_ns);
} else { } else {
mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
commit_tree(source_mnt); commit_tree(source_mnt);
......
...@@ -660,13 +660,10 @@ outrel: ...@@ -660,13 +660,10 @@ outrel:
if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN) if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
return -ENOMEM; return -ENOMEM;
if (user.object_name_len) { if (user.object_name_len) {
newname = kmalloc(user.object_name_len, GFP_USER); newname = memdup_user(user.object_name,
if (!newname) user.object_name_len);
return -ENOMEM; if (IS_ERR(newname))
if (copy_from_user(newname, user.object_name, user.object_name_len)) { return PTR_ERR(newname);
kfree(newname);
return -EFAULT;
}
} else { } else {
newname = NULL; newname = NULL;
} }
...@@ -760,13 +757,9 @@ outrel: ...@@ -760,13 +757,9 @@ outrel:
if (user.len > NCP_PRIVATE_DATA_MAX_LEN) if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
return -ENOMEM; return -ENOMEM;
if (user.len) { if (user.len) {
new = kmalloc(user.len, GFP_USER); new = memdup_user(user.data, user.len);
if (!new) if (IS_ERR(new))
return -ENOMEM; return PTR_ERR(new);
if (copy_from_user(new, user.data, user.len)) {
kfree(new);
return -EFAULT;
}
} else { } else {
new = NULL; new = NULL;
} }
......
...@@ -229,21 +229,23 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) ...@@ -229,21 +229,23 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
goto out; goto out;
status = vfs_readdir(filp, nfsd4_build_namelist, &names); status = vfs_readdir(filp, nfsd4_build_namelist, &names);
fput(filp); fput(filp);
mutex_lock(&dir->d_inode->i_mutex);
while (!list_empty(&names)) { while (!list_empty(&names)) {
entry = list_entry(names.next, struct name_list, list); entry = list_entry(names.next, struct name_list, list);
dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1); dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
status = PTR_ERR(dentry); status = PTR_ERR(dentry);
goto out; break;
} }
status = f(dir, dentry); status = f(dir, dentry);
dput(dentry); dput(dentry);
if (status) if (status)
goto out; break;
list_del(&entry->list); list_del(&entry->list);
kfree(entry); kfree(entry);
} }
mutex_unlock(&dir->d_inode->i_mutex);
out: out:
while (!list_empty(&names)) { while (!list_empty(&names)) {
entry = list_entry(names.next, struct name_list, list); entry = list_entry(names.next, struct name_list, list);
...@@ -254,36 +256,6 @@ out: ...@@ -254,36 +256,6 @@ out:
return status; return status;
} }
static int
nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry)
{
int status;
if (!S_ISREG(dir->d_inode->i_mode)) {
printk("nfsd4: non-file found in client recovery directory\n");
return -EINVAL;
}
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
status = vfs_unlink(dir->d_inode, dentry);
mutex_unlock(&dir->d_inode->i_mutex);
return status;
}
static int
nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry)
{
int status;
/* For now this directory should already be empty, but we empty it of
* any regular files anyway, just in case the directory was created by
* a kernel from the future.... */
nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
status = vfs_rmdir(dir->d_inode, dentry);
mutex_unlock(&dir->d_inode->i_mutex);
return status;
}
static int static int
nfsd4_unlink_clid_dir(char *name, int namlen) nfsd4_unlink_clid_dir(char *name, int namlen)
{ {
...@@ -294,18 +266,18 @@ nfsd4_unlink_clid_dir(char *name, int namlen) ...@@ -294,18 +266,18 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
mutex_lock(&rec_dir.dentry->d_inode->i_mutex); mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
dentry = lookup_one_len(name, rec_dir.dentry, namlen); dentry = lookup_one_len(name, rec_dir.dentry, namlen);
mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
status = PTR_ERR(dentry); status = PTR_ERR(dentry);
return status; goto out_unlock;
} }
status = -ENOENT; status = -ENOENT;
if (!dentry->d_inode) if (!dentry->d_inode)
goto out; goto out;
status = vfs_rmdir(rec_dir.dentry->d_inode, dentry);
status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
out: out:
dput(dentry); dput(dentry);
out_unlock:
mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
return status; return status;
} }
...@@ -348,7 +320,7 @@ purge_old(struct dentry *parent, struct dentry *child) ...@@ -348,7 +320,7 @@ purge_old(struct dentry *parent, struct dentry *child)
if (nfs4_has_reclaimed_state(child->d_name.name, false)) if (nfs4_has_reclaimed_state(child->d_name.name, false))
return 0; return 0;
status = nfsd4_clear_clid_dir(parent, child); status = vfs_rmdir(parent->d_inode, child);
if (status) if (status)
printk("failed to remove client recovery directory %s\n", printk("failed to remove client recovery directory %s\n",
child->d_name.name); child->d_name.name);
......
...@@ -116,10 +116,15 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, ...@@ -116,10 +116,15 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
} }
if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) {
/* successfully crossed mount point */ /* successfully crossed mount point */
exp_put(exp); /*
*expp = exp2; * This is subtle: dentry is *not* under mnt at this point.
* The only reason we are safe is that original mnt is pinned
* down by exp, so we should dput before putting exp.
*/
dput(dentry); dput(dentry);
*dpp = mounts; *dpp = mounts;
exp_put(exp);
*expp = exp2;
} else { } else {
exp_put(exp2); exp_put(exp2);
dput(mounts); dput(mounts);
...@@ -1885,8 +1890,8 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, ...@@ -1885,8 +1890,8 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen,
return 0; return 0;
} }
static int nfsd_buffered_readdir(struct file *file, filldir_t func, static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func,
struct readdir_cd *cdp, loff_t *offsetp) struct readdir_cd *cdp, loff_t *offsetp)
{ {
struct readdir_data buf; struct readdir_data buf;
struct buffered_dirent *de; struct buffered_dirent *de;
...@@ -1896,11 +1901,12 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func, ...@@ -1896,11 +1901,12 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
buf.dirent = (void *)__get_free_page(GFP_KERNEL); buf.dirent = (void *)__get_free_page(GFP_KERNEL);
if (!buf.dirent) if (!buf.dirent)
return -ENOMEM; return nfserrno(-ENOMEM);
offset = *offsetp; offset = *offsetp;
while (1) { while (1) {
struct inode *dir_inode = file->f_path.dentry->d_inode;
unsigned int reclen; unsigned int reclen;
cdp->err = nfserr_eof; /* will be cleared on successful read */ cdp->err = nfserr_eof; /* will be cleared on successful read */
...@@ -1919,26 +1925,38 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func, ...@@ -1919,26 +1925,38 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
if (!size) if (!size)
break; break;
/*
* Various filldir functions may end up calling back into
* lookup_one_len() and the file system's ->lookup() method.
* These expect i_mutex to be held, as it would within readdir.
*/
host_err = mutex_lock_killable(&dir_inode->i_mutex);
if (host_err)
break;
de = (struct buffered_dirent *)buf.dirent; de = (struct buffered_dirent *)buf.dirent;
while (size > 0) { while (size > 0) {
offset = de->offset; offset = de->offset;
if (func(cdp, de->name, de->namlen, de->offset, if (func(cdp, de->name, de->namlen, de->offset,
de->ino, de->d_type)) de->ino, de->d_type))
goto done; break;
if (cdp->err != nfs_ok) if (cdp->err != nfs_ok)
goto done; break;
reclen = ALIGN(sizeof(*de) + de->namlen, reclen = ALIGN(sizeof(*de) + de->namlen,
sizeof(u64)); sizeof(u64));
size -= reclen; size -= reclen;
de = (struct buffered_dirent *)((char *)de + reclen); de = (struct buffered_dirent *)((char *)de + reclen);
} }
mutex_unlock(&dir_inode->i_mutex);
if (size > 0) /* We bailed out early */
break;
offset = vfs_llseek(file, 0, SEEK_CUR); offset = vfs_llseek(file, 0, SEEK_CUR);
} }
done:
free_page((unsigned long)(buf.dirent)); free_page((unsigned long)(buf.dirent));
if (host_err) if (host_err)
......
...@@ -55,59 +55,54 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ...@@ -55,59 +55,54 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
EXPORT_SYMBOL(vfs_getattr); EXPORT_SYMBOL(vfs_getattr);
int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) int vfs_fstat(unsigned int fd, struct kstat *stat)
{ {
struct path path; struct file *f = fget(fd);
int error; int error = -EBADF;
error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path); if (f) {
if (!error) { error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
error = vfs_getattr(path.mnt, path.dentry, stat); fput(f);
path_put(&path);
} }
return error; return error;
} }
EXPORT_SYMBOL(vfs_fstat);
int vfs_stat(char __user *name, struct kstat *stat) int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag)
{ {
return vfs_stat_fd(AT_FDCWD, name, stat); struct path path;
} int error = -EINVAL;
int lookup_flags = 0;
EXPORT_SYMBOL(vfs_stat); if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
goto out;
int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) if (!(flag & AT_SYMLINK_NOFOLLOW))
{ lookup_flags |= LOOKUP_FOLLOW;
struct path path;
int error;
error = user_path_at(dfd, name, 0, &path); error = user_path_at(dfd, filename, lookup_flags, &path);
if (!error) { if (error)
error = vfs_getattr(path.mnt, path.dentry, stat); goto out;
path_put(&path);
} error = vfs_getattr(path.mnt, path.dentry, stat);
path_put(&path);
out:
return error; return error;
} }
EXPORT_SYMBOL(vfs_fstatat);
int vfs_lstat(char __user *name, struct kstat *stat) int vfs_stat(char __user *name, struct kstat *stat)
{ {
return vfs_lstat_fd(AT_FDCWD, name, stat); return vfs_fstatat(AT_FDCWD, name, stat, 0);
} }
EXPORT_SYMBOL(vfs_stat);
EXPORT_SYMBOL(vfs_lstat); int vfs_lstat(char __user *name, struct kstat *stat)
int vfs_fstat(unsigned int fd, struct kstat *stat)
{ {
struct file *f = fget(fd); return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW);
int error = -EBADF;
if (f) {
error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
fput(f);
}
return error;
} }
EXPORT_SYMBOL(vfs_lstat);
EXPORT_SYMBOL(vfs_fstat);
#ifdef __ARCH_WANT_OLD_STAT #ifdef __ARCH_WANT_OLD_STAT
...@@ -155,23 +150,25 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta ...@@ -155,23 +150,25 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
{ {
struct kstat stat; struct kstat stat;
int error = vfs_stat_fd(AT_FDCWD, filename, &stat); int error;
if (!error) error = vfs_stat(filename, &stat);
error = cp_old_stat(&stat, statbuf); if (error)
return error;
return error; return cp_old_stat(&stat, statbuf);
} }
SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
{ {
struct kstat stat; struct kstat stat;
int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); int error;
if (!error) error = vfs_lstat(filename, &stat);
error = cp_old_stat(&stat, statbuf); if (error)
return error;
return error; return cp_old_stat(&stat, statbuf);
} }
SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
...@@ -240,23 +237,23 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) ...@@ -240,23 +237,23 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf) SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf)
{ {
struct kstat stat; struct kstat stat;
int error = vfs_stat_fd(AT_FDCWD, filename, &stat); int error = vfs_stat(filename, &stat);
if (!error)
error = cp_new_stat(&stat, statbuf);
return error; if (error)
return error;
return cp_new_stat(&stat, statbuf);
} }
SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf) SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf)
{ {
struct kstat stat; struct kstat stat;
int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); int error;
if (!error) error = vfs_lstat(filename, &stat);
error = cp_new_stat(&stat, statbuf); if (error)
return error;
return error; return cp_new_stat(&stat, statbuf);
} }
#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
...@@ -264,21 +261,12 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename, ...@@ -264,21 +261,12 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename,
struct stat __user *, statbuf, int, flag) struct stat __user *, statbuf, int, flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error)
error = cp_new_stat(&stat, statbuf);
out: error = vfs_fstatat(dfd, filename, &stat, flag);
return error; if (error)
return error;
return cp_new_stat(&stat, statbuf);
} }
#endif #endif
...@@ -404,21 +392,12 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename, ...@@ -404,21 +392,12 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename,
struct stat64 __user *, statbuf, int, flag) struct stat64 __user *, statbuf, int, flag)
{ {
struct kstat stat; struct kstat stat;
int error = -EINVAL; int error;
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
goto out;
if (flag & AT_SYMLINK_NOFOLLOW)
error = vfs_lstat_fd(dfd, filename, &stat);
else
error = vfs_stat_fd(dfd, filename, &stat);
if (!error)
error = cp_new_stat64(&stat, statbuf);
out: error = vfs_fstatat(dfd, filename, &stat, flag);
return error; if (error)
return error;
return cp_new_stat64(&stat, statbuf);
} }
#endif /* __ARCH_WANT_STAT64 */ #endif /* __ARCH_WANT_STAT64 */
......
...@@ -157,14 +157,9 @@ static ssize_t write(struct file *file, const char __user *userbuf, ...@@ -157,14 +157,9 @@ static ssize_t write(struct file *file, const char __user *userbuf,
count = size - offs; count = size - offs;
} }
temp = kmalloc(count, GFP_KERNEL); temp = memdup_user(userbuf, count);
if (!temp) if (IS_ERR(temp))
return -ENOMEM; return PTR_ERR(temp);
if (copy_from_user(temp, userbuf, count)) {
count = -EFAULT;
goto out_free;
}
mutex_lock(&bb->mutex); mutex_lock(&bb->mutex);
...@@ -176,8 +171,6 @@ static ssize_t write(struct file *file, const char __user *userbuf, ...@@ -176,8 +171,6 @@ static ssize_t write(struct file *file, const char __user *userbuf,
if (count > 0) if (count > 0)
*off = offs + count; *off = offs + count;
out_free:
kfree(temp);
return count; return count;
} }
......
...@@ -237,13 +237,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, ...@@ -237,13 +237,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
if (size) { if (size) {
if (size > XATTR_SIZE_MAX) if (size > XATTR_SIZE_MAX)
return -E2BIG; return -E2BIG;
kvalue = kmalloc(size, GFP_KERNEL); kvalue = memdup_user(value, size);
if (!kvalue) if (IS_ERR(kvalue))
return -ENOMEM; return PTR_ERR(kvalue);
if (copy_from_user(kvalue, value, size)) {
kfree(kvalue);
return -EFAULT;
}
} }
error = vfs_setxattr(d, kname, kvalue, size, flags); error = vfs_setxattr(d, kname, kvalue, size, flags);
......
...@@ -489,17 +489,12 @@ xfs_attrmulti_attr_set( ...@@ -489,17 +489,12 @@ xfs_attrmulti_attr_set(
if (len > XATTR_SIZE_MAX) if (len > XATTR_SIZE_MAX)
return EINVAL; return EINVAL;
kbuf = kmalloc(len, GFP_KERNEL); kbuf = memdup_user(ubuf, len);
if (!kbuf) if (IS_ERR(kbuf))
return ENOMEM; return PTR_ERR(kbuf);
if (copy_from_user(kbuf, ubuf, len))
goto out_kfree;
error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
out_kfree:
kfree(kbuf);
return error; return error;
} }
...@@ -540,20 +535,16 @@ xfs_attrmulti_by_handle( ...@@ -540,20 +535,16 @@ xfs_attrmulti_by_handle(
if (!size || size > 16 * PAGE_SIZE) if (!size || size > 16 * PAGE_SIZE)
goto out_dput; goto out_dput;
error = ENOMEM; ops = memdup_user(am_hreq.ops, size);
ops = kmalloc(size, GFP_KERNEL); if (IS_ERR(ops)) {
if (!ops) error = PTR_ERR(ops);
goto out_dput; goto out_dput;
}
error = EFAULT;
if (copy_from_user(ops, am_hreq.ops, size))
goto out_kfree_ops;
attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
if (!attr_name) if (!attr_name)
goto out_kfree_ops; goto out_kfree_ops;
error = 0; error = 0;
for (i = 0; i < am_hreq.opcount; i++) { for (i = 0; i < am_hreq.opcount; i++) {
ops[i].am_error = strncpy_from_user(attr_name, ops[i].am_error = strncpy_from_user(attr_name,
......
...@@ -427,20 +427,16 @@ xfs_compat_attrmulti_by_handle( ...@@ -427,20 +427,16 @@ xfs_compat_attrmulti_by_handle(
if (!size || size > 16 * PAGE_SIZE) if (!size || size > 16 * PAGE_SIZE)
goto out_dput; goto out_dput;
error = ENOMEM; ops = memdup_user(compat_ptr(am_hreq.ops), size);
ops = kmalloc(size, GFP_KERNEL); if (IS_ERR(ops)) {
if (!ops) error = PTR_ERR(ops);
goto out_dput; goto out_dput;
}
error = EFAULT;
if (copy_from_user(ops, compat_ptr(am_hreq.ops), size))
goto out_kfree_ops;
attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
if (!attr_name) if (!attr_name)
goto out_kfree_ops; goto out_kfree_ops;
error = 0; error = 0;
for (i = 0; i < am_hreq.opcount; i++) { for (i = 0; i < am_hreq.opcount; i++) {
ops[i].am_error = strncpy_from_user(attr_name, ops[i].am_error = strncpy_from_user(attr_name,
......
...@@ -2299,9 +2299,8 @@ extern int vfs_readdir(struct file *, filldir_t, void *); ...@@ -2299,9 +2299,8 @@ extern int vfs_readdir(struct file *, filldir_t, void *);
extern int vfs_stat(char __user *, struct kstat *); extern int vfs_stat(char __user *, struct kstat *);
extern int vfs_lstat(char __user *, struct kstat *); extern int vfs_lstat(char __user *, struct kstat *);
extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
extern int vfs_fstat(unsigned int, struct kstat *); extern int vfs_fstat(unsigned int, struct kstat *);
extern int vfs_fstatat(int , char __user *, struct kstat *, int);
extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
unsigned long arg); unsigned long arg);
...@@ -2449,7 +2448,7 @@ struct ctl_table; ...@@ -2449,7 +2448,7 @@ struct ctl_table;
int proc_nr_files(struct ctl_table *table, int write, struct file *filp, int proc_nr_files(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos); void __user *buffer, size_t *lenp, loff_t *ppos);
int get_filesystem_list(char * buf); int __init get_filesystem_list(char *buf);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_FS_H */ #endif /* _LINUX_FS_H */
...@@ -193,7 +193,7 @@ struct reiserfs_journal { ...@@ -193,7 +193,7 @@ struct reiserfs_journal {
atomic_t j_wcount; /* count of writers for current commit */ atomic_t j_wcount; /* count of writers for current commit */
unsigned long j_bcount; /* batch count. allows turning X transactions into 1 */ unsigned long j_bcount; /* batch count. allows turning X transactions into 1 */
unsigned long j_first_unflushed_offset; /* first unflushed transactions offset */ unsigned long j_first_unflushed_offset; /* first unflushed transactions offset */
unsigned long j_last_flush_trans_id; /* last fully flushed journal timestamp */ unsigned j_last_flush_trans_id; /* last fully flushed journal timestamp */
struct buffer_head *j_header_bh; struct buffer_head *j_header_bh;
time_t j_trans_start_time; /* time this transaction started */ time_t j_trans_start_time; /* time this transaction started */
......
...@@ -734,9 +734,6 @@ int audit_tag_tree(char *old, char *new) ...@@ -734,9 +734,6 @@ int audit_tag_tree(char *old, char *new)
dentry = dget(path.dentry); dentry = dget(path.dentry);
path_put(&path); path_put(&path);
if (dentry == tagged->mnt_root && dentry == mnt->mnt_root)
follow_up(&mnt, &dentry);
list_add_tail(&list, &tagged->mnt_list); list_add_tail(&list, &tagged->mnt_list);
mutex_lock(&audit_filter_mutex); mutex_lock(&audit_filter_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment