Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 367269
b: refs/heads/master
c: 16ca941
h: refs/heads/master
i:
  367267: ba9488f
v: v3
  • Loading branch information
Benjamin Marzinski authored and Steven Whitehouse committed Apr 8, 2013
1 parent 8bdc5a6 commit d13a98d
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 20095218fb882139527c0e04b8e63869fa057b14
refs/heads/master: 16ca9412d8018188bddda29c3fee88471b94e3cb
2 changes: 1 addition & 1 deletion trunk/fs/gfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
if (atomic_read(&bh->b_count))
goto cannot_release;
bd = bh->b_private;
if (bd && bd->bd_ail)
if (bd && bd->bd_tr)
goto cannot_release;
if (buffer_pinned(bh) || buffer_dirty(bh))
goto not_possible;
Expand Down
17 changes: 8 additions & 9 deletions trunk/fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ struct gfs2_holder;
struct gfs2_glock;
struct gfs2_quota_data;
struct gfs2_trans;
struct gfs2_ail;
struct gfs2_jdesc;
struct gfs2_sbd;
struct lm_lockops;
Expand All @@ -53,7 +52,7 @@ struct gfs2_log_header_host {

struct gfs2_log_operations {
void (*lo_before_commit) (struct gfs2_sbd *sdp);
void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai);
void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr);
void (*lo_before_scan) (struct gfs2_jdesc *jd,
struct gfs2_log_header_host *head, int pass);
int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start,
Expand Down Expand Up @@ -139,7 +138,7 @@ struct gfs2_bufdata {
struct list_head bd_list;
const struct gfs2_log_operations *bd_ops;

struct gfs2_ail *bd_ail;
struct gfs2_trans *bd_tr;
struct list_head bd_ail_st_list;
struct list_head bd_ail_gl_list;
};
Expand Down Expand Up @@ -433,21 +432,20 @@ struct gfs2_trans {
struct gfs2_holder tr_t_gh;

int tr_touched;
int tr_attached;

unsigned int tr_num_buf_new;
unsigned int tr_num_databuf_new;
unsigned int tr_num_buf_rm;
unsigned int tr_num_databuf_rm;
unsigned int tr_num_revoke;
unsigned int tr_num_revoke_rm;
};

struct gfs2_ail {
struct list_head ai_list;
struct list_head tr_list;

unsigned int ai_first;
struct list_head ai_ail1_list;
struct list_head ai_ail2_list;
unsigned int tr_first;
struct list_head tr_ail1_list;
struct list_head tr_ail2_list;
};

