summaryrefslogtreecommitdiffstats
path: root/fs/ceph/super.h
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2017-04-04 08:39:46 -0400
committerIlya Dryomov <idryomov@gmail.com>2017-05-04 03:19:22 -0400
commit26544c623e741ac6445f8b1ae369ee32ae1794ad (patch)
tree72810f59f5735dad3b29c5a127ae2a823fc1ff1d /fs/ceph/super.h
parent6fc1fe5e4cfc8939ee59a570b087946042a30140 (diff)
ceph: when seeing write errors on an inode, switch to sync writes
Currently, we don't have a real feedback mechanism in place for when we start seeing buffered writeback errors. If writeback is failing, there is nothing that prevents an application from continuing to dirty pages that aren't being cleaned. In the event that we're seeing write errors of any sort occur on an inode, have the callback set a flag to force further writes to be synchronous. When the next write succeeds, clear the flag to allow buffered writeback to continue. Since this is just a hint to the write submission mechanism, we only take the i_ceph_lock when a lockless check shows that the flag needs to be changed. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: "Yan, Zhengā€¯ <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/super.h')
-rw-r--r--fs/ceph/super.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index c68e6a045fb9..7334ee86b9e8 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -474,6 +474,32 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
474#define CEPH_I_CAP_DROPPED (1 << 8) /* caps were forcibly dropped */ 474#define CEPH_I_CAP_DROPPED (1 << 8) /* caps were forcibly dropped */
475#define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */ 475#define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */
476#define CEPH_I_FLUSH_SNAPS (1 << 10) /* need flush snapss */ 476#define CEPH_I_FLUSH_SNAPS (1 << 10) /* need flush snapss */
477#define CEPH_I_ERROR_WRITE (1 << 11) /* have seen write errors */
478
479/*
480 * We set the ERROR_WRITE bit when we start seeing write errors on an inode
481 * and then clear it when they start succeeding. Note that we do a lockless
482 * check first, and only take the lock if it looks like it needs to be changed.
483 * The write submission code just takes this as a hint, so we're not too
484 * worried if a few slip through in either direction.
485 */
486static inline void ceph_set_error_write(struct ceph_inode_info *ci)
487{
488 if (!(READ_ONCE(ci->i_ceph_flags) & CEPH_I_ERROR_WRITE)) {
489 spin_lock(&ci->i_ceph_lock);
490 ci->i_ceph_flags |= CEPH_I_ERROR_WRITE;
491 spin_unlock(&ci->i_ceph_lock);
492 }
493}
494
495static inline void ceph_clear_error_write(struct ceph_inode_info *ci)
496{
497 if (READ_ONCE(ci->i_ceph_flags) & CEPH_I_ERROR_WRITE) {
498 spin_lock(&ci->i_ceph_lock);
499 ci->i_ceph_flags &= ~CEPH_I_ERROR_WRITE;
500 spin_unlock(&ci->i_ceph_lock);
501 }
502}
477 503
478static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci, 504static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci,
479 long long release_count, 505 long long release_count,