Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[cascardo/linux.git] / include / linux / fs.h
index 5d1f6fa..ea80f1c 100644 (file)
@@ -123,6 +123,9 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 /* File is opened with O_PATH; almost nothing can be done with it */
 #define FMODE_PATH             ((__force fmode_t)0x4000)
 
+/* File needs atomic accesses to f_pos */
+#define FMODE_ATOMIC_POS       ((__force fmode_t)0x8000)
+
 /* File was opened by fanotify and shouldn't generate fanotify events */
 #define FMODE_NONOTIFY         ((__force fmode_t)0x1000000)
 
@@ -416,6 +419,7 @@ struct address_space {
        struct mutex            i_mmap_mutex;   /* protect tree, count, list */
        /* Protected by tree_lock together with the radix tree */
        unsigned long           nrpages;        /* number of total pages */
+       unsigned long           nrshadows;      /* number of shadow entries */
        pgoff_t                 writeback_index;/* writeback starts here */
        const struct address_space_operations *a_ops;   /* methods */
        unsigned long           flags;          /* error bits/gfp mask */
@@ -586,6 +590,9 @@ struct inode {
        atomic_t                i_count;
        atomic_t                i_dio_count;
        atomic_t                i_writecount;
+#ifdef CONFIG_IMA
+       atomic_t                i_readcount; /* struct files open RO */
+#endif
        const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */
        struct file_lock        *i_flock;
        struct address_space    i_data;
@@ -606,9 +613,6 @@ struct inode {
        struct hlist_head       i_fsnotify_marks;
 #endif
 
-#ifdef CONFIG_IMA
-       atomic_t                i_readcount; /* struct files open RO */
-#endif
        void                    *i_private; /* fs or device private pointer */
 };
 
@@ -780,13 +784,14 @@ struct file {
        const struct file_operations    *f_op;
 
        /*
-        * Protects f_ep_links, f_flags, f_pos vs i_size in lseek SEEK_CUR.
+        * Protects f_ep_links, f_flags.
         * Must not be taken from IRQ context.
         */
        spinlock_t              f_lock;
        atomic_long_t           f_count;
        unsigned int            f_flags;
        fmode_t                 f_mode;
+       struct mutex            f_pos_lock;
        loff_t                  f_pos;
        struct fown_struct      f_owner;
        const struct cred       *f_cred;
@@ -808,7 +813,7 @@ struct file {
 #ifdef CONFIG_DEBUG_WRITECOUNT
        unsigned long f_mnt_write_state;
 #endif
-};
+} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
 
 struct file_handle {
        __u32 handle_bytes;
@@ -888,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
@@ -992,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
@@ -1012,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 *);
@@ -1030,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;
 }
@@ -1042,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;
 }
@@ -1083,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;
 }
@@ -1456,7 +1464,7 @@ extern int vfs_symlink(struct inode *, struct dentry *, const char *);
 extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **);
 extern int vfs_rmdir(struct inode *, struct dentry *);
 extern int vfs_unlink(struct inode *, struct dentry *, struct inode **);
-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **);
+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int);
 
 /*
  * VFS dentry helper functions.
@@ -1567,6 +1575,8 @@ struct inode_operations {
        int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
+       int (*rename2) (struct inode *, struct dentry *,
+                       struct inode *, struct dentry *, unsigned int);
        int (*setattr) (struct dentry *, struct iattr *);
        int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
        int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1909,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;
 
@@ -1918,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);
 
 /*
@@ -1941,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;
 }
 
@@ -1964,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;
@@ -1999,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;
 }
@@ -2021,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;
 }
@@ -2295,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))