struct gfs2_journal_extent {
Expand Down Expand Up @@ -710,6 +708,7 @@ struct gfs2_sbd {

spinlock_t sd_log_lock;

struct gfs2_trans *sd_log_tr;
unsigned int sd_log_blks_reserved;
unsigned int sd_log_commited_buf;
unsigned int sd_log_commited_databuf;
Expand Down
104 changes: 57 additions & 47 deletions trunk/fs/gfs2/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,

void gfs2_remove_from_ail(struct gfs2_bufdata *bd)
{
bd->bd_ail = NULL;
bd->bd_tr = NULL;
list_del_init(&bd->bd_ail_st_list);
list_del_init(&bd->bd_ail_gl_list);
atomic_dec(&bd->bd_gl->gl_ail_count);
Expand All @@ -90,7 +90,7 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd)

static int gfs2_ail1_start_one(struct gfs2_sbd *sdp,
struct writeback_control *wbc,
struct gfs2_ail *ai)
struct gfs2_trans *tr)
__releases(&sdp->sd_ail_lock)
__acquires(&sdp->sd_ail_lock)
{
Expand All @@ -99,15 +99,15 @@ __acquires(&sdp->sd_ail_lock)
struct gfs2_bufdata *bd, *s;
struct buffer_head *bh;

list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, bd_ail_st_list) {
list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) {
bh = bd->bd_bh;

gfs2_assert(sdp, bd->bd_ail == ai);
gfs2_assert(sdp, bd->bd_tr == tr);

if (!buffer_busy(bh)) {
if (!buffer_uptodate(bh))
gfs2_io_error_bh(sdp, bh);
list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list);
continue;
}

Expand All @@ -116,7 +116,7 @@ __acquires(&sdp->sd_ail_lock)
if (gl == bd->bd_gl)
continue;
gl = bd->bd_gl;
list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list);
list_move(&bd->bd_ail_st_list, &tr->tr_ail1_list);
mapping = bh->b_page->mapping;
if (!mapping)
continue;
Expand Down Expand Up @@ -144,15 +144,15 @@ __acquires(&sdp->sd_ail_lock)
void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
{
struct list_head *head = &sdp->sd_ail1_list;
struct gfs2_ail *ai;
struct gfs2_trans *tr;

trace_gfs2_ail_flush(sdp, wbc, 1);
spin_lock(&sdp->sd_ail_lock);
restart:
list_for_each_entry_reverse(ai, head, ai_list) {
list_for_each_entry_reverse(tr, head, tr_list) {
if (wbc->nr_to_write <= 0)
break;
if (gfs2_ail1_start_one(sdp, wbc, ai))
if (gfs2_ail1_start_one(sdp, wbc, tr))
goto restart;
}
spin_unlock(&sdp->sd_ail_lock);
Expand Down Expand Up @@ -183,20 +183,20 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp)
*
*/

static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
{
struct gfs2_bufdata *bd, *s;
struct buffer_head *bh;

list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list,
bd_ail_st_list) {
bh = bd->bd_bh;
gfs2_assert(sdp, bd->bd_ail == ai);
gfs2_assert(sdp, bd->bd_tr == tr);
if (buffer_busy(bh))
continue;
if (!buffer_uptodate(bh))
gfs2_io_error_bh(sdp, bh);
list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list);
}

}
Expand All @@ -210,14 +210,14 @@ static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)

static int gfs2_ail1_empty(struct gfs2_sbd *sdp)
{
struct gfs2_ail *ai, *s;
struct gfs2_trans *tr, *s;
int ret;

spin_lock(&sdp->sd_ail_lock);
list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) {
gfs2_ail1_empty_one(sdp, ai);
if (list_empty(&ai->ai_ail1_list))
list_move(&ai->ai_list, &sdp->sd_ail2_list);
list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) {
gfs2_ail1_empty_one(sdp, tr);
if (list_empty(&tr->tr_ail1_list))
list_move(&tr->tr_list, &sdp->sd_ail2_list);
else
break;
}
Expand All @@ -229,13 +229,13 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp)

static void gfs2_ail1_wait(struct gfs2_sbd *sdp)
{
struct gfs2_ail *ai;
struct gfs2_trans *tr;
struct gfs2_bufdata *bd;
struct buffer_head *bh;

spin_lock(&sdp->sd_ail_lock);
list_for_each_entry_reverse(ai, &sdp->sd_ail1_list, ai_list) {
list_for_each_entry(bd, &ai->ai_ail1_list, bd_ail_st_list) {
list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) {
list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) {
bh = bd->bd_bh;
if (!buffer_locked(bh))
continue;
Expand All @@ -256,40 +256,40 @@ static void gfs2_ail1_wait(struct gfs2_sbd *sdp)
*
*/

static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
{
struct list_head *head = &ai->ai_ail2_list;
struct list_head *head = &tr->tr_ail2_list;
struct gfs2_bufdata *bd;

while (!list_empty(head)) {
bd = list_entry(head->prev, struct gfs2_bufdata,
bd_ail_st_list);
gfs2_assert(sdp, bd->bd_ail == ai);
gfs2_assert(sdp, bd->bd_tr == tr);
gfs2_remove_from_ail(bd);
}
}

static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
{
struct gfs2_ail *ai, *safe;
struct gfs2_trans *tr, *safe;
unsigned int old_tail = sdp->sd_log_tail;
int wrap = (new_tail < old_tail);
int a, b, rm;

spin_lock(&sdp->sd_ail_lock);

list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) {
a = (old_tail <= ai->ai_first);
b = (ai->ai_first < new_tail);
list_for_each_entry_safe(tr, safe, &sdp->sd_ail2_list, tr_list) {
a = (old_tail <= tr->tr_first);
b = (tr->tr_first < new_tail);
rm = (wrap) ? (a || b) : (a && b);
if (!rm)
continue;

gfs2_ail2_empty_one(sdp, ai);
list_del(&ai->ai_list);
gfs2_assert_warn(sdp, list_empty(&ai->ai_ail1_list));
gfs2_assert_warn(sdp, list_empty(&ai->ai_ail2_list));
kfree(ai);
gfs2_ail2_empty_one(sdp, tr);
list_del(&tr->tr_list);
gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list));
gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list));
kfree(tr);
}

