Browse Source

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

Pull second vfs pile from Al Viro:
 "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the
  deadlock reproduced by xfstests 068), symlink and hardlink restriction
  patches, plus assorted cleanups and fixes.

  Note that another fsfreeze deadlock (emergency thaw one) is *not*
  dealt with - the series by Fernando conflicts a lot with Jan's, breaks
  userland ABI (FIFREEZE semantics gets changed) and trades the deadlock
  for massive vfsmount leak; this is going to be handled next cycle.
  There probably will be another pull request, but that stuff won't be
  in it."

Fix up trivial conflicts due to unrelated changes next to each other in
drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c}

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits)
  delousing target_core_file a bit
  Documentation: Correct s_umount state for freeze_fs/unfreeze_fs
  fs: Remove old freezing mechanism
  ext2: Implement freezing
  btrfs: Convert to new freezing mechanism
  nilfs2: Convert to new freezing mechanism
  ntfs: Convert to new freezing mechanism
  fuse: Convert to new freezing mechanism
  gfs2: Convert to new freezing mechanism
  ocfs2: Convert to new freezing mechanism
  xfs: Convert to new freezing code
  ext4: Convert to new freezing mechanism
  fs: Protect write paths by sb_start_write - sb_end_write
  fs: Skip atime update on frozen filesystem
  fs: Add freezing handling to mnt_want_write() / mnt_drop_write()
  fs: Improve filesystem freezing handling
  switch the protection of percpu_counter list to spinlock
  nfsd: Push mnt_want_write() outside of i_mutex
  btrfs: Push mnt_want_write() outside of i_mutex
  fat: Push mnt_want_write() outside of i_mutex
  ...
master
Linus Torvalds 9 years ago
parent
commit
a0e881b7c1
  1. 4
      Documentation/filesystems/Locking
  2. 42
      Documentation/sysctl/fs.txt
  3. 77
      arch/powerpc/platforms/cell/spufs/inode.c
  4. 2
      arch/powerpc/platforms/cell/spufs/syscalls.c
  5. 9
      drivers/base/devtmpfs.c
  6. 2
      drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
  7. 31
      drivers/staging/bcm/Misc.c
  8. 7
      drivers/staging/gdm72xx/sdio_boot.c
  9. 22
      drivers/staging/gdm72xx/usb_boot.c
  10. 32
      drivers/target/target_core_file.c
  11. 12
      drivers/usb/gadget/storage_common.c
  12. 6
      drivers/usb/gadget/u_uac1.c
  13. 2
      drivers/video/fb_defio.c
  14. 3
      fs/9p/vfs_file.c
  15. 3
      fs/btrfs/disk-io.c
  16. 3
      fs/btrfs/file.c
  17. 6
      fs/btrfs/inode.c
  18. 15
      fs/btrfs/ioctl.c
  19. 7
      fs/btrfs/transaction.c
  20. 28
      fs/buffer.c
  21. 3
      fs/ceph/addr.c
  22. 30
      fs/ecryptfs/inode.c
  23. 19
      fs/exec.c
  24. 5
      fs/ext2/inode.c
  25. 33
      fs/ext2/super.c
  26. 15
      fs/ext4/inode.c
  27. 6
      fs/ext4/mmp.c
  28. 31
      fs/ext4/super.c
  29. 15
      fs/fat/file.c
  30. 4
      fs/file_table.c
  31. 4
      fs/fuse/file.c
  32. 18
      fs/gfs2/file.c
  33. 4
      fs/gfs2/trans.c
  34. 12
      fs/inode.c
  35. 4
      fs/internal.h
  36. 14
      fs/lockd/clntproc.c
  37. 1
      fs/lockd/svc4proc.c
  38. 1
      fs/lockd/svclock.c
  39. 1
      fs/lockd/svcproc.c
  40. 313
      fs/namei.c
  41. 97
      fs/namespace.c
  42. 9
      fs/nfsd/nfs4recover.c
  43. 1
      fs/nfsd/nfsfh.c
  44. 9
      fs/nfsd/nfsproc.c
  45. 79
      fs/nfsd/vfs.c
  46. 11
      fs/nfsd/vfs.h
  47. 18
      fs/nilfs2/file.c
  48. 2
      fs/nilfs2/ioctl.c
  49. 5
      fs/nilfs2/segment.c
  50. 3
      fs/ntfs/file.c
  51. 11
      fs/ocfs2/file.c
  52. 14
      fs/ocfs2/ioctl.c
  53. 7
      fs/ocfs2/journal.c
  54. 2
      fs/ocfs2/mmap.c
  55. 11
      fs/ocfs2/refcounttree.c
  56. 15
      fs/open.c
  57. 75
      fs/pipe.c
  58. 3
      fs/splice.c
  59. 252
      fs/super.c
  60. 2
      fs/sysfs/bin.c
  61. 18
      fs/xfs/xfs_aops.c
  62. 10
      fs/xfs/xfs_file.c
  63. 55
      fs/xfs/xfs_ioctl.c
  64. 12
      fs/xfs/xfs_ioctl32.c
  65. 4
      fs/xfs/xfs_iomap.c
  66. 2
      fs/xfs/xfs_mount.c
  67. 3
      fs/xfs/xfs_mount.h
  68. 2
      fs/xfs/xfs_sync.c
  69. 17
      fs/xfs/xfs_trans.c
  70. 2
      fs/xfs/xfs_trans.h
  71. 4
      include/linux/audit.h
  72. 154
      include/linux/fs.h
  73. 1
      include/linux/mm.h
  74. 1
      include/linux/namei.h
  75. 1
      include/linux/nfsd/nfsfh.h
  76. 2
      include/linux/pipe_fs_i.h
  77. 21
      kernel/audit.c
  78. 18
      kernel/sysctl.c
  79. 14
      lib/percpu_counter.c
  80. 31
      mm/filemap.c
  81. 6
      mm/filemap_xip.c
  82. 14
      mm/memory.c
  83. 93
      net/unix/af_unix.c
  84. 8
      sound/sound_firmware.c

