gfs2: Get rid of sd_reserving_log
authorAndreas Gruenbacher <agruenba@redhat.com>
Sun, 13 Dec 2020 08:21:34 +0000 (09:21 +0100)
committerAndreas Gruenbacher <agruenba@redhat.com>
Wed, 3 Feb 2021 17:37:24 +0000 (18:37 +0100)
This counter and the associated wait queue are only used so that
gfs2_make_fs_ro can efficiently wait for all pending log space
allocations to fail after setting the filesystem to read-only.  This
comes at the cost of waking up that wait queue very frequently.

Instead, when gfs2_log_reserve fails because the filesystem has become
read-only, Wake up sd_log_waitq.  In gfs2_make_fs_ro, set the file
system read-only and then wait until all the log space has been
released.  Give up and report the problem after a while.  With that,
sd_reserving_log and sd_reserving_log_wait can be removed.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/incore.h
fs/gfs2/log.c
fs/gfs2/log.h
fs/gfs2/ops_fstype.c
fs/gfs2/super.c
fs/gfs2/trans.c

index c3f6dd3..8f8676c 100644 (file)
@@ -849,9 +849,6 @@ struct gfs2_sbd {
        int sd_log_error; /* First log error */
        wait_queue_head_t sd_withdraw_wait;
 
-       atomic_t sd_reserving_log;
-       wait_queue_head_t sd_reserving_log_wait;
-
        unsigned int sd_log_flush_head;
 
        spinlock_t sd_ail_lock;
index 0fceb60..0da0549 100644 (file)
@@ -397,6 +397,15 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
        spin_unlock(&sdp->sd_ail_lock);
 }
 
+/**
+ * gfs2_log_is_empty - Check if the log is empty
+ * @sdp: The GFS2 superblock
+ */
+
+bool gfs2_log_is_empty(struct gfs2_sbd *sdp) {
+       return atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks;
+}
+
 /**
  * gfs2_log_release - Release a given number of log blocks
  * @sdp: The GFS2 superblock
@@ -461,13 +470,9 @@ retry:
                } while(free_blocks <= wanted);
                finish_wait(&sdp->sd_log_waitq, &wait);
        }
-       atomic_inc(&sdp->sd_reserving_log);
        if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks,
-                               free_blocks - blks) != free_blocks) {
-               if (atomic_dec_and_test(&sdp->sd_reserving_log))
-                       wake_up(&sdp->sd_reserving_log_wait);
+                               free_blocks - blks) != free_blocks)
                goto retry;
-       }
        atomic_sub(blks, &sdp->sd_log_blks_needed);
        trace_gfs2_log_blocks(sdp, -blks);
 
@@ -483,8 +488,6 @@ retry:
                gfs2_log_release(sdp, blks);
                ret = -EROFS;
        }
-       if (atomic_dec_and_test(&sdp->sd_reserving_log))
-               wake_up(&sdp->sd_reserving_log_wait);
        return ret;
 }
 
index a9cdbc9..16efbe6 100644 (file)
@@ -64,6 +64,7 @@ static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip)
 extern void gfs2_ordered_del_inode(struct gfs2_inode *ip);
 extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct);
 extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
+extern bool gfs2_log_is_empty(struct gfs2_sbd *sdp);
 extern void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks);
 extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
 extern void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
index 61fce59..986dc2e 100644 (file)
@@ -136,8 +136,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
        init_rwsem(&sdp->sd_log_flush_lock);
        atomic_set(&sdp->sd_log_in_flight, 0);
-       atomic_set(&sdp->sd_reserving_log, 0);
-       init_waitqueue_head(&sdp->sd_reserving_log_wait);
        init_waitqueue_head(&sdp->sd_log_flush_wait);
        atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
        mutex_init(&sdp->sd_freeze_mutex);
index ed7a829..f188277 100644 (file)
@@ -645,13 +645,13 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
 
                gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN |
                               GFS2_LFC_MAKE_FS_RO);
-               wait_event(sdp->sd_reserving_log_wait,
-                          atomic_read(&sdp->sd_reserving_log) == 0);
-               gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) ==
-                                sdp->sd_jdesc->jd_blocks);
+               wait_event_timeout(sdp->sd_log_waitq,
+                                  gfs2_log_is_empty(sdp),
+                                  HZ * 5);
+               gfs2_assert_warn(sdp, gfs2_log_is_empty(sdp));
        } else {
-               wait_event_timeout(sdp->sd_reserving_log_wait,
-                                  atomic_read(&sdp->sd_reserving_log) == 0,
+               wait_event_timeout(sdp->sd_log_waitq,
+                                  gfs2_log_is_empty(sdp),
                                   HZ * 5);
        }
        if (gfs2_holder_initialized(&freeze_gh))
index db29ca2..aefe450 100644 (file)
@@ -71,6 +71,8 @@ int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
        error = gfs2_log_reserve(sdp, tr->tr_reserved);
        if (error) {
                sb_end_intwrite(sdp->sd_vfs);
+               if (error == -EROFS)
+                       wake_up(&sdp->sd_log_waitq);
                return error;
        }