Merge tag 'ceph-for-4.12-rc1' of git://github.com/ceph/ceph-client
[sfrench/cifs-2.6.git] / fs / ceph / super.h
index fe6b9cfc4013e63c8b6f6ea3b9b3bd1d4eb89364..a973acd8beaff67b5b0e67b1217c9bb7419c9982 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/writeback.h>
 #include <linux/slab.h>
 #include <linux/posix_acl.h>
+#include <linux/refcount.h>
 
 #include <linux/ceph/libceph.h>
 
@@ -92,8 +93,6 @@ struct ceph_fs_client {
        struct workqueue_struct *trunc_wq;
        atomic_long_t writeback_count;
 
-       struct backing_dev_info backing_dev_info;
-
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_dentry_lru, *debugfs_caps;
        struct dentry *debugfs_congestion_kb;
@@ -162,7 +161,7 @@ struct ceph_cap_flush {
  * data before flushing the snapped state (tracked here) back to the MDS.
  */
 struct ceph_cap_snap {
-       atomic_t nref;
+       refcount_t nref;
        struct list_head ci_item;
 
        struct ceph_cap_flush cap_flush;
@@ -191,7 +190,7 @@ struct ceph_cap_snap {
 
 static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
 {
-       if (atomic_dec_and_test(&capsnap->nref)) {
+       if (refcount_dec_and_test(&capsnap->nref)) {
                if (capsnap->xattr_blob)
                        ceph_buffer_put(capsnap->xattr_blob);
                kfree(capsnap);
@@ -473,6 +472,32 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
 #define CEPH_I_CAP_DROPPED     (1 << 8)  /* caps were forcibly dropped */
 #define CEPH_I_KICK_FLUSH      (1 << 9)  /* kick flushing caps */
 #define CEPH_I_FLUSH_SNAPS     (1 << 10) /* need flush snapss */
+#define CEPH_I_ERROR_WRITE     (1 << 11) /* have seen write errors */
+
+/*
+ * We set the ERROR_WRITE bit when we start seeing write errors on an inode
+ * and then clear it when they start succeeding. Note that we do a lockless
+ * check first, and only take the lock if it looks like it needs to be changed.
+ * The write submission code just takes this as a hint, so we're not too
+ * worried if a few slip through in either direction.
+ */
+static inline void ceph_set_error_write(struct ceph_inode_info *ci)
+{
+       if (!(READ_ONCE(ci->i_ceph_flags) & CEPH_I_ERROR_WRITE)) {
+               spin_lock(&ci->i_ceph_lock);
+               ci->i_ceph_flags |= CEPH_I_ERROR_WRITE;
+               spin_unlock(&ci->i_ceph_lock);
+       }
+}
+
+static inline void ceph_clear_error_write(struct ceph_inode_info *ci)
+{
+       if (READ_ONCE(ci->i_ceph_flags) & CEPH_I_ERROR_WRITE) {
+               spin_lock(&ci->i_ceph_lock);
+               ci->i_ceph_flags &= ~CEPH_I_ERROR_WRITE;
+               spin_unlock(&ci->i_ceph_lock);
+       }
+}
 
 static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci,
                                           long long release_count,