diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2012-06-05 15:10:17 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-14 14:33:04 +0200 |
commit | d18e9008c377dc6a6d2166a6840bf3a23a5867fd (patch) | |
tree | 6bbb29aea7e931b603bd4cea3cc74a0eda7b6379 /Documentation/filesystems | |
parent | vfs: lookup_open(): expand lookup_hash() (diff) | |
download | linux-d18e9008c377dc6a6d2166a6840bf3a23a5867fd.tar.xz linux-d18e9008c377dc6a6d2166a6840bf3a23a5867fd.zip |
vfs: add i_op->atomic_open()
Add a new inode operation which is called on the last component of an open.
Using this 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 NULL instead of an open struct file
pointer.
i_op->atomic_open() is only called if the last component is negative or needs
lookup. Handling cached positive dentries here doesn't add much value: these
can be opened using f_op->open(). If the cached file turns out to be invalid,
the open can be retried, this time using ->atomic_open() with a fresh dentry.
For now leave the old way of using open intents in lookup and revalidate in
place. This will be removed once all the users are converted.
David Howells noticed that if ->atomic_open() opens the file but does not create
it, handle_truncate() will be called on it even if it is not a regular file.
Fix this by checking the file type in this case too.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'Documentation/filesystems')
-rw-r--r-- | Documentation/filesystems/Locking | 4 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 11 |
2 files changed, 15 insertions, 0 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 8e2da1e06e3b..8157488c3463 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -62,6 +62,9 @@ ata *); int (*removexattr) (struct dentry *, const char *); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); void (*update_time)(struct inode *, struct timespec *, int); + struct file * (*atomic_open)(struct inode *, struct dentry *, + struct opendata *, unsigned open_flag, + umode_t create_mode, bool *created); locking rules: all may block @@ -89,6 +92,7 @@ listxattr: no removexattr: yes fiemap: no update_time: no +atomic_open: yes Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on victim. diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index efd23f481704..beb6e691f70a 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -364,6 +364,9 @@ struct inode_operations { ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*removexattr) (struct dentry *, const char *); void (*update_time)(struct inode *, struct timespec *, int); + struct file * (*atomic_open)(struct inode *, struct dentry *, + struct opendata *, unsigned open_flag, + umode_t create_mode, bool *created); }; Again, all methods are called without any locks being held, unless @@ -476,6 +479,14 @@ otherwise noted. an inode. If this is not defined the VFS will update the inode itself and call mark_inode_dirty_sync. + 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 NULL instead of + an open struct file pointer. This method is only called if the last + component is negative or needs lookup. Cached positive dentries are + still handled by f_op->open(). + The Address Space Object ======================== |