Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linux
[pandora-kernel.git] / include / linux / fs.h
index 73ce69f..ed6ee47 100644 (file)
@@ -382,7 +382,6 @@ struct inodes_stat_t {
 #include <linux/path.h>
 #include <linux/stat.h>
 #include <linux/cache.h>
-#include <linux/kobject.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
 #include <linux/prio_tree.h>
@@ -392,6 +391,7 @@ struct inodes_stat_t {
 #include <linux/capability.h>
 #include <linux/semaphore.h>
 #include <linux/fiemap.h>
+#include <linux/rculist_bl.h>
 
 #include <asm/atomic.h>
 #include <asm/byteorder.h>
@@ -401,6 +401,7 @@ struct hd_geometry;
 struct iovec;
 struct nameidata;
 struct kiocb;
+struct kobject;
 struct pipe_inode_info;
 struct poll_table_struct;
 struct kstatfs;
@@ -663,8 +664,9 @@ struct block_device {
        void *                  bd_claiming;
        void *                  bd_holder;
        int                     bd_holders;
+       bool                    bd_write_holder;
 #ifdef CONFIG_SYSFS
-       struct list_head        bd_holder_list;
+       struct gendisk *        bd_holder_disk; /* for sysfs slave linkng */
 #endif
        struct block_device *   bd_contains;
        unsigned                bd_block_size;
@@ -733,16 +735,31 @@ struct posix_acl;
 #define ACL_NOT_CACHED ((void *)(-1))
 
 struct inode {
+       /* RCU path lookup touches following: */
+       umode_t                 i_mode;
+       uid_t                   i_uid;
+       gid_t                   i_gid;
+       const struct inode_operations   *i_op;
+       struct super_block      *i_sb;
+
+       spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
+       unsigned int            i_flags;
+       struct mutex            i_mutex;
+
+       unsigned long           i_state;
+       unsigned long           dirtied_when;   /* jiffies of first dirtying */
+
        struct hlist_node       i_hash;
        struct list_head        i_wb_list;      /* backing dev IO list */
        struct list_head        i_lru;          /* inode LRU list */
        struct list_head        i_sb_list;
-       struct list_head        i_dentry;
+       union {
+               struct list_head        i_dentry;
+               struct rcu_head         i_rcu;
+       };
        unsigned long           i_ino;
        atomic_t                i_count;
        unsigned int            i_nlink;
-       uid_t                   i_uid;
-       gid_t                   i_gid;
        dev_t                   i_rdev;
        unsigned int            i_blkbits;
        u64                     i_version;
@@ -755,13 +772,8 @@ struct inode {
        struct timespec         i_ctime;
        blkcnt_t                i_blocks;
        unsigned short          i_bytes;
-       umode_t                 i_mode;
-       spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
-       struct mutex            i_mutex;
        struct rw_semaphore     i_alloc_sem;
-       const struct inode_operations   *i_op;
        const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */
-       struct super_block      *i_sb;
        struct file_lock        *i_flock;
        struct address_space    *i_mapping;
        struct address_space    i_data;
@@ -782,11 +794,6 @@ struct inode {
        struct hlist_head       i_fsnotify_marks;
 #endif
 
-       unsigned long           i_state;
-       unsigned long           dirtied_when;   /* jiffies of first dirtying */
-
-       unsigned int            i_flags;
-
 #ifdef CONFIG_IMA
        /* protected by i_lock */
        unsigned int            i_readcount; /* struct files open RO */
@@ -1371,13 +1378,13 @@ struct super_block {
        const struct xattr_handler **s_xattr;
 
        struct list_head        s_inodes;       /* all inodes */
-       struct hlist_head       s_anon;         /* anonymous dentries for (nfs) exporting */
+       struct hlist_bl_head    s_anon;         /* anonymous dentries for (nfs) exporting */
 #ifdef CONFIG_SMP
        struct list_head __percpu *s_files;
 #else
        struct list_head        s_files;
 #endif
-       /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
+       /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */
        struct list_head        s_dentry_lru;   /* unused dentry lru */
        int                     s_nr_dentry_unused;     /* # of dentry on lru */
 
@@ -1416,6 +1423,7 @@ struct super_block {
         * generic_show_options()
         */
        char __rcu *s_options;
+       const struct dentry_operations *s_d_op; /* default d_op for dentries */
 };
 
 extern struct timespec current_fs_time(struct super_block *sb);
@@ -1544,9 +1552,18 @@ struct file_operations {
        int (*setlease)(struct file *, long, struct file_lock **);
 };
 
+#define IPERM_FLAG_RCU 0x0001
+
 struct inode_operations {
-       int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
        struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
+       void * (*follow_link) (struct dentry *, struct nameidata *);
+       int (*permission) (struct inode *, int, unsigned int);
+       int (*check_acl)(struct inode *, int, unsigned int);
+
+       int (*readlink) (struct dentry *, char __user *,int);
+       void (*put_link) (struct dentry *, struct nameidata *, void *);
+
+       int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
        int (*link) (struct dentry *,struct inode *,struct dentry *);
        int (*unlink) (struct inode *,struct dentry *);
        int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -1555,12 +1572,7 @@ struct inode_operations {
        int (*mknod) (struct inode *,struct dentry *,int,dev_t);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
-       int (*readlink) (struct dentry *, char __user *,int);
-       void * (*follow_link) (struct dentry *, struct nameidata *);
-       void (*put_link) (struct dentry *, struct nameidata *, void *);
        void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int);
-       int (*check_acl)(struct inode *, 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);
@@ -1572,7 +1584,7 @@ struct inode_operations {
                          loff_t len);
        int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
                      u64 len);
-};
+} ____cacheline_aligned;
 
 struct seq_file;
 
@@ -1823,7 +1835,9 @@ struct super_block *sget(struct file_system_type *type,
                        int (*set)(struct super_block *,void *),
                        void *data);
 extern struct dentry *mount_pseudo(struct file_system_type *, char *,
-       const struct super_operations *ops, unsigned long);
+       const struct super_operations *ops,
+       const struct dentry_operations *dops,
+       unsigned long);
 extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
 
 static inline void sb_mark_dirty(struct super_block *sb)
@@ -2005,7 +2019,6 @@ extern struct block_device *bdgrab(struct block_device *bdev);
 extern void bd_set_size(struct block_device *, loff_t size);
 extern void bd_forget(struct inode *inode);
 extern void bdput(struct block_device *);
-extern struct block_device *open_by_devnum(dev_t, fmode_t);
 extern void invalidate_bdev(struct block_device *);
 extern int sync_blockdev(struct block_device *bdev);
 extern struct super_block *freeze_bdev(struct block_device *);
@@ -2036,16 +2049,20 @@ extern const struct file_operations def_fifo_fops;
 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
 extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
 extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
-extern int blkdev_get(struct block_device *, fmode_t);
-extern int blkdev_put(struct block_device *, fmode_t);
-extern int bd_claim(struct block_device *, void *);
-extern void bd_release(struct block_device *);
+extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder);
+extern struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
+                                              void *holder);
+extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode,
+                                             void *holder);
+extern int blkdev_put(struct block_device *bdev, fmode_t mode);
 #ifdef CONFIG_SYSFS
-extern int bd_claim_by_disk(struct block_device *, void *, struct gendisk *);
-extern void bd_release_from_disk(struct block_device *, struct gendisk *);
+extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
 #else
-#define bd_claim_by_disk(bdev, holder, disk)   bd_claim(bdev, holder)
-#define bd_release_from_disk(bdev, disk)       bd_release(bdev)
+static inline int bd_link_disk_holder(struct block_device *bdev,
+                                     struct gendisk *disk)
+{
+       return 0;
+}
 #endif
 #endif
 
@@ -2081,8 +2098,6 @@ static inline void unregister_chrdev(unsigned int major, const char *name)
 extern const char *__bdevname(dev_t, char *buffer);
 extern const char *bdevname(struct block_device *bdev, char *buffer);
 extern struct block_device *lookup_bdev(const char *);
-extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
-extern void close_bdev_exclusive(struct block_device *, fmode_t);
 extern void blkdev_show(struct seq_file *,off_t);
 
 #else
@@ -2157,8 +2172,8 @@ extern sector_t bmap(struct inode *, sector_t);
 #endif
 extern int notify_change(struct dentry *, struct iattr *);
 extern int inode_permission(struct inode *, int);
-extern int generic_permission(struct inode *, int,
-               int (*check_acl)(struct inode *, int));
+extern int generic_permission(struct inode *, int, unsigned int,
+               int (*check_acl)(struct inode *, int, unsigned int));
 
 static inline bool execute_ok(struct inode *inode)
 {
@@ -2229,6 +2244,7 @@ extern void iget_failed(struct inode *);
 extern void end_writeback(struct inode *);
 extern void __destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);
+extern void free_inode_nonrcu(struct inode *inode);
 extern int should_remove_suid(struct dentry *);
 extern int file_remove_suid(struct file *);
 
@@ -2445,6 +2461,10 @@ static inline ino_t parent_ino(struct dentry *dentry)
 {
        ino_t res;
 
+       /*
+        * Don't strictly need d_lock here? If the parent ino could change
+        * then surely we'd have a deeper race in the caller?
+        */
        spin_lock(&dentry->d_lock);
        res = dentry->d_parent->d_inode->i_ino;
        spin_unlock(&dentry->d_lock);