4
Documentation/filesystems/Locking

@ -138,8 +138,8 @@ evict_inode:
put_super: write
write_super: read
sync_fs: read
freeze_fs: read
unfreeze_fs: read
freeze_fs: write
unfreeze_fs: write
statfs: maybe(read) (see below)
remount_fs: write
umount_begin: no

42
Documentation/sysctl/fs.txt

@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
- nr_open
- overflowuid
- overflowgid
- protected_hardlinks
- protected_symlinks
- suid_dumpable
- super-max
- super-nr
@ -157,6 +159,46 @@ The default is 65534.
==============================================================
protected_hardlinks:
A long-standing class of security issues is the hardlink-based
time-of-check-time-of-use race, most commonly seen in world-writable
directories like /tmp. The common method of exploitation of this flaw
is to cross privilege boundaries when following a given hardlink (i.e. a
root process follows a hardlink created by another user). Additionally,
on systems without separated partitions, this stops unauthorized users
from "pinning" vulnerable setuid/setgid files against being upgraded by
the administrator, or linking to special files.
When set to "0", hardlink creation behavior is unrestricted.
When set to "1" hardlinks cannot be created by users if they do not
already own the source file, or do not have read/write access to it.
This protection is based on the restrictions in Openwall and grsecurity.
==============================================================
protected_symlinks:
A long-standing class of security issues is the symlink-based
time-of-check-time-of-use race, most commonly seen in world-writable
directories like /tmp. The common method of exploitation of this flaw
is to cross privilege boundaries when following a given symlink (i.e. a
root process follows a symlink belonging to another user). For a likely
incomplete list of hundreds of examples across the years, please see:
http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
When set to "0", symlink following behavior is unrestricted.
When set to "1" symlinks are permitted to be followed only when outside
a sticky world-writable directory, or when the uid of the symlink and
follower match, or when the directory owner matches the symlink's owner.
This protection is based on the restrictions in Openwall and grsecurity.
==============================================================
suid_dumpable:
This value can be used to query and set the core dump mode for setuid

77
arch/powerpc/platforms/cell/spufs/inode.c

@ -186,10 +186,13 @@ static void spufs_prune_dir(struct dentry *dir)
static int spufs_rmdir(struct inode *parent, struct dentry *dir)
{
/* remove all entries */
int res;
spufs_prune_dir(dir);
d_drop(dir);
return simple_rmdir(parent, dir);
res = simple_rmdir(parent, dir);
/* We have to give up the mm_struct */
spu_forget(SPUFS_I(dir->d_inode)->i_ctx);
return res;
}
static int spufs_fill_dir(struct dentry *dir,
@ -245,9 +248,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
mutex_unlock(&parent->i_mutex);
WARN_ON(ret);
/* We have to give up the mm_struct */
spu_forget(ctx);
return dcache_dir_close(inode, file);
}
@ -450,28 +450,24 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
struct spu_context *neighbor;
struct path path = {.mnt = mnt, .dentry = dentry};
ret = -EPERM;
if ((flags & SPU_CREATE_NOSCHED) &&
!capable(CAP_SYS_NICE))
goto out_unlock;
return -EPERM;
ret = -EINVAL;
if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
== SPU_CREATE_ISOLATE)
goto out_unlock;
return -EINVAL;
ret = -ENODEV;
if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
goto out_unlock;
return -ENODEV;
gang = NULL;
neighbor = NULL;
affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
if (affinity) {
gang = SPUFS_I(inode)->i_gang;
ret = -EINVAL;
if (!gang)
goto out_unlock;
return -EINVAL;
mutex_lock(&gang->aff_mutex);
neighbor = spufs_assert_affinity(flags, gang, aff_filp);
if (IS_ERR(neighbor)) {
@ -492,22 +488,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
}
ret = spufs_context_open(&path);
if (ret < 0) {
if (ret < 0)
WARN_ON(spufs_rmdir(inode, dentry));
if (affinity)
mutex_unlock(&gang->aff_mutex);
mutex_unlock(&inode->i_mutex);
spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
goto out;
}
out_aff_unlock:
if (affinity)
mutex_unlock(&gang->aff_mutex);
out_unlock:
mutex_unlock(&inode->i_mutex);
out:
dput(dentry);
return ret;
}
@ -580,18 +566,13 @@ static int spufs_create_gang(struct inode *inode,
int ret;
ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);
if (ret)
goto out;
ret = spufs_gang_open(&path);
if (ret < 0) {
int err = simple_rmdir(inode, dentry);
WARN_ON(err);
if (!ret) {
ret = spufs_gang_open(&path);
if (ret < 0) {
int err = simple_rmdir(inode, dentry);
WARN_ON(err);
}
}
out:
mutex_unlock(&inode->i_mutex);
dput(dentry);
return ret;
}
@ -601,40 +582,32 @@ static struct file_system_type spufs_type;
long spufs_create(struct path *path, struct dentry *dentry,
unsigned int flags, umode_t mode, struct file *filp)
{
struct inode *dir = path->dentry->d_inode;
int ret;
ret = -EINVAL;
/* check if we are on spufs */
if (path->dentry->d_sb->s_type != &spufs_type)
goto out;
return -EINVAL;
/* don't accept undefined flags */
if (flags & (~SPU_CREATE_FLAG_ALL))
goto out;
return -EINVAL;
/* only threads can be underneath a gang */
if (path->dentry != path->dentry->d_sb->s_root) {
if ((flags & SPU_CREATE_GANG) ||
!SPUFS_I(path->dentry->d_inode)->i_gang)
goto out;
}
if (path->dentry != path->dentry->d_sb->s_root)
if ((flags & SPU_CREATE_GANG) || !SPUFS_I(dir)->i_gang)
return -EINVAL;
mode &= ~current_umask();
if (flags & SPU_CREATE_GANG)
ret = spufs_create_gang(path->dentry->d_inode,
dentry, path->mnt, mode);
ret = spufs_create_gang(dir, dentry, path->mnt, mode);
else
ret = spufs_create_context(path->dentry->d_inode,
dentry, path->mnt, flags, mode,
ret = spufs_create_context(dir, dentry, path->mnt, flags, mode,
filp);
if (ret >= 0)
fsnotify_mkdir(path->dentry->d_inode, dentry);
return ret;
fsnotify_mkdir(dir, dentry);
out:
mutex_unlock(&path->dentry->d_inode->i_mutex);
dput(dentry);
return ret;
}

2
arch/powerpc/platforms/cell/spufs/syscalls.c

@ -70,7 +70,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
ret = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
ret = spufs_create(&path, dentry, flags, mode, neighbor);
path_put(&path);
done_path_create(&path, dentry);
}
return ret;

