[PATCH] new helpers - collect_mounts() and release_collected_mounts()
[linux-2.6-block.git] / include / linux / fs.h
index 8b3580d0664e41f63d0a2d6cfd32a59ac99c97d5..50078bb30a1cb6c460fc043117bb38334a614c86 100644 (file)
@@ -123,6 +123,7 @@ extern int dir_notify_enable;
 #define MS_SLAVE       (1<<19) /* change to slave */
 #define MS_SHARED      (1<<20) /* change to shared */
 #define MS_RELATIME    (1<<21) /* Update atime relative to mtime/ctime. */
+#define MS_KERNMOUNT   (1<<22) /* this is a kern_mount call */
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1<<31)
 
@@ -300,9 +301,9 @@ struct kstatfs;
 struct vm_area_struct;
 struct vfsmount;
 
-extern void __init inode_init(unsigned long);
+extern void __init inode_init(void);
 extern void __init inode_init_early(void);
-extern void __init mnt_init(unsigned long);
+extern void __init mnt_init(void);
 extern void __init files_init(unsigned long);
 
 struct buffer_head;
@@ -329,6 +330,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #define ATTR_KILL_SUID 2048
 #define ATTR_KILL_SGID 4096
 #define ATTR_FILE      8192
+#define ATTR_KILL_PRIV 16384
+#define ATTR_OPEN      32768   /* Truncating from open(O_TRUNC) */
 
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
@@ -792,7 +795,7 @@ struct file {
        unsigned int            f_uid, f_gid;
        struct file_ra_state    f_ra;
 
-       unsigned long           f_version;
+       u64                     f_version;
 #ifdef CONFIG_SECURITY
        void                    *f_security;
 #endif
@@ -1002,6 +1005,7 @@ struct super_block {
        struct list_head        s_inodes;       /* all inodes */
        struct list_head        s_dirty;        /* dirty inodes */
        struct list_head        s_io;           /* parked for writeback */
+       struct list_head        s_more_io;      /* parked for more writeback */
        struct hlist_head       s_anon;         /* anonymous dentries for (nfs) exporting */
        struct list_head        s_files;
 
@@ -1260,16 +1264,68 @@ struct super_operations {
 #endif
 };
 
-/* Inode state bits.  Protected by inode_lock. */
-#define I_DIRTY_SYNC           1 /* Not dirty enough for O_DATASYNC */
-#define I_DIRTY_DATASYNC       2 /* Data-related inode changes pending */
-#define I_DIRTY_PAGES          4 /* Data-related inode changes pending */
-#define __I_LOCK               3
+/*
+ * Inode state bits.  Protected by inode_lock.
+ *
+ * Three bits determine the dirty state of the inode, I_DIRTY_SYNC,
+ * I_DIRTY_DATASYNC and I_DIRTY_PAGES.
+ *
+ * Four bits define the lifetime of an inode.  Initially, inodes are I_NEW,
+ * until that flag is cleared.  I_WILL_FREE, I_FREEING and I_CLEAR are set at
+ * various stages of removing an inode.
+ *
+ * Two bits are used for locking and completion notification, I_LOCK and I_SYNC.
+ *
+ * I_DIRTY_SYNC                Inode itself is dirty.
+ * I_DIRTY_DATASYNC    Data-related inode changes pending
+ * I_DIRTY_PAGES       Inode has dirty pages.  Inode itself may be clean.
+ * I_NEW               get_new_inode() sets i_state to I_LOCK|I_NEW.  Both
+ *                     are cleared by unlock_new_inode(), called from iget().
+ * I_WILL_FREE         Must be set when calling write_inode_now() if i_count
+ *                     is zero.  I_FREEING must be set when I_WILL_FREE is
+ *                     cleared.
+ * I_FREEING           Set when inode is about to be freed but still has dirty
+ *                     pages or buffers attached or the inode itself is still
+ *                     dirty.
+ * I_CLEAR             Set by clear_inode().  In this state the inode is clean
+ *                     and can be destroyed.
+ *
+ *                     Inodes that are I_WILL_FREE, I_FREEING or I_CLEAR are
+ *                     prohibited for many purposes.  iget() must wait for
+ *                     the inode to be completely released, then create it
+ *                     anew.  Other functions will just ignore such inodes,
+ *                     if appropriate.  I_LOCK is used for waiting.
+ *
+ * I_LOCK              Serves as both a mutex and completion notification.
+ *                     New inodes set I_LOCK.  If two processes both create
+ *                     the same inode, one of them will release its inode and
+ *                     wait for I_LOCK to be released before returning.
+ *                     Inodes in I_WILL_FREE, I_FREEING or I_CLEAR state can
+ *                     also cause waiting on I_LOCK, without I_LOCK actually
+ *                     being set.  find_inode() uses this to prevent returning
+ *                     nearly-dead inodes.
+ * I_SYNC              Similar to I_LOCK, but limited in scope to writeback
+ *                     of inode dirty data.  Having a seperate lock for this
+ *                     purpose reduces latency and prevents some filesystem-
+ *                     specific deadlocks.
+ *
+ * Q: Why does I_DIRTY_DATASYNC exist?  It appears as if it could be replaced
+ *    by (I_DIRTY_SYNC|I_DIRTY_PAGES).
+ * Q: What is the difference between I_WILL_FREE and I_FREEING?
+ * Q: igrab() only checks on (I_FREEING|I_WILL_FREE).  Should it also check on
+ *    I_CLEAR?  If not, why?
+ */
+#define I_DIRTY_SYNC           1
+#define I_DIRTY_DATASYNC       2
+#define I_DIRTY_PAGES          4
+#define I_NEW                  8
+#define I_WILL_FREE            16
+#define I_FREEING              32
+#define I_CLEAR                        64
+#define __I_LOCK               7
 #define I_LOCK                 (1 << __I_LOCK)
-#define I_FREEING              16
-#define I_CLEAR                        32
-#define I_NEW                  64
-#define I_WILL_FREE            128
+#define __I_SYNC               8
+#define I_SYNC                 (1 << __I_SYNC)
 
 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
 
@@ -1404,7 +1460,8 @@ void unnamed_dev_init(void);
 
 extern int register_filesystem(struct file_system_type *);
 extern int unregister_filesystem(struct file_system_type *);
-extern struct vfsmount *kern_mount(struct file_system_type *);
+extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
+#define kern_mount(type) kern_mount_data(type, NULL)
 extern int may_umount_tree(struct vfsmount *);
 extern int may_umount(struct vfsmount *);
 extern void umount_tree(struct vfsmount *, int, struct list_head *);
@@ -1413,6 +1470,8 @@ extern long do_mount(char *, char *, char *, unsigned long, void *);
 extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
 extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
                                  struct vfsmount *);
+extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
+extern void drop_collected_mounts(struct vfsmount *);
 
 extern int vfs_statfs(struct dentry *, struct kstatfs *);
 
@@ -1479,7 +1538,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
 
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
                       struct file *filp);
-extern long do_sys_open(int fdf, const char __user *filename, int flags,
+extern long do_sys_open(int dfd, const char __user *filename, int flags,
                        int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
@@ -1728,6 +1787,7 @@ extern int bdev_read_only(struct block_device *);
 extern int set_blocksize(struct block_device *, int);
 extern int sb_set_blocksize(struct super_block *, int);
 extern int sb_min_blocksize(struct super_block *, int);
+extern int sb_has_dirty_inodes(struct super_block *);
 
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
@@ -1866,6 +1926,8 @@ extern int vfs_fstat(unsigned int, struct kstat *);
 
 extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
 
+extern void get_filesystem(struct file_system_type *fs);
+extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
 extern struct super_block *user_get_super(dev_t);
@@ -1886,8 +1948,6 @@ extern int simple_empty(struct dentry *);
 extern int simple_readpage(struct file *file, struct page *page);
 extern int simple_prepare_write(struct file *file, struct page *page,
                        unsigned offset, unsigned to);
-extern int simple_commit_write(struct file *file, struct page *page,
-                               unsigned offset, unsigned to);
 extern int simple_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata);