Commit 0854d450 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Al Viro

vfs: improve i_op->atomic_open() documentation

Fix documentation of ->atomic_open() and related functions: finish_open()
and finish_no_open().  Also add details that seem to be unclear and a
source of bugs (some of which are fixed in the following series).

Cc-ing maintainers of all filesystems implementing ->atomic_open().
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Sage Weil <sage@inktank.com>
Cc: Steve French <sfrench@samba.org>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 606035e7
...@@ -359,11 +359,9 @@ struct inode_operations { ...@@ -359,11 +359,9 @@ struct inode_operations {
ssize_t (*listxattr) (struct dentry *, char *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *); int (*removexattr) (struct dentry *, const char *);
void (*update_time)(struct inode *, struct timespec *, int); void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *, int (*atomic_open)(struct inode *, struct dentry *, struct file *,
unsigned open_flag, umode_t create_mode, int *opened);
int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*tmpfile) (struct inode *, struct dentry *, umode_t);
} ____cacheline_aligned;
struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
}; };
Again, all methods are called without any locks being held, unless Again, all methods are called without any locks being held, unless
...@@ -470,9 +468,11 @@ otherwise noted. ...@@ -470,9 +468,11 @@ otherwise noted.
method the filesystem can look up, possibly create and open the file in 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 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 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 usual 0 or -ve . This method is only called if the last component is
component is negative or needs lookup. Cached positive dentries are negative or needs lookup. Cached positive dentries are still handled by
still handled by f_op->open(). 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.
tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to
atomically creating, opening and unlinking a file in given directory. atomically creating, opening and unlinking a file in given directory.
......
...@@ -744,14 +744,24 @@ static int do_dentry_open(struct file *f, ...@@ -744,14 +744,24 @@ static int do_dentry_open(struct file *f,
/** /**
* finish_open - finish opening a file * finish_open - finish opening a file
* @od: opaque open data * @file: file pointer
* @dentry: pointer to dentry * @dentry: pointer to dentry
* @open: open callback * @open: open callback
* @opened: state of open
* *
* This can be used to finish opening a file passed to i_op->atomic_open(). * This can be used to finish opening a file passed to i_op->atomic_open().
* *
* If the open callback is set to NULL, then the standard f_op->open() * If the open callback is set to NULL, then the standard f_op->open()
* filesystem callback is substituted. * filesystem callback is substituted.
*
* NB: the dentry reference is _not_ consumed. If, for example, the dentry is
* the return value of d_splice_alias(), then the caller needs to perform dput()
* on it after finish_open().
*
* On successful return @file is a fully instantiated open file. After this, if
* an error occurs in ->atomic_open(), it needs to clean up with fput().
*
* Returns zero on success or -errno if the open failed.
*/ */
int finish_open(struct file *file, struct dentry *dentry, int finish_open(struct file *file, struct dentry *dentry,
int (*open)(struct inode *, struct file *), int (*open)(struct inode *, struct file *),
...@@ -772,11 +782,16 @@ EXPORT_SYMBOL(finish_open); ...@@ -772,11 +782,16 @@ EXPORT_SYMBOL(finish_open);
/** /**
* finish_no_open - finish ->atomic_open() without opening the file * finish_no_open - finish ->atomic_open() without opening the file
* *
* @od: opaque open data * @file: file pointer
* @dentry: dentry or NULL (as returned from ->lookup()) * @dentry: dentry or NULL (as returned from ->lookup())
* *
* This can be used to set the result of a successful lookup in ->atomic_open(). * This can be used to set the result of a successful lookup in ->atomic_open().
* The filesystem's atomic_open() method shall return NULL after calling this. *
* NB: unlike finish_open() this function does consume the dentry reference and
* the caller need not dput() it.
*
* Returns "1" which must be the return value of ->atomic_open() after having
* called this function.
*/ */
int finish_no_open(struct file *file, struct dentry *dentry) int finish_no_open(struct file *file, struct dentry *dentry)
{ {
......
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