Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / fs / ceph / super.h
index 037cdfb..60aac3a 100644 (file)
 #define CEPH_MOUNT_OPT_MOUNTWAIT       (1<<12) /* mount waits if no mds is up */
 #define CEPH_MOUNT_OPT_NOQUOTADF       (1<<13) /* no root dir quota in statfs */
 #define CEPH_MOUNT_OPT_NOCOPYFROM      (1<<14) /* don't use RADOS 'copy-from' op */
+#define CEPH_MOUNT_OPT_ASYNC_DIROPS    (1<<15) /* allow async directory ops */
 
 #define CEPH_MOUNT_OPT_DEFAULT                 \
        (CEPH_MOUNT_OPT_DCACHE |                \
         CEPH_MOUNT_OPT_NOCOPYFROM)
 
 #define ceph_set_mount_opt(fsc, opt) \
-       (fsc)->mount_options->flags |= CEPH_MOUNT_OPT_##opt;
+       (fsc)->mount_options->flags |= CEPH_MOUNT_OPT_##opt
+#define ceph_clear_mount_opt(fsc, opt) \
+       (fsc)->mount_options->flags &= ~CEPH_MOUNT_OPT_##opt
 #define ceph_test_mount_opt(fsc, opt) \
        (!!((fsc)->mount_options->flags & CEPH_MOUNT_OPT_##opt))
 
@@ -170,9 +173,9 @@ struct ceph_cap {
        struct list_head caps_item;
 };
 
-#define CHECK_CAPS_NODELAY    1  /* do not delay any further */
-#define CHECK_CAPS_AUTHONLY   2  /* only check auth cap */
-#define CHECK_CAPS_FLUSH      4  /* flush any dirty caps */
+#define CHECK_CAPS_AUTHONLY   1  /* only check auth cap */
+#define CHECK_CAPS_FLUSH      2  /* flush any dirty caps */
+#define CHECK_CAPS_NOINVAL    4  /* don't invalidate pagecache */
 
 struct ceph_cap_flush {
        u64 tid;
@@ -284,6 +287,7 @@ struct ceph_dentry_info {
 #define CEPH_DENTRY_REFERENCED         1
 #define CEPH_DENTRY_LEASE_LIST         2
 #define CEPH_DENTRY_SHRINK_LIST                4
+#define CEPH_DENTRY_PRIMARY_LINK       8
 
 struct ceph_inode_xattrs_info {
        /*
@@ -315,13 +319,14 @@ struct ceph_inode_info {
        u64 i_inline_version;
        u32 i_time_warp_seq;
 
-       unsigned i_ceph_flags;
+       unsigned long i_ceph_flags;
        atomic64_t i_release_count;
        atomic64_t i_ordered_count;
        atomic64_t i_complete_seq[2];
 
        struct ceph_dir_layout i_dir_layout;
        struct ceph_file_layout i_layout;
+       struct ceph_file_layout i_cached_layout;        // for async creates
        char *i_symlink;
 
        /* for dirs */
@@ -352,7 +357,6 @@ struct ceph_inode_info {
        struct ceph_cap_flush *i_prealloc_cap_flush;
        struct list_head i_cap_flush_list;
        wait_queue_head_t i_cap_wq;      /* threads waiting on a capability */
-       unsigned long i_hold_caps_min; /* jiffies */
        unsigned long i_hold_caps_max; /* jiffies */
        struct list_head i_cap_delay_list;  /* for delayed cap release to mds */
        struct ceph_cap_reservation i_cap_migration_resv;
@@ -361,6 +365,8 @@ struct ceph_inode_info {
                                                    dirty|flushing caps */
        unsigned i_snap_caps;           /* cap bits for snapped files */
 
+       unsigned long i_last_rd;
+       unsigned long i_last_wr;
        int i_nr_by_mode[CEPH_FILE_MODE_BITS];  /* open file counts */
 
        struct mutex i_truncate_mutex;
@@ -375,7 +381,7 @@ struct ceph_inode_info {
 
        /* held references to caps */
        int i_pin_ref;
-       int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref;
+       int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref, i_fx_ref;
        int i_wrbuffer_ref, i_wrbuffer_ref_head;
        atomic_t i_filelock_ref;
        atomic_t i_shared_gen;       /* increment each time we get FILE_SHARED */
@@ -511,18 +517,18 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
  * Ceph inode.
  */
 #define CEPH_I_DIR_ORDERED     (1 << 0)  /* dentries in dir are ordered */
-#define CEPH_I_NODELAY         (1 << 1)  /* do not delay cap release */
 #define CEPH_I_FLUSH           (1 << 2)  /* do not delay flush of dirty metadata */
 #define CEPH_I_POOL_PERM       (1 << 3)  /* pool rd/wr bits are valid */
 #define CEPH_I_POOL_RD         (1 << 4)  /* can read from pool */
 #define CEPH_I_POOL_WR         (1 << 5)  /* can write to pool */
 #define CEPH_I_SEC_INITED      (1 << 6)  /* security initialized */
-#define CEPH_I_CAP_DROPPED     (1 << 7)  /* caps were forcibly dropped */
-#define CEPH_I_KICK_FLUSH      (1 << 8)  /* kick flushing caps */
-#define CEPH_I_FLUSH_SNAPS     (1 << 9)  /* need flush snapss */
-#define CEPH_I_ERROR_WRITE     (1 << 10) /* have seen write errors */
-#define CEPH_I_ERROR_FILELOCK  (1 << 11) /* have seen file lock errors */
-#define CEPH_I_ODIRECT         (1 << 12) /* inode in direct I/O mode */
+#define CEPH_I_KICK_FLUSH      (1 << 7)  /* kick flushing caps */
+#define CEPH_I_FLUSH_SNAPS     (1 << 8)  /* need flush snapss */
+#define CEPH_I_ERROR_WRITE     (1 << 9) /* have seen write errors */
+#define CEPH_I_ERROR_FILELOCK  (1 << 10) /* have seen file lock errors */
+#define CEPH_I_ODIRECT         (1 << 11) /* inode in direct I/O mode */
+#define CEPH_ASYNC_CREATE_BIT  (12)      /* async create in flight for this */
+#define CEPH_I_ASYNC_CREATE    (1 << CEPH_ASYNC_CREATE_BIT)
 
 /*
  * Masks of ceph inode work.
@@ -674,18 +680,12 @@ extern int __ceph_caps_revoking_other(struct ceph_inode_info *ci,
 extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
 extern int __ceph_caps_used(struct ceph_inode_info *ci);
 
-extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci);
-
-/*
- * wanted, by virtue of open file modes AND cap refs (buffered/cached data)
- */
-static inline int __ceph_caps_wanted(struct ceph_inode_info *ci)
+static inline bool __ceph_is_file_opened(struct ceph_inode_info *ci)
 {
-       int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
-       if (w & CEPH_CAP_FILE_BUFFER)
-               w |= CEPH_CAP_FILE_EXCL;  /* we want EXCL if dirty data */
-       return w;
+       return ci->i_nr_by_mode[0];
 }
+extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci);
+extern int __ceph_caps_wanted(struct ceph_inode_info *ci);
 
 /* what the mds thinks we want */
 extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check);
@@ -899,6 +899,9 @@ static inline bool __ceph_have_pending_cap_snap(struct ceph_inode_info *ci)
 }
 
 /* inode.c */
+struct ceph_mds_reply_info_in;
+struct ceph_mds_reply_dirfrag;
+
 extern const struct inode_operations ceph_file_iops;
 
 extern struct inode *ceph_alloc_inode(struct super_block *sb);
@@ -914,6 +917,11 @@ extern void ceph_fill_file_time(struct inode *inode, int issued,
                                u64 time_warp_seq, struct timespec64 *ctime,
                                struct timespec64 *mtime,
                                struct timespec64 *atime);
+extern int ceph_fill_inode(struct inode *inode, struct page *locked_page,
+                   struct ceph_mds_reply_info_in *iinfo,
+                   struct ceph_mds_reply_dirfrag *dirinfo,
+                   struct ceph_mds_session *session, int cap_fmode,
+                   struct ceph_cap_reservation *caps_reservation);
 extern int ceph_fill_trace(struct super_block *sb,
                           struct ceph_mds_request *req);
 extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
@@ -1042,7 +1050,7 @@ extern struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc,
                                     struct ceph_cap_reservation *ctx);
 extern void ceph_add_cap(struct inode *inode,
                         struct ceph_mds_session *session, u64 cap_id,
-                        int fmode, unsigned issued, unsigned wanted,
+                        unsigned issued, unsigned wanted,
                         unsigned cap, unsigned seq, u64 realmino, int flags,
                         struct ceph_cap **new_cap);
 extern void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release);
@@ -1058,8 +1066,12 @@ extern void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc,
                                          struct ceph_mds_session *session);
 extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
                                    struct ceph_mds_session *session);
+void ceph_kick_flushing_inode_caps(struct ceph_mds_session *session,
+                                  struct ceph_inode_info *ci);
 extern struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci,
                                             int mds);
+extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int caps,
+                               bool snap_rwsem_locked);
 extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps);
 extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
 extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
@@ -1084,8 +1096,10 @@ extern int ceph_try_get_caps(struct inode *inode,
                             int need, int want, bool nonblock, int *got);
 
 /* for counting open files by mode */
-extern void __ceph_get_fmode(struct ceph_inode_info *ci, int mode);
-extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode);
+extern void ceph_get_fmode(struct ceph_inode_info *ci, int mode, int count);
+extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode, int count);
+extern void __ceph_touch_fmode(struct ceph_inode_info *ci,
+                              struct ceph_mds_client *mdsc, int fmode);
 
 /* addr.c */
 extern const struct address_space_operations ceph_aops;
@@ -1097,7 +1111,7 @@ extern void ceph_pool_perm_destroy(struct ceph_mds_client* mdsc);
 /* file.c */
 extern const struct file_operations ceph_file_fops;
 
-extern int ceph_renew_caps(struct inode *inode);
+extern int ceph_renew_caps(struct inode *inode, int fmode);
 extern int ceph_open(struct inode *inode, struct file *file);
 extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
                            struct file *file, unsigned flags, umode_t mode);