Commit f3708fb5 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher
Browse files

gfs2: Get rid of sd_reserving_log



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: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent c968f578
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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;
+10 −7
Original line number Diff line number Diff line
@@ -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 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
		} 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 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
		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;
}

+1 −0
Original line number Diff line number Diff line
@@ -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,
+0 −2
Original line number Diff line number Diff line
@@ -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);
+6 −6
Original line number Diff line number Diff line
@@ -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))
Loading