Merge branch 'locks-3.15' of git://git.samba.org/jlayton/linux
[cascardo/linux.git] / include / linux / fs.h
index 215cb1b..a877ed3 100644 (file)
@@ -893,6 +893,7 @@ static inline int file_check_writeable(struct file *filp)
 #define FL_SLEEP       128     /* A blocking lock */
 #define FL_DOWNGRADE_PENDING   256 /* Lease is being downgraded */
 #define FL_UNLOCK_PENDING      512 /* Lease is being broken */
+#define FL_FILE_PVT    1024    /* lock is private to the file */
 
 /*
  * Special return value from posix_lock_file() and vfs_lock_file() for
@@ -997,12 +998,12 @@ struct file_lock {
 extern void send_sigio(struct fown_struct *fown, int fd, int band);
 
 #ifdef CONFIG_FILE_LOCKING
-extern int fcntl_getlk(struct file *, struct flock __user *);
+extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *);
 extern int fcntl_setlk(unsigned int, struct file *, unsigned int,
                        struct flock __user *);
 
 #if BITS_PER_LONG == 32
-extern int fcntl_getlk64(struct file *, struct flock64 __user *);
+extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 __user *);
 extern int fcntl_setlk64(unsigned int, struct file *, unsigned int,
                        struct flock64 __user *);
 #endif
@@ -1017,7 +1018,7 @@ extern struct file_lock * locks_alloc_lock(void);
 extern void locks_copy_lock(struct file_lock *, struct file_lock *);
 extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
 extern void locks_remove_posix(struct file *, fl_owner_t);
-extern void locks_remove_flock(struct file *);
+extern void locks_remove_file(struct file *);
 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 *);
@@ -1035,7 +1036,8 @@ 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);
 #else /* !CONFIG_FILE_LOCKING */
-static inline int fcntl_getlk(struct file *file, struct flock __user *user)
+static inline int fcntl_getlk(struct file *file, unsigned int cmd,
+                             struct flock __user *user)
 {
        return -EINVAL;
 }
@@ -1047,7 +1049,8 @@ static inline int fcntl_setlk(unsigned int fd, struct file *file,
 }
 
 #if BITS_PER_LONG == 32
-static inline int fcntl_getlk64(struct file *file, struct flock64 __user *user)
+static inline int fcntl_getlk64(struct file *file, unsigned int cmd,
+                               struct flock64 __user *user)
 {
        return -EINVAL;
 }
@@ -1088,7 +1091,7 @@ static inline void locks_remove_posix(struct file *filp, fl_owner_t owner)
        return;
 }
 
-static inline void locks_remove_flock(struct file *filp)
+static inline void locks_remove_file(struct file *filp)
 {
        return;
 }
@@ -1916,6 +1919,11 @@ extern int current_umask(void);
 extern void ihold(struct inode * inode);
 extern void iput(struct inode *);
 
+static inline struct inode *file_inode(struct file *f)
+{
+       return f->f_inode;
+}
+
 /* /sys/fs */
 extern struct kobject *fs_kobj;
 
@@ -1925,7 +1933,7 @@ extern struct kobject *fs_kobj;
 #define FLOCK_VERIFY_WRITE 2
 
 #ifdef CONFIG_FILE_LOCKING
-extern int locks_mandatory_locked(struct inode *);
+extern int locks_mandatory_locked(struct file *);
 extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
 
 /*
@@ -1948,10 +1956,10 @@ static inline int mandatory_lock(struct inode *ino)
        return IS_MANDLOCK(ino) && __mandatory_lock(ino);
 }
 
-static inline int locks_verify_locked(struct inode *inode)
+static inline int locks_verify_locked(struct file *file)
 {
-       if (mandatory_lock(inode))
-               return locks_mandatory_locked(inode);
+       if (mandatory_lock(file_inode(file)))
+               return locks_mandatory_locked(file);
        return 0;
 }
 
@@ -1971,6 +1979,12 @@ static inline int locks_verify_truncate(struct inode *inode,
 
 static inline int break_lease(struct inode *inode, unsigned int mode)
 {
+       /*
+        * Since this check is lockless, we must ensure that any refcounts
+        * taken are done before checking inode->i_flock. Otherwise, we could
+        * end up racing with tasks trying to set a new lease on this file.
+        */
+       smp_mb();
        if (inode->i_flock)
                return __break_lease(inode, mode, FL_LEASE);
        return 0;
@@ -2006,7 +2020,7 @@ static inline int break_deleg_wait(struct inode **delegated_inode)
 }
 
 #else /* !CONFIG_FILE_LOCKING */
-static inline int locks_mandatory_locked(struct inode *inode)
+static inline int locks_mandatory_locked(struct file *file)
 {
        return 0;
 }
@@ -2028,7 +2042,7 @@ static inline int mandatory_lock(struct inode *inode)
        return 0;
 }
 
-static inline int locks_verify_locked(struct inode *inode)
+static inline int locks_verify_locked(struct file *file)
 {
        return 0;
 }
@@ -2302,11 +2316,6 @@ static inline bool execute_ok(struct inode *inode)
        return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
 }
 
-static inline struct inode *file_inode(struct file *f)
-{
-       return f->f_inode;
-}
-
 static inline void file_start_write(struct file *file)
 {
        if (!S_ISREG(file_inode(file)->i_mode))