9
drivers/base/devtmpfs.c

@ -156,9 +156,7 @@ static int dev_mkdir(const char *name, umode_t mode)
if (!err)
/* mark as kernel-created inode */
dentry->d_inode->i_private = &thread;
dput(dentry);
mutex_unlock(&path.dentry->d_inode->i_mutex);
path_put(&path);
done_path_create(&path, dentry);
return err;
}
@ -218,10 +216,7 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
/* mark as kernel-created inode */
dentry->d_inode->i_private = &thread;
}
dput(dentry);
mutex_unlock(&path.dentry->d_inode->i_mutex);
path_put(&path);
done_path_create(&path, dentry);
return err;
}

2
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c

@ -1188,7 +1188,7 @@ exit:
kfree(buf);
/* close file before return */
if (fp)
filp_close(fp, current->files);
filp_close(fp, NULL);
/* restore previous address limit */
set_fs(old_fs);

31
drivers/staging/bcm/Misc.c

@ -157,12 +157,7 @@ static int create_worker_threads(struct bcm_mini_adapter *psAdapter)
static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path)
{
struct file *flp = NULL;
mm_segment_t oldfs;
oldfs = get_fs();
set_fs(get_ds());
flp = filp_open(path, O_RDONLY, S_IRWXU);
set_fs(oldfs);
struct file *flp = filp_open(path, O_RDONLY, S_IRWXU);
if (IS_ERR(flp)) {
pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp));
flp = NULL;
@ -183,14 +178,12 @@ static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, u
{
int errorno = 0;
struct file *flp = NULL;
mm_segment_t oldfs;
struct timeval tv = {0};
flp = open_firmware_file(Adapter, path);
if (!flp) {
errorno = -ENOENT;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path);
goto exit_download;
return -ENOENT;
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path, (unsigned long)flp->f_dentry->d_inode->i_size, loc);
do_gettimeofday(&tv);
@ -201,10 +194,7 @@ static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, u
errorno = -EIO;
goto exit_download;
}
oldfs = get_fs();
set_fs(get_ds());
vfs_llseek(flp, 0, 0);
set_fs(oldfs);
if (Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!");
errorno = -EIO;
@ -212,12 +202,7 @@ static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, u
}
exit_download:
oldfs = get_fs();
set_fs(get_ds());
if (flp && !(IS_ERR(flp)))
filp_close(flp, current->files);
set_fs(oldfs);
filp_close(flp, NULL);
return errorno;
}
@ -1056,10 +1041,8 @@ OUT:
static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
{
struct file *flp = NULL;
mm_segment_t oldfs = {0};
char *buff;
int len = 0;
loff_t pos = 0;
buff = kmalloc(BUFFER_1K, GFP_KERNEL);
if (!buff)
@ -1079,20 +1062,16 @@ static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter)
Adapter->pstargetparams = NULL;
return -ENOENT;
}
oldfs = get_fs();
set_fs(get_ds());
len = vfs_read(flp, (void __user __force *)buff, BUFFER_1K, &pos);
set_fs(oldfs);
len = kernel_read(flp, 0, buff, BUFFER_1K);
filp_close(flp, NULL);
if (len != sizeof(STARGETPARAMS)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Mismatch in Target Param Structure!\n");
kfree(buff);
kfree(Adapter->pstargetparams);
Adapter->pstargetparams = NULL;
filp_close(flp, current->files);
return -ENOENT;
}
filp_close(flp, current->files);
/* Check for autolink in config params */
/*

7
drivers/staging/gdm72xx/sdio_boot.c

@ -66,9 +66,8 @@ static int download_image(struct sdio_func *func, char *img_name)
return -ENOENT;
}
if (filp->f_dentry)
inode = filp->f_dentry->d_inode;
if (!inode || !S_ISREG(inode->i_mode)) {
inode = filp->f_dentry->d_inode;
if (!S_ISREG(inode->i_mode)) {
printk(KERN_ERR "Invalid file type: %s\n", img_name);
ret = -EINVAL;
goto out;
@ -123,7 +122,7 @@ static int download_image(struct sdio_func *func, char *img_name)
pno++;
}
out:
filp_close(filp, current->files);
filp_close(filp, NULL);
return ret;
}

22
drivers/staging/gdm72xx/usb_boot.c

@ -173,14 +173,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0);
if (IS_ERR(filp)) {
printk(KERN_ERR "Can't find %s.\n", img_name);
set_fs(fs);
ret = PTR_ERR(filp);
goto restore_fs;
}
if (filp->f_dentry)
inode = filp->f_dentry->d_inode;
if (!inode || !S_ISREG(inode->i_mode)) {
inode = filp->f_dentry->d_inode;
if (!S_ISREG(inode->i_mode)) {
printk(KERN_ERR "Invalid file type: %s\n", img_name);
ret = -EINVAL;
goto out;
@ -262,7 +260,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
ret = -EINVAL;
}
out:
filp_close(filp, current->files);
filp_close(filp, NULL);
restore_fs:
set_fs(fs);
@ -322,13 +320,11 @@ static int em_download_image(struct usb_device *usbdev, char *path,
goto restore_fs;
}
if (filp->f_dentry) {
inode = filp->f_dentry->d_inode;
if (!inode || !S_ISREG(inode->i_mode)) {
printk(KERN_ERR "Invalid file type: %s\n", path);
ret = -EINVAL;
goto out;
}
inode = filp->f_dentry->d_inode;
if (!S_ISREG(inode->i_mode)) {
printk(KERN_ERR "Invalid file type: %s\n", path);
ret = -EINVAL;
goto out;
}
buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
@ -364,7 +360,7 @@ static int em_download_image(struct usb_device *usbdev, char *path,
goto out;
out:
filp_close(filp, current->files);
filp_close(filp, NULL);
restore_fs:
set_fs(fs);

32
drivers/target/target_core_file.c

@ -109,46 +109,29 @@ static struct se_device *fd_create_virtdevice(
struct se_subsystem_dev *se_dev,
void *p)
{
char *dev_p = NULL;
struct se_device *dev;
struct se_dev_limits dev_limits;
struct queue_limits *limits;
struct fd_dev *fd_dev = p;
struct fd_host *fd_host = hba->hba_ptr;
mm_segment_t old_fs;
struct file *file;
struct inode *inode = NULL;
int dev_flags = 0, flags, ret = -EINVAL;
memset(&dev_limits, 0, sizeof(struct se_dev_limits));
old_fs = get_fs();
set_fs(get_ds());
dev_p = getname(fd_dev->fd_dev_name);
set_fs(old_fs);
if (IS_ERR(dev_p)) {
pr_err("getname(%s) failed: %lu\n",
fd_dev->fd_dev_name, IS_ERR(dev_p));
ret = PTR_ERR(dev_p);
goto fail;
}
/*
* Use O_DSYNC by default instead of O_SYNC to forgo syncing
* of pure timestamp updates.
*/
flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
file = filp_open(dev_p, flags, 0600);
file = filp_open(fd_dev->fd_dev_name, flags, 0600);
if (IS_ERR(file)) {
pr_err("filp_open(%s) failed\n", dev_p);
pr_err("filp_open(%s) failed\n", fd_dev->fd_dev_name);
ret = PTR_ERR(file);
goto fail;
}
if (!file || !file->f_dentry) {
pr_err("filp_open(%s) failed\n", dev_p);
goto fail;
}
fd_dev->fd_file = file;
/*
* If using a block backend with this struct file, we extract
@ -212,14 +195,12 @@ static struct se_device *fd_create_virtdevice(
" %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id,
fd_dev->fd_dev_name, fd_dev->fd_dev_size);
putname(dev_p);
return dev;
fail:
if (fd_dev->fd_file) {
filp_close(fd_dev->fd_file, NULL);
fd_dev->fd_file = NULL;
}
putname(dev_p);
return ERR_PTR(ret);
}
@ -452,14 +433,11 @@ static ssize_t fd_set_configfs_dev_params(
token = match_token(ptr, tokens, args);
switch (token) {
case Opt_fd_dev_name:
arg_p = match_strdup(&args[0]);
if (!arg_p) {
ret = -ENOMEM;
if (match_strlcpy(fd_dev->fd_dev_name, &args[0],
FD_MAX_DEV_NAME) == 0) {
ret = -EINVAL;
break;
}
snprintf(fd_dev->fd_dev_name, FD_MAX_DEV_NAME,
"%s", arg_p);
kfree(arg_p);
pr_debug("FILEIO: Referencing Path: %s\n",
fd_dev->fd_dev_name);
fd_dev->fbd_flags |= FBDF_HAS_PATH;

12
drivers/usb/gadget/storage_common.c

@ -656,9 +656,8 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
if (!(filp->f_mode & FMODE_WRITE))
ro = 1;
if (filp->f_path.dentry)
inode = filp->f_path.dentry->d_inode;
if (!inode || (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
inode = filp->f_path.dentry->d_inode;
if ((!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
LINFO(curlun, "invalid file type: %s\n", filename);
goto out;
}
@ -667,7 +666,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
* If we can't read the file, it's no good.
* If we can't write the file, use it read-only.
*/
if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) {
if (!(filp->f_op->read || filp->f_op->aio_read)) {
LINFO(curlun, "file not readable: %s\n", filename);
goto out;
}
@ -712,7 +711,6 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
if (fsg_lun_is_open(curlun))
fsg_lun_close(curlun);
get_file(filp);
curlun->blksize = blksize;
curlun->blkbits = blkbits;
curlun->ro = ro;
@ -720,10 +718,10 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
curlun->file_length = size;
curlun->num_sectors = num_sectors;
LDBG(curlun, "open backing file: %s\n", filename);
rc = 0;
return 0;
out:
filp_close(filp, current->files);
fput(filp);
return rc;
}

6
drivers/usb/gadget/u_uac1.c

@ -275,17 +275,17 @@ static int gaudio_close_snd_dev(struct gaudio *gau)
/* Close control device */
snd = &gau->control;
if (snd->filp)
filp_close(snd->filp, current->files);
filp_close(snd->filp, NULL);
/* Close PCM playback device and setup substream */
snd = &gau->playback;
if (snd->filp)
filp_close(snd->filp, current->files);
filp_close(snd->filp, NULL);
/* Close PCM capture device and setup substream */
snd = &gau->capture;
if (snd->filp)
filp_close(snd->filp, current->files);
filp_close(snd->filp, NULL);
return 0;
}

2
drivers/video/fb_defio.c

@ -104,6 +104,8 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
deferred framebuffer IO. then if userspace touches a page
again, we repeat the same scheme */
file_update_time(vma->vm_file);
/* protect against the workqueue changing the page list */
mutex_lock(&fbdefio->lock);

3
fs/9p/vfs_file.c

@ -610,6 +610,9 @@ v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
page, (unsigned long)filp->private_data);
/* Update file times before taking page lock */
file_update_time(filp);
v9inode = V9FS_I(inode);
/* make sure the cache has finished storing the page */
v9fs_fscache_wait_on_page_write(inode, page);