spin_unlock(&sdp->sd_ail_lock);
Expand Down Expand Up @@ -435,16 +435,17 @@ static unsigned int calc_reserved(struct gfs2_sbd *sdp)

static unsigned int current_tail(struct gfs2_sbd *sdp)
{
struct gfs2_ail *ai;
struct gfs2_trans *tr;
unsigned int tail;

spin_lock(&sdp->sd_ail_lock);

if (list_empty(&sdp->sd_ail1_list)) {
tail = sdp->sd_log_head;
} else {
ai = list_entry(sdp->sd_ail1_list.prev, struct gfs2_ail, ai_list);
tail = ai->ai_first;
tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans,
tr_list);
tail = tr->tr_first;
}

spin_unlock(&sdp->sd_ail_lock);
Expand Down Expand Up @@ -600,7 +601,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)

void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
{
struct gfs2_ail *ai;
struct gfs2_trans *tr;

down_write(&sdp->sd_log_flush_lock);

Expand All @@ -611,9 +612,12 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
}
trace_gfs2_log_flush(sdp, 1);

ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL);
INIT_LIST_HEAD(&ai->ai_ail1_list);
INIT_LIST_HEAD(&ai->ai_ail2_list);
tr = sdp->sd_log_tr;
if (tr) {
sdp->sd_log_tr = NULL;
INIT_LIST_HEAD(&tr->tr_ail1_list);
INIT_LIST_HEAD(&tr->tr_ail2_list);
}

if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) {
printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf,
Expand All @@ -630,7 +634,8 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)

sdp->sd_log_flush_head = sdp->sd_log_head;
sdp->sd_log_flush_wrapped = 0;
ai->ai_first = sdp->sd_log_flush_head;
if (tr)
tr->tr_first = sdp->sd_log_flush_head;

gfs2_ordered_write(sdp);
lops_before_commit(sdp);
Expand All @@ -643,7 +648,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
trace_gfs2_log_blocks(sdp, -1);
log_write_header(sdp, 0);
}
lops_after_commit(sdp, ai);
lops_after_commit(sdp, tr);

gfs2_log_lock(sdp);
sdp->sd_log_head = sdp->sd_log_flush_head;
Expand All @@ -653,16 +658,16 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
sdp->sd_log_commited_revoke = 0;

spin_lock(&sdp->sd_ail_lock);
if (!list_empty(&ai->ai_ail1_list)) {
list_add(&ai->ai_list, &sdp->sd_ail1_list);
ai = NULL;
if (tr && !list_empty(&tr->tr_ail1_list)) {
list_add(&tr->tr_list, &sdp->sd_ail1_list);
tr = NULL;
}
spin_unlock(&sdp->sd_ail_lock);
gfs2_log_unlock(sdp);
trace_gfs2_log_flush(sdp, 0);
up_write(&sdp->sd_log_flush_lock);

kfree(ai);
kfree(tr);
}

static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
Expand All @@ -687,6 +692,12 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
sdp->sd_jdesc->jd_blocks);
sdp->sd_log_blks_reserved = reserved;

if (sdp->sd_log_tr == NULL &&
(tr->tr_num_buf_new || tr->tr_num_databuf_new)) {
gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl);
sdp->sd_log_tr = tr;
tr->tr_attached = 1;
}
gfs2_log_unlock(sdp);
}

Expand All @@ -708,7 +719,6 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
{
log_refund(sdp, tr);
up_read(&sdp->sd_log_flush_lock);

if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) ||
((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) >
Expand Down
Loading

0 comments on commit d13a98d

Please sign in to comment.