Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f55ab26a authored by Steven Whitehouse's avatar Steven Whitehouse
Browse files

[GFS2] Use mutices rather than semaphores



As well as a number of minor bug fixes, this patch changes GFS
to use mutices rather than semaphores. This results in better
information in case there are any locking problems.

Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 5c4e9e03
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ int gfs2_glock_put(struct gfs2_glock *gl)
	struct gfs2_gl_hash_bucket *bucket = gl->gl_bucket;
	int rv = 0;

	down(&sdp->sd_invalidate_inodes_mutex);
	mutex_lock(&sdp->sd_invalidate_inodes_mutex);

	write_lock(&bucket->hb_lock);
	if (kref_put(&gl->gl_ref, kill_glock)) {
@@ -161,7 +161,7 @@ int gfs2_glock_put(struct gfs2_glock *gl)
	}
	write_unlock(&bucket->hb_lock);
 out:
	up(&sdp->sd_invalidate_inodes_mutex);
	mutex_unlock(&sdp->sd_invalidate_inodes_mutex);
	return rv;
}

@@ -2312,9 +2312,9 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
		   invalidate_inodes_mutex prevents glock_put()'s during
		   an invalidate_inodes() */

		down(&sdp->sd_invalidate_inodes_mutex);
		mutex_lock(&sdp->sd_invalidate_inodes_mutex);
		invalidate_inodes(sdp->sd_vfs);
		up(&sdp->sd_invalidate_inodes_mutex);
		mutex_unlock(&sdp->sd_invalidate_inodes_mutex);
		yield();
	}
}
+11 −11
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ struct gfs2_rgrpd {
	uint64_t rd_rg_vn;
	struct gfs2_bitmap *rd_bits;
	unsigned int rd_bh_count;
	struct semaphore rd_mutex;
	struct mutex rd_mutex;
	uint32_t rd_free_clone;
	struct gfs2_log_element rd_le;
	uint32_t rd_last_alloc_data;
@@ -277,7 +277,7 @@ enum {
struct gfs2_file {
	unsigned long f_flags;		/* GFF_... */

	struct semaphore f_fl_mutex;
	struct mutex f_fl_mutex;
	struct gfs2_holder f_fl_gh;

	struct gfs2_inode *f_inode;
@@ -510,7 +510,7 @@ struct gfs2_sbd {
	struct gfs2_holder sd_live_gh;
	struct gfs2_glock *sd_rename_gl;
	struct gfs2_glock *sd_trans_gl;
	struct semaphore sd_invalidate_inodes_mutex;
	struct mutex sd_invalidate_inodes_mutex;

	/* Inode Stuff */

@@ -528,12 +528,12 @@ struct gfs2_sbd {

	/* Inum stuff */

	struct semaphore sd_inum_mutex;
	struct mutex sd_inum_mutex;

	/* StatFS stuff */

	spinlock_t sd_statfs_spin;
	struct semaphore sd_statfs_mutex;
	struct mutex sd_statfs_mutex;
	struct gfs2_statfs_change sd_statfs_master;
	struct gfs2_statfs_change sd_statfs_local;
	unsigned long sd_statfs_sync_time;
@@ -542,7 +542,7 @@ struct gfs2_sbd {

	uint64_t sd_rindex_vn;
	spinlock_t sd_rindex_spin;
	struct semaphore sd_rindex_mutex;
	struct mutex sd_rindex_mutex;
	struct list_head sd_rindex_list;
	struct list_head sd_rindex_mru_list;
	struct list_head sd_rindex_recent_list;
@@ -553,7 +553,7 @@ struct gfs2_sbd {

	struct list_head sd_jindex_list;
	spinlock_t sd_jindex_spin;
	struct semaphore sd_jindex_mutex;
	struct mutex sd_jindex_mutex;
	unsigned int sd_journals;
	unsigned long sd_jindex_refresh_time;

@@ -581,7 +581,7 @@ struct gfs2_sbd {
	struct list_head sd_unlinked_list;
	atomic_t sd_unlinked_count;
	spinlock_t sd_unlinked_spin;
	struct semaphore sd_unlinked_mutex;
	struct mutex sd_unlinked_mutex;

	unsigned int sd_unlinked_slots;
	unsigned int sd_unlinked_chunks;
@@ -592,7 +592,7 @@ struct gfs2_sbd {
	struct list_head sd_quota_list;
	atomic_t sd_quota_count;
	spinlock_t sd_quota_spin;
	struct semaphore sd_quota_mutex;
	struct mutex sd_quota_mutex;

	unsigned int sd_quota_slots;
	unsigned int sd_quota_chunks;
@@ -637,7 +637,7 @@ struct gfs2_sbd {
	int sd_log_idle;

	unsigned long sd_log_flush_time;
	struct semaphore sd_log_flush_lock;
	struct mutex sd_log_flush_lock;
	struct list_head sd_log_flush_list;

	unsigned int sd_log_flush_head;
@@ -659,7 +659,7 @@ struct gfs2_sbd {
	/* For quiescing the filesystem */

	struct gfs2_holder sd_freeze_gh;
	struct semaphore sd_freeze_lock;
	struct mutex sd_freeze_lock;
	unsigned int sd_freeze_count;

	/* Counters */
+6 −6
Original line number Diff line number Diff line
@@ -782,11 +782,11 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
	if (error)
		return error;
	down(&sdp->sd_inum_mutex);
	mutex_lock(&sdp->sd_inum_mutex);

	error = gfs2_meta_inode_buffer(ip, &bh);
	if (error) {
		up(&sdp->sd_inum_mutex);
		mutex_unlock(&sdp->sd_inum_mutex);
		gfs2_trans_end(sdp);
		return error;
	}
@@ -800,14 +800,14 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
		gfs2_inum_range_out(&ir,
				    bh->b_data + sizeof(struct gfs2_dinode));
		brelse(bh);
		up(&sdp->sd_inum_mutex);
		mutex_unlock(&sdp->sd_inum_mutex);
		gfs2_trans_end(sdp);
		return 0;
	}

	brelse(bh);

	up(&sdp->sd_inum_mutex);
	mutex_unlock(&sdp->sd_inum_mutex);
	gfs2_trans_end(sdp);

	return 1;
@@ -829,7 +829,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
	error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
	if (error)
		goto out;
	down(&sdp->sd_inum_mutex);
	mutex_lock(&sdp->sd_inum_mutex);

	error = gfs2_meta_inode_buffer(ip, &bh);
	if (error)
@@ -869,7 +869,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
	brelse(bh);

 out_end_trans:
	up(&sdp->sd_inum_mutex);
	mutex_unlock(&sdp->sd_inum_mutex);
	gfs2_trans_end(sdp);

 out:
+19 −35
Original line number Diff line number Diff line
@@ -23,29 +23,16 @@

#define PULL 1

static inline int is_done(struct gfs2_sbd *sdp, atomic_t *a)
{
	int done;
	gfs2_log_lock(sdp);
	done = atomic_read(a) ? 0 : 1;
	gfs2_log_unlock(sdp);
	return done;
}

static void do_lock_wait(struct gfs2_sbd *sdp, wait_queue_head_t *wq,
			 atomic_t *a)
{
	gfs2_log_unlock(sdp);
	wait_event(*wq, is_done(sdp, a));
	gfs2_log_lock(sdp);
	wait_event(*wq, atomic_read(a) ? 0 : 1);
}

static void lock_for_trans(struct gfs2_sbd *sdp)
{
	gfs2_log_lock(sdp);
	do_lock_wait(sdp, &sdp->sd_log_trans_wq, &sdp->sd_log_flush_count);
	atomic_inc(&sdp->sd_log_trans_count);
	gfs2_log_unlock(sdp);
}

static void unlock_from_trans(struct gfs2_sbd *sdp)
@@ -55,15 +42,13 @@ static void unlock_from_trans(struct gfs2_sbd *sdp)
		wake_up(&sdp->sd_log_flush_wq);
}

void gfs2_lock_for_flush(struct gfs2_sbd *sdp)
static void gfs2_lock_for_flush(struct gfs2_sbd *sdp)
{
	gfs2_log_lock(sdp);
	atomic_inc(&sdp->sd_log_flush_count);
	do_lock_wait(sdp, &sdp->sd_log_flush_wq, &sdp->sd_log_trans_count);
	gfs2_log_unlock(sdp);
}

void gfs2_unlock_from_flush(struct gfs2_sbd *sdp)
static void gfs2_unlock_from_flush(struct gfs2_sbd *sdp)
{
	gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_flush_count));
	if (atomic_dec_and_test(&sdp->sd_log_flush_count))
@@ -209,7 +194,6 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)

	for (;;) {
		gfs2_log_lock(sdp);

		if (list_empty(&list)) {
			list_add_tail(&list, &sdp->sd_log_blks_list);
			while (sdp->sd_log_blks_list.next != &list) {
@@ -225,7 +209,6 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
				set_current_state(TASK_RUNNING);
			}
		}

		/* Never give away the last block so we can
		   always pull the tail if we need to. */
		if (sdp->sd_log_blks_free > blks) {
@@ -237,14 +220,12 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
		}

		gfs2_log_unlock(sdp);

		gfs2_ail1_empty(sdp, 0);
		gfs2_log_flush(sdp);

		if (try++)
			gfs2_ail1_start(sdp, 0);
	}

	lock_for_trans(sdp);

	return 0;
@@ -512,21 +493,25 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
	ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL);
	INIT_LIST_HEAD(&ai->ai_ail1_list);
	INIT_LIST_HEAD(&ai->ai_ail2_list);

	gfs2_lock_for_flush(sdp);
	down(&sdp->sd_log_flush_lock);

	gfs2_assert_withdraw(sdp,
			sdp->sd_log_num_buf == sdp->sd_log_commited_buf);
	gfs2_assert_withdraw(sdp,
			sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);

	if (gl && list_empty(&gl->gl_le.le_list)) {
		up(&sdp->sd_log_flush_lock);
	if (gl) {
		gfs2_log_lock(sdp);
		if (list_empty(&gl->gl_le.le_list)) {
			gfs2_log_unlock(sdp);
			gfs2_unlock_from_flush(sdp);
			kfree(ai);
			return;
		}
		gfs2_log_unlock(sdp);
	}

	mutex_lock(&sdp->sd_log_flush_lock);

	gfs2_assert_withdraw(sdp,
			sdp->sd_log_num_buf == sdp->sd_log_commited_buf);
	gfs2_assert_withdraw(sdp,
			sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);

	sdp->sd_log_flush_head = sdp->sd_log_head;
	sdp->sd_log_flush_wrapped = 0;
@@ -538,7 +523,6 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
	else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle)
		log_write_header(sdp, 0, PULL);
	lops_after_commit(sdp, ai);

	sdp->sd_log_head = sdp->sd_log_flush_head;
	if (sdp->sd_log_flush_wrapped)
		sdp->sd_log_wraps++;
@@ -554,7 +538,7 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
	}
	gfs2_log_unlock(sdp);

	up(&sdp->sd_log_flush_lock);
	mutex_unlock(&sdp->sd_log_flush_lock);
	sdp->sd_vfs->s_dirt = 0;
	gfs2_unlock_from_flush(sdp);

@@ -627,7 +611,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)

void gfs2_log_shutdown(struct gfs2_sbd *sdp)
{
	down(&sdp->sd_log_flush_lock);
	mutex_lock(&sdp->sd_log_flush_lock);

	gfs2_assert_withdraw(sdp, !atomic_read(&sdp->sd_log_trans_count));
	gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved);
@@ -654,6 +638,6 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
		sdp->sd_log_wraps++;
	sdp->sd_log_tail = sdp->sd_log_head;

	up(&sdp->sd_log_flush_lock);
	mutex_unlock(&sdp->sd_log_flush_lock);
}
+0 −3
Original line number Diff line number Diff line
@@ -42,9 +42,6 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp,
	sdp->sd_log_head = sdp->sd_log_tail = value;
}

void gfs2_lock_for_flush(struct gfs2_sbd *sdp);
void gfs2_unlock_from_flush(struct gfs2_sbd *sdp);

unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
			    unsigned int ssize);

Loading