vserver 1.9.3
[linux-2.6.git] / include / linux / fs.h
index 1e60528..e7ddd96 100644 (file)
@@ -88,6 +88,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
 #define SPECIAL 4      /* For non-blockdevice requests in request queue */
 #define READ_SYNC      (READ | (1 << BIO_RW_SYNC))
 #define WRITE_SYNC     (WRITE | (1 << BIO_RW_SYNC))
+#define WRITE_BARRIER  ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
 
 #define SEL_IN         1
 #define SEL_OUT                2
@@ -119,7 +120,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
 #define MS_VERBOSE     32768
 #define MS_POSIXACL    (1<<16) /* VFS does not apply the umask */
 #define MS_ONE_SECOND  (1<<17) /* fs has 1 sec a/m/ctime resolution */
-#define MS_TAGXID      (1<<24) /* tag inodes with context information */
+#define MS_TAGXID      (1<<24) /* tag inodes with context information */
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1<<31)
 
@@ -345,14 +346,14 @@ struct address_space {
        struct inode            *host;          /* owner: inode, block_device */
        struct radix_tree_root  page_tree;      /* radix tree of all pages */
        spinlock_t              tree_lock;      /* and spinlock protecting it */
-       unsigned long           nrpages;        /* number of total pages */
-       pgoff_t                 writeback_index;/* writeback starts here */
-       struct address_space_operations *a_ops; /* methods */
-       struct prio_tree_root   i_mmap;         /* tree of private mappings */
        unsigned int            i_mmap_writable;/* count VM_SHARED mappings */
+       struct prio_tree_root   i_mmap;         /* tree of private and shared mappings */
        struct list_head        i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
        spinlock_t              i_mmap_lock;    /* protect tree, count, list */
        atomic_t                truncate_count; /* Cover race condition with truncate */
+       unsigned long           nrpages;        /* number of total pages */
+       pgoff_t                 writeback_index;/* writeback starts here */
+       struct address_space_operations *a_ops; /* methods */
        unsigned long           flags;          /* error bits/gfp mask */
        struct backing_dev_info *backing_dev_info; /* device readahead, etc */
        spinlock_t              private_lock;   /* for use by the address_space */
@@ -448,6 +449,7 @@ struct inode {
        unsigned long           i_version;
        unsigned long           i_blocks;
        unsigned short          i_bytes;
+       unsigned char           i_sock;
        spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
        struct semaphore        i_sem;
        struct rw_semaphore     i_alloc_sem;
@@ -467,6 +469,8 @@ struct inode {
        struct cdev             *i_cdev;
        int                     i_cindex;
 
+       __u32                   i_generation;
+
        unsigned long           i_dnotify_mask; /* Directory notify events */
        struct dnotify_struct   *i_dnotify; /* for directory notifications */
 
@@ -474,11 +478,9 @@ struct inode {
        unsigned long           dirtied_when;   /* jiffies of first dirtying */
 
        unsigned int            i_flags;
-       unsigned char           i_sock;
 
        atomic_t                i_writecount;
        void                    *i_security;
-       __u32                   i_generation;
        union {
                void            *generic_ip;
        } u;
@@ -566,8 +568,8 @@ struct file_ra_state {
        unsigned long prev_page;        /* Cache last read() position */
        unsigned long ahead_start;      /* Ahead window */
        unsigned long ahead_size;
-       unsigned long serial_cnt;       /* measure of sequentiality */
-       unsigned long average;          /* another measure of sequentiality */
+       unsigned long currnt_wnd_hit;   /* locality in the current window */
+       unsigned long average;          /* size of next current window */
        unsigned long ra_pages;         /* Maximum readahead window */
        unsigned long mmap_hit;         /* Cache hit stat for mmap accesses */
        unsigned long mmap_miss;        /* Cache miss stat for mmap accesses */
@@ -587,6 +589,8 @@ struct file {
        unsigned int            f_uid, f_gid;
        struct file_ra_state    f_ra;
 
+       xid_t                   f_xid;
+
        unsigned long           f_version;
        void                    *f_security;
 
@@ -607,11 +611,6 @@ extern spinlock_t files_lock;
 #define get_file(x)    atomic_inc(&(x)->f_count)
 #define file_count(x)  atomic_read(&(x)->f_count)
 
-/* Initialize and open a private file and allocate its security structure. */
-extern int open_private_file(struct file *, struct dentry *, int);
-/* Release a private file and free its security structure. */
-extern void close_private_file(struct file *file);
-
 #define        MAX_NON_LFS     ((1UL<<31) - 1)
 
 /* Page cache limit. The filesystems should put that into their s_maxbytes 
@@ -638,6 +637,18 @@ extern void close_private_file(struct file *file);
  */
 typedef struct files_struct *fl_owner_t;
 
+struct file_lock_operations {
+       void (*fl_insert)(struct file_lock *);  /* lock insertion callback */
+       void (*fl_remove)(struct file_lock *);  /* lock removal callback */
+       void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
+       void (*fl_release_private)(struct file_lock *);
+};
+
+struct lock_manager_operations {
+       int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
+       void (*fl_notify)(struct file_lock *);  /* unblock callback */
+};
+
 /* that will die - we need it for nfs_lock_info */
 #include <linux/nfs_fs_i.h>
 
@@ -654,13 +665,11 @@ struct file_lock {
        loff_t fl_start;
        loff_t fl_end;
 
-       void (*fl_notify)(struct file_lock *);  /* unblock callback */
-       void (*fl_insert)(struct file_lock *);  /* lock insertion callback */
-       void (*fl_remove)(struct file_lock *);  /* lock removal callback */
-
        struct fasync_struct *  fl_fasync; /* for lease break notifications */
        unsigned long fl_break_time;    /* for nonblocking lease breaks */
 
+       struct file_lock_operations *fl_ops;    /* Callbacks for filesystems */
+       struct lock_manager_operations *fl_lmops;       /* Callbacks for lockmanagers */
        union {
                struct nfs_lock_info    nfs_fl;
        } fl_u;
@@ -696,9 +705,11 @@ extern void locks_remove_posix(struct file *, fl_owner_t);
 extern void locks_remove_flock(struct file *);
 extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
 extern int posix_lock_file(struct file *, struct file_lock *);
+extern int posix_lock_file_wait(struct file *, struct file_lock *);
 extern void posix_block_lock(struct file_lock *, struct file_lock *);
 extern void posix_unblock_lock(struct file *, struct file_lock *);
 extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
+extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
 extern int __break_lease(struct inode *inode, unsigned int flags);
 extern void lease_get_mtime(struct inode *, struct timespec *time);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
@@ -822,6 +833,11 @@ extern int vfs_rmdir(struct inode *, struct dentry *);
 extern int vfs_unlink(struct inode *, struct dentry *);
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
+/*
+ * VFS dentry helper functions.
+ */
+extern void dentry_unhash(struct dentry *dentry);
+
 /*
  * File types
  *
@@ -838,6 +854,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de
 #define DT_SOCK                12
 #define DT_WHT         14
 
+#define OSYNC_METADATA (1<<0)
+#define OSYNC_DATA     (1<<1)
+#define OSYNC_INODE    (1<<2)
+int generic_osync_inode(struct inode *, struct address_space *, int);
+
 /*
  * This is the "filldir" function type, used by readdir() to let
  * the kernel specify what kind of dirent layout it wants to have.
@@ -906,6 +927,7 @@ struct file_operations {
        unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
        int (*check_flags)(int);
        int (*dir_notify)(struct file *filp, unsigned long arg);
+       int (*flock) (struct file *, int, struct file_lock *);
 };
 
 struct inode_operations {
@@ -952,7 +974,7 @@ struct super_operations {
        void (*read_inode) (struct inode *);
   
        void (*dirty_inode) (struct inode *);
-       void (*write_inode) (struct inode *, int);
+       int (*write_inode) (struct inode *, int);
        void (*put_inode) (struct inode *);
        void (*drop_inode) (struct inode *);
        void (*delete_inode) (struct inode *);
@@ -1141,6 +1163,7 @@ struct super_block *sget(struct file_system_type *type,
 struct super_block *get_sb_pseudo(struct file_system_type *, char *,
                        struct super_operations *ops, unsigned long);
 int __put_super(struct super_block *sb);
+int __put_super_and_need_restart(struct super_block *sb);
 void unnamed_dev_init(void);
 
 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
@@ -1423,7 +1446,11 @@ extern ssize_t generic_file_aio_read(struct kiocb *, char __user *, size_t, loff
 extern ssize_t __generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t *);
 extern ssize_t generic_file_aio_write(struct kiocb *, const char __user *, size_t, loff_t);
 extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *,
-                               unsigned long, loff_t *);
+               unsigned long, loff_t *);
+extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *,
+               unsigned long *, loff_t, loff_t *, size_t, size_t);
+extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *,
+               unsigned long, loff_t, loff_t *, size_t, ssize_t);
 extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
 extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
 ssize_t generic_file_write_nolock(struct file *file, const struct iovec *iov,
@@ -1461,18 +1488,21 @@ static inline void do_generic_file_read(struct file * filp, loff_t *ppos,
 ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        struct block_device *bdev, const struct iovec *iov, loff_t offset,
        unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
-       int needs_special_locking);
+       int lock_type);
+
+enum {
+       DIO_LOCKING = 1, /* need locking between buffered and direct access */
+       DIO_NO_LOCKING,  /* bdev; no locking at all between buffered/direct */
+       DIO_OWN_LOCKING, /* filesystem locks buffered and direct internally */
+};
 
-/*
- * For filesystems which need locking between buffered and direct access
- */
 static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
        struct inode *inode, struct block_device *bdev, const struct iovec *iov,
        loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
        dio_iodone_t end_io)
 {
        return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
-                               nr_segs, get_blocks, end_io, 1);
+                               nr_segs, get_blocks, end_io, DIO_LOCKING);
 }
 
 static inline ssize_t blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
@@ -1481,7 +1511,16 @@ static inline ssize_t blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
        dio_iodone_t end_io)
 {
        return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
-                               nr_segs, get_blocks, end_io, 0);
+                               nr_segs, get_blocks, end_io, DIO_NO_LOCKING);
+}
+
+static inline ssize_t blockdev_direct_IO_own_locking(int rw, struct kiocb *iocb,
+       struct inode *inode, struct block_device *bdev, const struct iovec *iov,
+       loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
+       dio_iodone_t end_io)
+{
+       return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
+                               nr_segs, get_blocks, end_io, DIO_OWN_LOCKING);
 }
 
 extern struct file_operations generic_ro_fops;
@@ -1562,6 +1601,39 @@ static inline ino_t parent_ino(struct dentry *dentry)
 /* kernel/fork.c */
 extern int unshare_files(void);
 
+/* Transaction based IO helpers */
+
+/*
+ * An argresp is stored in an allocated page and holds the
+ * size of the argument or response, along with its content
+ */
+struct simple_transaction_argresp {
+       ssize_t size;
+       char data[0];
+};
+
+#define SIMPLE_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct simple_transaction_argresp))
+
+char *simple_transaction_get(struct file *file, const char __user *buf,
+                               size_t size);
+ssize_t simple_transaction_read(struct file *file, char __user *buf,
+                               size_t size, loff_t *pos);
+int simple_transaction_release(struct inode *inode, struct file *file);
+
+static inline void simple_transaction_set(struct file *file, size_t n)
+{
+       struct simple_transaction_argresp *ar = file->private_data;
+
+       BUG_ON(n > SIMPLE_TRANSACTION_LIMIT);
+
+       /*
+        * The barrier ensures that ar->size will really remain zero until
+        * ar->data is ready for reading.
+        */
+       smp_mb();
+       ar->size = n;
+}
+
 #ifdef CONFIG_SECURITY
 static inline char *alloc_secdata(void)
 {