3
fs/btrfs/disk-io.c

@ -1614,8 +1614,6 @@ static int cleaner_kthread(void *arg)
struct btrfs_root *root = arg;
do {
vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
mutex_trylock(&root->fs_info->cleaner_mutex)) {
btrfs_run_delayed_iputs(root);
@ -1647,7 +1645,6 @@ static int transaction_kthread(void *arg)
do {
cannot_commit = false;
delay = HZ * 30;
vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
mutex_lock(&root->fs_info->transaction_kthread_mutex);
spin_lock(&root->fs_info->trans_lock);

3
fs/btrfs/file.c

@ -1379,7 +1379,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
ssize_t err = 0;
size_t count, ocount;
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
sb_start_write(inode->i_sb);
mutex_lock(&inode->i_mutex);
@ -1469,6 +1469,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
num_written = err;
}
out:
sb_end_write(inode->i_sb);
current->backing_dev_info = NULL;
return num_written ? num_written : err;
}

6
fs/btrfs/inode.c

@ -6629,6 +6629,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
u64 page_start;
u64 page_end;
sb_start_pagefault(inode->i_sb);
ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
if (!ret) {
ret = file_update_time(vma->vm_file);
@ -6718,12 +6719,15 @@ again:
unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
out_unlock:
if (!ret)
if (!ret) {
sb_end_pagefault(inode->i_sb);
return VM_FAULT_LOCKED;
}
unlock_page(page);
out:
btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
out_noreserve:
sb_end_pagefault(inode->i_sb);
return ret;
}

15
fs/btrfs/ioctl.c

@ -195,6 +195,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
if (!inode_owner_or_capable(inode))
return -EACCES;
ret = mnt_want_write_file(file);
if (ret)
return ret;
mutex_lock(&inode->i_mutex);
ip_oldflags = ip->flags;
@ -209,10 +213,6 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
}
}
ret = mnt_want_write_file(file);
if (ret)
goto out_unlock;
if (flags & FS_SYNC_FL)
ip->flags |= BTRFS_INODE_SYNC;
else
@ -275,9 +275,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
inode->i_flags = i_oldflags;
}
mnt_drop_write_file(file);
out_unlock:
mutex_unlock(&inode->i_mutex);
mnt_drop_write_file(file);
return ret;
}
@ -664,6 +664,10 @@ static noinline int btrfs_mksubvol(struct path *parent,
struct dentry *dentry;
int error;
error = mnt_want_write(parent->mnt);
if (error)
return error;
mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
dentry = lookup_one_len(name, parent->dentry, namelen);
@ -699,6 +703,7 @@ out_dput:
dput(dentry);
out_unlock:
mutex_unlock(&dir->i_mutex);
mnt_drop_write(parent->mnt);
return error;
}

