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
  ...
This commit is contained in:
Linus Torvalds
2012-08-01 10:26:23 -07:00
84 changed files with 1327 additions and 640 deletions

View File

@@ -1016,18 +1016,16 @@ fail_inode:
return NULL;
}
struct file *create_write_pipe(int flags)
int create_pipe_files(struct file **res, int flags)
{
int err;
struct inode *inode;
struct inode *inode = get_pipe_inode();
struct file *f;
struct path path;
struct qstr name = { .name = "" };
static struct qstr name = { .name = "" };
err = -ENFILE;
inode = get_pipe_inode();
if (!inode)
goto err;
return -ENFILE;
err = -ENOMEM;
path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name);
@@ -1041,62 +1039,43 @@ struct file *create_write_pipe(int flags)
f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops);
if (!f)
goto err_dentry;
f->f_mapping = inode->i_mapping;
f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
f->f_version = 0;
return f;
res[0] = alloc_file(&path, FMODE_READ, &read_pipefifo_fops);
if (!res[0])
goto err_file;
err_dentry:
path_get(&path);
res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
res[1] = f;
return 0;
err_file:
put_filp(f);
err_dentry:
free_pipe_info(inode);
path_put(&path);
return ERR_PTR(err);
return err;
err_inode:
err_inode:
free_pipe_info(inode);
iput(inode);
err:
return ERR_PTR(err);
}
void free_write_pipe(struct file *f)
{
free_pipe_info(f->f_dentry->d_inode);
path_put(&f->f_path);
put_filp(f);
}
struct file *create_read_pipe(struct file *wrf, int flags)
{
/* Grab pipe from the writer */
struct file *f = alloc_file(&wrf->f_path, FMODE_READ,
&read_pipefifo_fops);
if (!f)
return ERR_PTR(-ENFILE);
path_get(&wrf->f_path);
f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
return f;
return err;
}
int do_pipe_flags(int *fd, int flags)
{
struct file *fw, *fr;
struct file *files[2];
int error;
int fdw, fdr;
if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
return -EINVAL;
fw = create_write_pipe(flags);
if (IS_ERR(fw))
return PTR_ERR(fw);
fr = create_read_pipe(fw, flags);
error = PTR_ERR(fr);
if (IS_ERR(fr))
goto err_write_pipe;
error = create_pipe_files(files, flags);
if (error)
return error;
error = get_unused_fd_flags(flags);
if (error < 0)
@@ -1109,8 +1088,8 @@ int do_pipe_flags(int *fd, int flags)
fdw = error;
audit_fd_pair(fdr, fdw);
fd_install(fdr, fr);
fd_install(fdw, fw);
fd_install(fdr, files[0]);
fd_install(fdw, files[1]);
fd[0] = fdr;
fd[1] = fdw;
@@ -1119,10 +1098,8 @@ int do_pipe_flags(int *fd, int flags)
err_fdr:
put_unused_fd(fdr);
err_read_pipe:
path_put(&fr->f_path);
put_filp(fr);
err_write_pipe:
free_write_pipe(fw);
fput(files[0]);
fput(files[1]);
return error;
}