forked from Minki/linux
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: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
c968f5788b
commit
f3708fb59f
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user