Merge branch 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs open-related updates from Al Viro:

 - "do we need fput() or put_filp()" rules are gone - it's always fput()
   now. We keep track of that state where it belongs - in ->f_mode.

 - int *opened mess killed - in finish_open(), in ->atomic_open()
   instances and in fs/namei.c code around do_last()/lookup_open()/atomic_open().

 - alloc_file() wrappers with saner calling conventions are introduced
   (alloc_file_clone() and alloc_file_pseudo()); callers converted, with
   much simplification.

 - while we are at it, saner calling conventions for path_init() and
   link_path_walk(), simplifying things inside fs/namei.c (both on
   open-related paths and elsewhere).

* 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits)
  few more cleanups of link_path_walk() callers
  allow link_path_walk() to take ERR_PTR()
  make path_init() unconditionally paired with terminate_walk()
  document alloc_file() changes
  make alloc_file() static
  do_shmat(): grab shp->shm_file earlier, switch to alloc_file_clone()
  new helper: alloc_file_clone()
  create_pipe_files(): switch the first allocation to alloc_file_pseudo()
  anon_inode_getfile(): switch to alloc_file_pseudo()
  hugetlb_file_setup(): switch to alloc_file_pseudo()
  ocxlflash_getfile(): switch to alloc_file_pseudo()
  cxl_getfile(): switch to alloc_file_pseudo()
  ... and switch shmem_file_setup() to alloc_file_pseudo()
  __shmem_file_setup(): reorder allocations
  new wrapper: alloc_file_pseudo()
  kill FILE_{CREATED,OPENED}
  switch atomic_open() and lookup_open() to returning 0 in all success cases
  document ->atomic_open() changes
  ->atomic_open(): return 0 in all success cases
  get rid of 'opened' in path_openat() and the helpers downstream
  ...
This commit is contained in:
Linus Torvalds 2018-08-13 19:58:36 -07:00
commit a66b4cd1e7
45 changed files with 371 additions and 576 deletions

View file

@ -64,7 +64,7 @@ prototypes:
void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *,
struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
umode_t create_mode);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
locking rules:

View file

@ -602,3 +602,23 @@ in your dentry operations instead.
dentry separately, and it now has request_mask and query_flags arguments
to specify the fields and sync type requested by statx. Filesystems not
supporting any statx-specific features may ignore the new arguments.
--
[mandatory]
->atomic_open() calling conventions have changed. Gone is int *opened,
along with FILE_OPENED/FILE_CREATED. In place of those we have
FMODE_OPENED/FMODE_CREATED, set in file->f_mode. Additionally, return
value for 'called finish_no_open(), open it yourself' case has become
0, not 1. Since finish_no_open() itself is returning 0 now, that part
does not need any changes in ->atomic_open() instances.
--
[mandatory]
alloc_file() has become static now; two wrappers are to be used instead.
alloc_file_pseudo(inode, vfsmount, name, flags, ops) is for the cases
when dentry needs to be created; that's the majority of old alloc_file()
users. Calling conventions: on success a reference to new struct file
is returned and callers reference to inode is subsumed by that. On
failure, ERR_PTR() is returned and no caller's references are affected,
so the caller needs to drop the inode reference it held.
alloc_file_clone(file, flags, ops) does not affect any caller's references.
On success you get a new struct file sharing the mount/dentry with the
original, on failure - ERR_PTR().

View file

@ -386,7 +386,7 @@ struct inode_operations {
ssize_t (*listxattr) (struct dentry *, char *, size_t);
void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
unsigned open_flag, umode_t create_mode, int *opened);
unsigned open_flag, umode_t create_mode);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
};
@ -496,13 +496,15 @@ otherwise noted.
atomic_open: called on the last component of an open. Using this optional
method the filesystem can look up, possibly create and open the file in
one atomic operation. If it cannot perform this (e.g. the file type
turned out to be wrong) it may signal this by returning 1 instead of
usual 0 or -ve . This method is only called if the last component is
negative or needs lookup. Cached positive dentries are still handled by
f_op->open(). If the file was created, the FILE_CREATED flag should be
set in "opened". In case of O_EXCL the method must only succeed if the
file didn't exist and hence FILE_CREATED shall always be set on success.
one atomic operation. If it wants to leave actual opening to the
caller (e.g. if the file turned out to be a symlink, device, or just
something filesystem won't do atomic open for), it may signal this by
returning finish_no_open(file, dentry). This method is only called if
the last component is negative or needs lookup. Cached positive dentries
are still handled by f_op->open(). If the file was created,
FMODE_CREATED flag should be set in file->f_mode. In case of O_EXCL
the method must only succeed if the file didn't exist and hence FMODE_CREATED
shall always be set on success.
tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to
atomically creating, opening and unlinking a file in given directory.