Merge branch 'work.const-path' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-block.git] / include / linux / fs.h
index 09a68517e952a5d64eba7007060f7a03a3e5f786..98a18ccf3fc059c5bf24aa98de6df6872e119f98 100644 (file)
@@ -577,6 +577,18 @@ static inline void mapping_allow_writable(struct address_space *mapping)
 struct posix_acl;
 #define ACL_NOT_CACHED ((void *)(-1))
 
+static inline struct posix_acl *
+uncached_acl_sentinel(struct task_struct *task)
+{
+       return (void *)task + 1;
+}
+
+static inline bool
+is_uncached_acl(struct posix_acl *acl)
+{
+       return (long)acl & 1;
+}
+
 #define IOP_FASTPERM   0x0001
 #define IOP_LOOKUP     0x0002
 #define IOP_NOFOLLOW   0x0004
@@ -635,7 +647,7 @@ struct inode {
 
        /* Misc */
        unsigned long           i_state;
-       struct mutex            i_mutex;
+       struct rw_semaphore     i_rwsem;
 
        unsigned long           dirtied_when;   /* jiffies of first dirtying */
        unsigned long           dirtied_time_when;
@@ -672,6 +684,7 @@ struct inode {
                struct block_device     *i_bdev;
                struct cdev             *i_cdev;
                char                    *i_link;
+               unsigned                i_dir_seq;
        };
 
        __u32                   i_generation;
@@ -721,27 +734,42 @@ enum inode_i_mutex_lock_class
 
 static inline void inode_lock(struct inode *inode)
 {
-       mutex_lock(&inode->i_mutex);
+       down_write(&inode->i_rwsem);
 }
 
 static inline void inode_unlock(struct inode *inode)
 {
-       mutex_unlock(&inode->i_mutex);
+       up_write(&inode->i_rwsem);
+}
+
+static inline void inode_lock_shared(struct inode *inode)
+{
+       down_read(&inode->i_rwsem);
+}
+
+static inline void inode_unlock_shared(struct inode *inode)
+{
+       up_read(&inode->i_rwsem);
 }
 
 static inline int inode_trylock(struct inode *inode)
 {
-       return mutex_trylock(&inode->i_mutex);
+       return down_write_trylock(&inode->i_rwsem);
+}
+
+static inline int inode_trylock_shared(struct inode *inode)
+{
+       return down_read_trylock(&inode->i_rwsem);
 }
 
 static inline int inode_is_locked(struct inode *inode)
 {
-       return mutex_is_locked(&inode->i_mutex);
+       return rwsem_is_locked(&inode->i_rwsem);
 }
 
 static inline void inode_lock_nested(struct inode *inode, unsigned subclass)
 {
-       mutex_lock_nested(&inode->i_mutex, subclass);
+       down_write_nested(&inode->i_rwsem, subclass);
 }
 
 void lock_two_nondirectories(struct inode *, struct inode*);
@@ -929,7 +957,7 @@ static inline struct file *get_file(struct file *f)
 /* Page cache limit. The filesystems should put that into their s_maxbytes 
    limits, otherwise bad things can happen in VM. */ 
 #if BITS_PER_LONG==32
-#define MAX_LFS_FILESIZE       (((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
+#define MAX_LFS_FILESIZE       (((loff_t)PAGE_SIZE << (BITS_PER_LONG-1))-1)
 #elif BITS_PER_LONG==64
 #define MAX_LFS_FILESIZE       ((loff_t)0x7fffffffffffffffLL)
 #endif
@@ -1241,6 +1269,16 @@ static inline struct inode *file_inode(const struct file *f)
        return f->f_inode;
 }
 
+static inline struct dentry *file_dentry(const struct file *file)
+{
+       struct dentry *dentry = file->f_path.dentry;
+
+       if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
+               return dentry->d_op->d_real(dentry, file_inode(file));
+       else
+               return dentry;
+}
+
 static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
 {
        return locks_lock_inode_wait(file_inode(filp), fl);
@@ -1636,6 +1674,7 @@ struct file_operations {
        ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
        ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
        int (*iterate) (struct file *, struct dir_context *);
+       int (*iterate_shared) (struct file *, struct dir_context *);
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
        long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
@@ -1690,7 +1729,8 @@ struct inode_operations {
        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);
-       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+       ssize_t (*getxattr) (struct dentry *, struct inode *,
+                            const char *, void *, size_t);
        ssize_t (*listxattr) (struct dentry *, char *, size_t);
        int (*removexattr) (struct dentry *, const char *);
        int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
@@ -2067,7 +2107,7 @@ extern int generic_update_time(struct inode *, struct timespec *, int);
 /* /sys/fs */
 extern struct kobject *fs_kobj;
 
-#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
+#define MAX_RW_COUNT (INT_MAX & PAGE_MASK)
 
 #ifdef CONFIG_MANDATORY_FILE_LOCKING
 extern int locks_mandatory_locked(struct file *);
@@ -3094,6 +3134,13 @@ static inline bool dir_relax(struct inode *inode)
        return !IS_DEADDIR(inode);
 }
 
+static inline bool dir_relax_shared(struct inode *inode)
+{
+       inode_unlock_shared(inode);
+       inode_lock_shared(inode);
+       return !IS_DEADDIR(inode);
+}
+
 extern bool path_noexec(const struct path *path);
 extern void inode_nohighmem(struct inode *inode);