7
fs/btrfs/transaction.c

@ -335,6 +335,8 @@ again:
if (!h)
return ERR_PTR(-ENOMEM);
sb_start_intwrite(root->fs_info->sb);
if (may_wait_transaction(root, type))
wait_current_trans(root);
@ -345,6 +347,7 @@ again:
} while (ret == -EBUSY);
if (ret < 0) {
sb_end_intwrite(root->fs_info->sb);
kmem_cache_free(btrfs_trans_handle_cachep, h);
return ERR_PTR(ret);
}
@ -548,6 +551,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;
sb_end_intwrite(root->fs_info->sb);
if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
should_end_transaction(trans, root)) {
trans->transaction->blocked = 1;
@ -1578,6 +1583,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
put_transaction(cur_trans);
put_transaction(cur_trans);
sb_end_intwrite(root->fs_info->sb);
trace_btrfs_transaction_commit(root);
btrfs_scrub_continue(root);

28
fs/buffer.c

@ -2306,8 +2306,8 @@ EXPORT_SYMBOL(block_commit_write);
* beyond EOF, then the page is guaranteed safe against truncation until we
* unlock the page.
*
* Direct callers of this function should call vfs_check_frozen() so that page
* fault does not busyloop until the fs is thawed.
* Direct callers of this function should protect against filesystem freezing
* using sb_start_write() - sb_end_write() functions.
*/
int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
get_block_t get_block)
@ -2318,6 +2318,12 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
loff_t size;
int ret;
/*
* Update file times before taking page lock. We may end up failing the
* fault so this update may be superfluous but who really cares...
*/
file_update_time(vma->vm_file);
lock_page(page);
size = i_size_read(inode);
if ((page->mapping != inode->i_mapping) ||
@ -2339,18 +2345,7 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
if (unlikely(ret < 0))
goto out_unlock;
/*
* Freezing in progress? We check after the page is marked dirty and
* with page lock held so if the test here fails, we are sure freezing
* code will wait during syncing until the page fault is done - at that
* point page will be dirty and unlocked so freezing code will write it
* and writeprotect it again.
*/
set_page_dirty(page);
if (inode->i_sb->s_frozen != SB_UNFROZEN) {
ret = -EAGAIN;
goto out_unlock;
}
wait_on_page_writeback(page);
return 0;
out_unlock:
@ -2365,12 +2360,9 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
int ret;
struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb;
/*
* This check is racy but catches the common case. The check in
* __block_page_mkwrite() is reliable.
*/
vfs_check_frozen(sb, SB_FREEZE_WRITE);
sb_start_pagefault(sb);
ret = __block_page_mkwrite(vma, vmf, get_block);
sb_end_pagefault(sb);
return block_page_mkwrite_return(ret);
}
EXPORT_SYMBOL(block_page_mkwrite);

3
fs/ceph/addr.c

@ -1184,6 +1184,9 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
loff_t size, len;
int ret;
/* Update time before taking page lock */
file_update_time(vma->vm_file);
size = i_size_read(inode);
if (off + PAGE_CACHE_SIZE <= size)
len = PAGE_CACHE_SIZE;

30
fs/ecryptfs/inode.c

@ -318,21 +318,20 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry,
struct vfsmount *lower_mnt;
int rc = 0;
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode);
BUG_ON(!lower_dentry->d_count);
dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
ecryptfs_set_dentry_private(dentry, dentry_info);
if (!dentry_info) {
printk(KERN_ERR "%s: Out of memory whilst attempting "
"to allocate ecryptfs_dentry_info struct\n",
__func__);
dput(lower_dentry);
mntput(lower_mnt);
d_drop(dentry);
return -ENOMEM;
}
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode);
BUG_ON(!lower_dentry->d_count);
ecryptfs_set_dentry_private(dentry, dentry_info);
ecryptfs_set_dentry_lower(dentry, lower_dentry);
ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);
@ -381,12 +380,6 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
struct dentry *lower_dir_dentry, *lower_dentry;
int rc = 0;
if ((ecryptfs_dentry->d_name.len == 1
&& !strcmp(ecryptfs_dentry->d_name.name, "."))
|| (ecryptfs_dentry->d_name.len == 2
&& !strcmp(ecryptfs_dentry->d_name.name, ".."))) {
goto out_d_drop;
}
lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent);
mutex_lock(&lower_dir_dentry->d_inode->i_mutex);
lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name,
@ -397,8 +390,8 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
rc = PTR_ERR(lower_dentry);
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
"[%d] on lower_dentry = [%s]\n", __func__, rc,
encrypted_and_encoded_name);
goto out_d_drop;
ecryptfs_dentry->d_name.name);
goto out;
}
if (lower_dentry->d_inode)
goto interpose;
@ -415,7 +408,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
if (rc) {
printk(KERN_ERR "%s: Error attempting to encrypt and encode "
"filename; rc = [%d]\n", __func__, rc);
goto out_d_drop;
goto out;
}
mutex_lock(&lower_dir_dentry->d_inode->i_mutex);
lower_dentry = lookup_one_len(encrypted_and_encoded_name,
@ -427,14 +420,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
"[%d] on lower_dentry = [%s]\n", __func__, rc,
encrypted_and_encoded_name);
goto out_d_drop;
goto out;
}
interpose:
rc = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry,
ecryptfs_dir_inode);
goto out;
out_d_drop:
d_drop(ecryptfs_dentry);
out:
kfree(encrypted_and_encoded_name);
return ERR_PTR(rc);

