summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 20:10:19 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 20:10:19 +0400
commit790eac5640abf7a57fa3a644386df330e18c11b0 (patch)
tree08de20bde44f59e51b91ff473a71047c2957e8c9 /include/linux
parent0b0585c3e192967cb2ef0ac0816eb8a8c8d99840 (diff)
parent48bde8d3620f5f3c6ae9ff599eb404055ae51664 (diff)
downloadlinux-790eac5640abf7a57fa3a644386df330e18c11b0.tar.xz
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second set of VFS changes from Al Viro: "Assorted f_pos race fixes, making do_splice_direct() safe to call with i_mutex on parent, O_TMPFILE support, Jeff's locks.c series, ->d_hash/->d_compare calling conventions changes from Linus, misc stuff all over the place." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) Document ->tmpfile() ext4: ->tmpfile() support vfs: export lseek_execute() to modules lseek_execute() doesn't need an inode passed to it block_dev: switch to fixed_size_llseek() cpqphp_sysfs: switch to fixed_size_llseek() tile-srom: switch to fixed_size_llseek() proc_powerpc: switch to fixed_size_llseek() ubi/cdev: switch to fixed_size_llseek() pci/proc: switch to fixed_size_llseek() isapnp: switch to fixed_size_llseek() lpfc: switch to fixed_size_llseek() locks: give the blocked_hash its own spinlock locks: add a new "lm_owner_key" lock operation locks: turn the blocked_list into a hashtable locks: convert fl_link to a hlist_node locks: avoid taking global lock if possible when waking up blocked waiters locks: protect most of the file_lock handling with i_lock locks: encapsulate the fl_link list handling locks: make "added" in __posix_lock_file a bool ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/dcache.h11
-rw-r--r--include/linux/fs.h49
-rw-r--r--include/linux/fsnotify.h8
3 files changed, 36 insertions, 32 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 1a6bb81f0fe5..f42dbe145479 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -146,10 +146,8 @@ enum dentry_d_lock_class
struct dentry_operations {
int (*d_revalidate)(struct dentry *, unsigned int);
int (*d_weak_revalidate)(struct dentry *, unsigned int);
- int (*d_hash)(const struct dentry *, const struct inode *,
- struct qstr *);
- int (*d_compare)(const struct dentry *, const struct inode *,
- const struct dentry *, const struct inode *,
+ int (*d_hash)(const struct dentry *, struct qstr *);
+ int (*d_compare)(const struct dentry *, const struct dentry *,
unsigned int, const char *, const struct qstr *);
int (*d_delete)(const struct dentry *);
void (*d_release)(struct dentry *);
@@ -246,6 +244,8 @@ extern struct dentry * d_make_root(struct inode *);
/* <clickety>-<click> the ramfs-type tree */
extern void d_genocide(struct dentry *);
+extern void d_tmpfile(struct dentry *, struct inode *);
+
extern struct dentry *d_find_alias(struct inode *);
extern void d_prune_aliases(struct inode *);
@@ -300,8 +300,7 @@ extern struct dentry *d_lookup(const struct dentry *, const struct qstr *);
extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *);
extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *);
extern struct dentry *__d_lookup_rcu(const struct dentry *parent,
- const struct qstr *name,
- unsigned *seq, struct inode *inode);
+ const struct qstr *name, unsigned *seq);
/**
* __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f8a5240541b7..2b82c8041490 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -908,6 +908,7 @@ struct file_lock_operations {
struct lock_manager_operations {
int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
+ unsigned long (*lm_owner_key)(struct file_lock *);
void (*lm_notify)(struct file_lock *); /* unblock callback */
int (*lm_grant)(struct file_lock *, struct file_lock *, int);
void (*lm_break)(struct file_lock *);
@@ -926,9 +927,27 @@ int locks_in_grace(struct net *);
/* that will die - we need it for nfs_lock_info */
#include <linux/nfs_fs_i.h>
+/*
+ * struct file_lock represents a generic "file lock". It's used to represent
+ * POSIX byte range locks, BSD (flock) locks, and leases. It's important to
+ * note that the same struct is used to represent both a request for a lock and
+ * the lock itself, but the same object is never used for both.
+ *
+ * FIXME: should we create a separate "struct lock_request" to help distinguish
+ * these two uses?
+ *
+ * The i_flock list is ordered by:
+ *
+ * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX
+ * 2) lock owner
+ * 3) lock range start
+ * 4) lock range end
+ *
+ * Obviously, the last two criteria only matter for POSIX locks.
+ */
struct file_lock {
struct file_lock *fl_next; /* singly linked list for this inode */
- struct list_head fl_link; /* doubly linked list of all locks */
+ struct hlist_node fl_link; /* node in global lists */
struct list_head fl_block; /* circular list of blocked processes */
fl_owner_t fl_owner;
unsigned int fl_flags;
@@ -994,7 +1013,7 @@ extern void locks_release_private(struct file_lock *);
extern void posix_test_lock(struct file *, struct file_lock *);
extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
extern int posix_lock_file_wait(struct file *, struct file_lock *);
-extern int posix_unblock_lock(struct file *, struct file_lock *);
+extern int posix_unblock_lock(struct file_lock *);
extern int vfs_test_lock(struct file *, struct file_lock *);
extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
@@ -1006,9 +1025,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **);
extern int lease_modify(struct file_lock **, int);
extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
-extern void locks_delete_block(struct file_lock *waiter);
-extern void lock_flocks(void);
-extern void unlock_flocks(void);
#else /* !CONFIG_FILE_LOCKING */
static inline int fcntl_getlk(struct file *file, struct flock __user *user)
{
@@ -1084,8 +1100,7 @@ static inline int posix_lock_file_wait(struct file *filp, struct file_lock *fl)
return -ENOLCK;
}
-static inline int posix_unblock_lock(struct file *filp,
- struct file_lock *waiter)
+static inline int posix_unblock_lock(struct file_lock *waiter)
{
return -ENOENT;
}
@@ -1150,19 +1165,6 @@ static inline int lock_may_write(struct inode *inode, loff_t start,
{
return 1;
}
-
-static inline void locks_delete_block(struct file_lock *waiter)
-{
-}
-
-static inline void lock_flocks(void)
-{
-}
-
-static inline void unlock_flocks(void)
-{
-}
-
#endif /* !CONFIG_FILE_LOCKING */
@@ -1580,6 +1582,7 @@ struct inode_operations {
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);
} ____cacheline_aligned;
ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
@@ -1743,6 +1746,7 @@ struct super_operations {
#define I_REFERENCED (1 << 8)
#define __I_DIO_WAKEUP 9
#define I_DIO_WAKEUP (1 << I_DIO_WAKEUP)
+#define I_LINKABLE (1 << 10)
#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
@@ -1896,7 +1900,6 @@ extern int current_umask(void);
extern struct kobject *fs_kobj;
#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
-extern int rw_verify_area(int, struct file *, loff_t *, size_t);
#define FLOCK_VERIFY_READ 1
#define FLOCK_VERIFY_WRITE 2
@@ -2309,7 +2312,6 @@ extern struct file * open_exec(const char *);
/* fs/dcache.c -- generic fs support functions */
extern int is_subdir(struct dentry *, struct dentry *);
extern int path_is_under(struct path *, struct path *);
-extern ino_t find_inode_number(struct dentry *, struct qstr *);
#include <linux/err.h>
@@ -2424,9 +2426,12 @@ extern void
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
extern loff_t noop_llseek(struct file *file, loff_t offset, int whence);
extern loff_t no_llseek(struct file *file, loff_t offset, int whence);
+extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize);
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence);
extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
int whence, loff_t maxsize, loff_t eof);
+extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
+ int whence, loff_t size);
extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp);
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index a78680a92dba..1c804b057fb1 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -38,7 +38,7 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3
static inline int fsnotify_perm(struct file *file, int mask)
{
struct path *path = &file->f_path;
- struct inode *inode = path->dentry->d_inode;
+ struct inode *inode = file_inode(file);
__u32 fsnotify_mask = 0;
int ret;
@@ -192,7 +192,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
static inline void fsnotify_access(struct file *file)
{
struct path *path = &file->f_path;
- struct inode *inode = path->dentry->d_inode;
+ struct inode *inode = file_inode(file);
__u32 mask = FS_ACCESS;
if (S_ISDIR(inode->i_mode))
@@ -210,7 +210,7 @@ static inline void fsnotify_access(struct file *file)
static inline void fsnotify_modify(struct file *file)
{
struct path *path = &file->f_path;
- struct inode *inode = path->dentry->d_inode;
+ struct inode *inode = file_inode(file);
__u32 mask = FS_MODIFY;
if (S_ISDIR(inode->i_mode))
@@ -228,7 +228,7 @@ static inline void fsnotify_modify(struct file *file)
static inline void fsnotify_open(struct file *file)
{
struct path *path = &file->f_path;
- struct inode *inode = path->dentry->d_inode;
+ struct inode *inode = file_inode(file);
__u32 mask = FS_OPEN;
if (S_ISDIR(inode->i_mode))