19
fs/exec.c

@ -2069,25 +2069,18 @@ static void wait_for_dump_helpers(struct file *file)
*/
static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
{
struct file *rp, *wp;
struct file *files[2];
struct fdtable *fdt;
struct coredump_params *cp = (struct coredump_params *)info->data;
struct files_struct *cf = current->files;
int err = create_pipe_files(files, 0);
if (err)
return err;
wp = create_write_pipe(0);
if (IS_ERR(wp))
return PTR_ERR(wp);
rp = create_read_pipe(wp, 0);
if (IS_ERR(rp)) {
free_write_pipe(wp);
return PTR_ERR(rp);
}
cp->file = wp;
cp->file = files[1];
sys_close(0);
fd_install(0, rp);
fd_install(0, files[0]);
spin_lock(&cf->file_lock);
fdt = files_fdtable(cf);
__set_open_fd(0, fdt);

5
fs/ext2/inode.c

@ -79,6 +79,7 @@ void ext2_evict_inode(struct inode * inode)
truncate_inode_pages(&inode->i_data, 0);
if (want_delete) {
sb_start_intwrite(inode->i_sb);
/* set dtime */
EXT2_I(inode)->i_dtime = get_seconds();
mark_inode_dirty(inode);
@ -98,8 +99,10 @@ void ext2_evict_inode(struct inode * inode)
if (unlikely(rsv))
kfree(rsv);
if (want_delete)
if (want_delete) {
ext2_free_inode(inode);
sb_end_intwrite(inode->i_sb);
}
}
typedef struct {

33
fs/ext2/super.c

@ -42,6 +42,8 @@ static void ext2_sync_super(struct super_block *sb,
static int ext2_remount (struct super_block * sb, int * flags, char * data);
static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
static int ext2_sync_fs(struct super_block *sb, int wait);
static int ext2_freeze(struct super_block *sb);
static int ext2_unfreeze(struct super_block *sb);
void ext2_error(struct super_block *sb, const char *function,
const char *fmt, ...)
@ -305,6 +307,8 @@ static const struct super_operations ext2_sops = {
.evict_inode = ext2_evict_inode,
.put_super = ext2_put_super,
.sync_fs = ext2_sync_fs,
.freeze_fs = ext2_freeze,
.unfreeze_fs = ext2_unfreeze,
.statfs = ext2_statfs,
.remount_fs = ext2_remount,
.show_options = ext2_show_options,
@ -1200,6 +1204,35 @@ static int ext2_sync_fs(struct super_block *sb, int wait)
return 0;
}
static int ext2_freeze(struct super_block *sb)
{
struct ext2_sb_info *sbi = EXT2_SB(sb);
/*
* Open but unlinked files present? Keep EXT2_VALID_FS flag cleared
* because we have unattached inodes and thus filesystem is not fully
* consistent.
*/
if (atomic_long_read(&sb->s_remove_count)) {
ext2_sync_fs(sb, 1);
return 0;
}
/* Set EXT2_FS_VALID flag */
spin_lock(&sbi->s_lock);
sbi->s_es->s_state = cpu_to_le16(sbi->s_mount_state);
spin_unlock(&sbi->s_lock);
ext2_sync_super(sb, sbi->s_es, 1);
return 0;
}
static int ext2_unfreeze(struct super_block *sb)
{
/* Just write sb to clear EXT2_VALID_FS flag */
ext2_write_super(sb);
return 0;
}
void ext2_write_super(struct super_block *sb)
{

15
fs/ext4/inode.c

@ -233,6 +233,11 @@ void ext4_evict_inode(struct inode *inode)
if (is_bad_inode(inode))
goto no_delete;
/*
* Protect us against freezing - iput() caller didn't have to have any
* protection against it
*/
sb_start_intwrite(inode->i_sb);
handle = ext4_journal_start(inode, ext4_blocks_for_truncate(inode)+3);
if (IS_ERR(handle)) {
ext4_std_error(inode->i_sb, PTR_ERR(handle));
@ -242,6 +247,7 @@ void ext4_evict_inode(struct inode *inode)
* cleaned up.
*/
ext4_orphan_del(NULL, inode);
sb_end_intwrite(inode->i_sb);
goto no_delete;
}
@ -273,6 +279,7 @@ void ext4_evict_inode(struct inode *inode)
stop_handle:
ext4_journal_stop(handle);
ext4_orphan_del(NULL, inode);
sb_end_intwrite(inode->i_sb);
goto no_delete;
}
}
@ -301,6 +308,7 @@ void ext4_evict_inode(struct inode *inode)
else
ext4_free_inode(handle, inode);
ext4_journal_stop(handle);
sb_end_intwrite(inode->i_sb);
return;
no_delete:
ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
@ -4779,11 +4787,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
get_block_t *get_block;
int retries = 0;
/*
* This check is racy but catches the common case. We rely on
* __block_page_mkwrite() to do a reliable check.
*/
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
sb_start_pagefault(inode->i_sb);
/* Delalloc case is easy... */
if (test_opt(inode->i_sb, DELALLOC) &&
!ext4_should_journal_data(inode) &&
@ -4851,5 +4855,6 @@ retry_alloc:
out_ret:
ret = block_page_mkwrite_return(ret);
out:
sb_end_pagefault(inode->i_sb);
return ret;
}

6
fs/ext4/mmp.c

@ -44,6 +44,11 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
{
struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data);
/*
* We protect against freezing so that we don't create dirty buffers
* on frozen filesystem.
*/
sb_start_write(sb);
ext4_mmp_csum_set(sb, mmp);
mark_buffer_dirty(bh);
lock_buffer(bh);
@ -51,6 +56,7 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
get_bh(bh);
submit_bh(WRITE_SYNC, bh);
wait_on_buffer(bh);
sb_end_write(sb);
if (unlikely(!buffer_uptodate(bh)))
return 1;

31
fs/ext4/super.c

@ -331,33 +331,17 @@ static void ext4_put_nojournal(handle_t *handle)
* journal_end calls result in the superblock being marked dirty, so
* that sync() will call the filesystem's write_super callback if
* appropriate.
*
* To avoid j_barrier hold in userspace when a user calls freeze(),
* ext4 prevents a new handle from being started by s_frozen, which
* is in an upper layer.
*/
handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
{
journal_t *journal;
handle_t *handle;
trace_ext4_journal_start(sb, nblocks, _RET_IP_);
if (sb->s_flags & MS_RDONLY)
return ERR_PTR(-EROFS);
WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);
journal = EXT4_SB(sb)->s_journal;
handle = ext4_journal_current_handle();
/*
* If a handle has been started, it should be allowed to
* finish, otherwise deadlock could happen between freeze
* and others(e.g. truncate) due to the restart of the
* journal handle if the filesystem is forzen and active
* handles are not stopped.
*/
if (!handle)
vfs_check_frozen(sb, SB_FREEZE_TRANS);
if (!journal)
return ext4_get_nojournal();
/*
@ -2747,6 +2731,7 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
sb = elr->lr_super;
ngroups = EXT4_SB(sb)->s_groups_count;
sb_start_write(sb);
for (group = elr->lr_next_group; group < ngroups; group++) {
gdp = ext4_get_group_desc(sb, group, NULL);
if (!gdp) {
@ -2773,6 +2758,7 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
elr->lr_next_sched = jiffies + elr->lr_timeout;
elr->lr_next_group = group + 1;
}
sb_end_write(sb);
return ret;
}
@ -4460,10 +4446,8 @@ int ext4_force_commit(struct super_block *sb)
return 0;
journal = EXT4_SB(sb)->s_journal;
if (journal) {
vfs_check_frozen(sb, SB_FREEZE_TRANS);
if (journal)
ret = ext4_journal_force_commit(journal);
}
return ret;
}
@ -4493,9 +4477,8 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
* gives us a chance to flush the journal completely and mark the fs clean.
*
* Note that only this function cannot bring a filesystem to be in a clean
* state independently, because ext4 prevents a new handle from being started
* by @sb->s_frozen, which stays in an upper layer. It thus needs help from
* the upper layer.
* state independently. It relies on upper layer to stop all data & metadata
* modifications.
*/
static int ext4_freeze(struct super_block *sb)
{
@ -4522,7 +4505,7 @@ static int ext4_freeze(struct super_block *sb)
EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
error = ext4_commit_super(sb, 1);
out:
/* we rely on s_frozen to stop further updates */
/* we rely on upper layer to stop further updates */
jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
return error;
}

15
fs/fat/file.c

@ -43,10 +43,10 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
if (err)
goto out;
mutex_lock(&inode->i_mutex);
err = mnt_want_write_file(file);
if (err)
goto out_unlock_inode;
goto out;
mutex_lock(&inode->i_mutex);
/*
* ATTR_VOLUME and ATTR_DIR cannot be changed; this also
@ -73,14 +73,14 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
/* The root directory has no attributes */
if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) {
err = -EINVAL;
goto out_drop_write;
goto out_unlock_inode;
}
if (sbi->options.sys_immutable &&
((attr | oldattr) & ATTR_SYS) &&
!capable(CAP_LINUX_IMMUTABLE)) {
err = -EPERM;
goto out_drop_write;
goto out_unlock_inode;
}
/*
@ -90,12 +90,12 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
*/
err = security_inode_setattr(file->f_path.dentry, &ia);
if (err)
goto out_drop_write;
goto out_unlock_inode;
/* This MUST be done before doing anything irreversible... */
err = fat_setattr(file->f_path.dentry, &ia);
if (err)
goto out_drop_write;
goto out_unlock_inode;
fsnotify_change(file->f_path.dentry, ia.ia_valid);
if (sbi->options.sys_immutable) {
@ -107,10 +107,9 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
fat_save_attrs(inode, attr);
mark_inode_dirty(inode);
out_drop_write:
mnt_drop_write_file(file);
out_unlock_inode:
mutex_unlock(&inode->i_mutex);
mnt_drop_write_file(file);
out:
return err;
}

4
fs/file_table.c

@ -43,7 +43,7 @@ static struct kmem_cache *filp_cachep __read_mostly;
static struct percpu_counter nr_files __cacheline_aligned_in_smp;