Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 289809 Details for
Bug 423381
GFS2 - Filesystem withdraw when running postmark/benchp13 tests
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch that seems to fix the problem
423381.patch (text/plain), 30.79 KB, created by
Robert Peterson
on 2007-12-17 20:35:53 UTC
(
hide
)
Description:
Patch that seems to fix the problem
Filename:
MIME Type:
Creator:
Robert Peterson
Created:
2007-12-17 20:35:53 UTC
Size:
30.79 KB
patch
obsolete
>diff -pur gfs2-kmod-1.53-4.3.3/gfs2/daemon.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/daemon.c >--- gfs2-kmod-1.53-4.3.3/gfs2/daemon.c 2007-09-25 16:37:22.000000000 -0500 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/daemon.c 2007-12-17 11:01:31.000000000 -0600 >@@ -82,56 +82,6 @@ int gfs2_recoverd(void *data) > } > > /** >- * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks >- * @sdp: Pointer to GFS2 superblock >- * >- * Also, periodically check to make sure that we're using the most recent >- * journal index. >- */ >- >-int gfs2_logd(void *data) >-{ >- struct gfs2_sbd *sdp = data; >- struct gfs2_holder ji_gh; >- unsigned long t; >- int need_flush; >- >- while (!kthread_should_stop()) { >- /* Advance the log tail */ >- >- t = sdp->sd_log_flush_time + >- gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; >- >- gfs2_ail1_empty(sdp, DIO_ALL); >- gfs2_log_lock(sdp); >- need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); >- gfs2_log_unlock(sdp); >- if (need_flush || time_after_eq(jiffies, t)) { >- gfs2_log_flush(sdp, NULL); >- sdp->sd_log_flush_time = jiffies; >- } >- >- /* Check for latest journal index */ >- >- t = sdp->sd_jindex_refresh_time + >- gfs2_tune_get(sdp, gt_jindex_refresh_secs) * HZ; >- >- if (time_after_eq(jiffies, t)) { >- if (!gfs2_jindex_hold(sdp, &ji_gh)) >- gfs2_glock_dq_uninit(&ji_gh); >- sdp->sd_jindex_refresh_time = jiffies; >- } >- >- t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; >- if (freezing(current)) >- refrigerator(); >- schedule_timeout_interruptible(t); >- } >- >- return 0; >-} >- >-/** > * gfs2_quotad - Write cached quota changes into the quota file > * @sdp: Pointer to GFS2 superblock > * >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/daemon.h gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/daemon.h >--- gfs2-kmod-1.53-4.3.3/gfs2/daemon.h 2007-09-25 16:37:22.000000000 -0500 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/daemon.h 2007-12-17 11:04:48.000000000 -0600 >@@ -12,7 +12,6 @@ > > int gfs2_glockd(void *data); > int gfs2_recoverd(void *data); >-int gfs2_logd(void *data); > int gfs2_quotad(void *data); > > #endif /* __DAEMON_DOT_H__ */ >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/glock.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/glock.c >--- gfs2-kmod-1.53-4.3.3/gfs2/glock.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/glock.c 2007-12-17 13:37:13.000000000 -0600 >@@ -340,7 +340,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, > gl->gl_tchange = jiffies; > gl->gl_object = NULL; > gl->gl_sbd = sdp; >- lops_init_le(&gl->gl_le, &gfs2_glock_lops); > INIT_WORK(&gl->gl_work, glock_work_func, (void *)gl); > gl->gl_start = gl->gl_end = number; > >@@ -629,7 +628,6 @@ static void gfs2_glmutex_lock(struct gfs > struct gfs2_holder gh; > > gfs2_holder_init(gl, 0, 0, &gh); >- set_bit(HIF_MUTEX, &gh.gh_iflags); > set_bit(HIF_WAIT, &gh.gh_iflags); > list_add_tail(&gh.gh_list, &gl->gl_waiters1); > spin_unlock(&gl->gl_spin); >@@ -933,8 +931,8 @@ static void gfs2_glock_drop_th(struct gf > const struct gfs2_glock_operations *glops = gl->gl_ops; > unsigned int ret; > >- if (glops->go_drop_th) >- glops->go_drop_th(gl); >+ if (glops->go_xmote_th) >+ glops->go_xmote_th(gl); > > gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); > gfs2_assert_warn(sdp, list_empty(&gl->gl_holders)); >@@ -1900,8 +1898,6 @@ static int dump_glock(struct glock_iter > print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); > print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); > print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no"); >- print_dbg(gi, " le = %s\n", >- (list_empty(&gl->gl_le.le_list)) ? "no" : "yes"); > print_dbg(gi, " reclaim = %s\n", > (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); > print_dbg(gi, " ail = %d\n", atomic_read(&gl->gl_ail_count)); >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/glops.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/glops.c >--- gfs2-kmod-1.53-4.3.3/gfs2/glops.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/glops.c 2007-12-17 13:27:59.000000000 -0600 >@@ -480,14 +480,14 @@ static void rgrp_go_unlock(struct gfs2_h > } > > /** >- * trans_go_xmote_th - promote/demote the transaction glock >+ * trans_go_sync - promote/demote the transaction glock > * @gl: the glock > * @state: the requested state > * @flags: > * > */ > >-static void trans_go_xmote_th(struct gfs2_glock *gl) >+static void trans_go_sync(struct gfs2_glock *gl) > { > struct gfs2_sbd *sdp = gl->gl_sbd; > >@@ -531,24 +531,6 @@ static void trans_go_xmote_bh(struct gfs > } > > /** >- * trans_go_drop_th - unlock the transaction glock >- * @gl: the glock >- * >- * We want to sync the device even with localcaching. Remember >- * that localcaching journal replay only marks buffers dirty. >- */ >- >-static void trans_go_drop_th(struct gfs2_glock *gl) >-{ >- struct gfs2_sbd *sdp = gl->gl_sbd; >- >- if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { >- gfs2_meta_syncfs(sdp); >- gfs2_log_shutdown(sdp); >- } >-} >- >-/** > * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock > * @gl: the glock > * >@@ -576,7 +558,6 @@ const struct gfs2_glock_operations gfs2_ > > const struct gfs2_glock_operations gfs2_rgrp_glops = { > .go_xmote_th = meta_go_sync, >- .go_drop_th = meta_go_sync, > .go_inval = meta_go_inval, > .go_demote_ok = rgrp_go_demote_ok, > .go_lock = rgrp_go_lock, >@@ -586,9 +567,8 @@ const struct gfs2_glock_operations gfs2_ > }; > > const struct gfs2_glock_operations gfs2_trans_glops = { >- .go_xmote_th = trans_go_xmote_th, >+ .go_xmote_th = trans_go_sync, > .go_xmote_bh = trans_go_xmote_bh, >- .go_drop_th = trans_go_drop_th, > .go_type = LM_TYPE_NONDISK, > }; > >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/incore.h gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/incore.h >--- gfs2-kmod-1.53-4.3.3/gfs2/incore.h 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/incore.h 2007-12-17 12:20:32.000000000 -0600 >@@ -207,6 +207,7 @@ enum { > GLF_DEMOTE = 3, > GLF_PENDING_DEMOTE = 4, > GLF_DEMOTE_IN_PROGRESS = 6, >+ GLF_LFLUSH = 7, > }; > > struct gfs2_glock { >@@ -246,7 +247,6 @@ struct gfs2_glock { > > struct gfs2_sbd *gl_sbd; > >- struct gfs2_log_element gl_le; > struct list_head gl_ail_list; > atomic_t gl_ail_count; > struct work_struct gl_work; >@@ -464,13 +464,7 @@ struct gfs2_args { > struct gfs2_tune { > spinlock_t gt_spin; > >- unsigned int gt_ilimit; >- unsigned int gt_ilimit_tries; >- unsigned int gt_ilimit_min; > unsigned int gt_demote_secs; /* Cache retention for unheld glock */ >- unsigned int gt_incore_log_blocks; >- unsigned int gt_log_flush_secs; >- unsigned int gt_jindex_refresh_secs; /* Check for new journal index */ > > unsigned int gt_recoverd_secs; > unsigned int gt_logd_secs; >@@ -645,28 +639,29 @@ struct gfs2_sbd { > unsigned int sd_log_commited_databuf; > unsigned int sd_log_commited_revoke; > >- unsigned int sd_log_num_gl; >+ atomic_t sd_log_pinned; > unsigned int sd_log_num_buf; > unsigned int sd_log_num_revoke; > unsigned int sd_log_num_rg; > unsigned int sd_log_num_databuf; > >- struct list_head sd_log_le_gl; > struct list_head sd_log_le_buf; > struct list_head sd_log_le_revoke; > struct list_head sd_log_le_rg; > struct list_head sd_log_le_databuf; > struct list_head sd_log_le_ordered; > >- unsigned int sd_log_blks_free; >- struct mutex sd_log_reserve_mutex; >+ atomic_t sd_log_thresh1; >+ atomic_t sd_log_thresh2; >+ atomic_t sd_log_blks_free; >+ wait_queue_head_t sd_log_waitq; >+ wait_queue_head_t sd_logd_waitq; > > u64 sd_log_sequence; > unsigned int sd_log_head; > unsigned int sd_log_tail; > int sd_log_idle; > >- unsigned long sd_log_flush_time; > struct rw_semaphore sd_log_flush_lock; > atomic_t sd_log_in_flight; > wait_queue_head_t sd_log_flush_wait; >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/inode.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/inode.c >--- gfs2-kmod-1.53-4.3.3/gfs2/inode.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/inode.c 2007-12-13 11:36:36.000000000 -0600 >@@ -363,7 +363,7 @@ int gfs2_dinode_dealloc(struct gfs2_inod > if (error) > goto out_rg_gunlock; > >- gfs2_trans_add_gl(ip->i_gl); >+ set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); > > gfs2_free_di(rgd, ip); > >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/log.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/log.c >--- gfs2-kmod-1.53-4.3.3/gfs2/log.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/log.c 2007-12-17 12:48:02.000000000 -0600 >@@ -16,6 +16,7 @@ > #include <linux/crc32.h> > #include <linux/lm_interface.h> > #include <linux/delay.h> >+#include <linux/kthread.h> > > #include "gfs2.h" > #include "incore.h" >@@ -165,7 +166,7 @@ static int gfs2_ail1_empty_one(struct gf > return list_empty(&ai->ai_ail1_list); > } > >-static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) >+static void gfs2_ail1_start(struct gfs2_sbd *sdp) > { > struct list_head *head; > u64 sync_gen; >@@ -186,14 +187,7 @@ static void gfs2_ail1_start(struct gfs2_ > first_ai->ai_sync_gen = sync_gen; > gfs2_ail1_start_one(sdp, first_ai); /* This may drop log lock */ > >- if (flags & DIO_ALL) >- first = NULL; >- > while(!done) { >- if (first && (head->prev != first || >- gfs2_ail1_empty_one(sdp, first_ai, 0))) >- break; >- > done = 1; > list_for_each_entry_safe_reverse(ai, tmp, head, ai_list) { > if (ai->ai_sync_gen >= sync_gen) >@@ -208,7 +202,7 @@ static void gfs2_ail1_start(struct gfs2_ > gfs2_log_unlock(sdp); > } > >-int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) >+static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) > { > struct gfs2_ail *ai, *s; > int ret; >@@ -287,72 +281,57 @@ static void ail2_empty(struct gfs2_sbd * > * flush time, so we ensure that we have just enough free blocks at all > * times to avoid running out during a log flush. > * >+ * We no longer flush the log here, instead we wake up logd to do that >+ * for us. To avoid the thundering herd and to ensure that we deal fairly >+ * with queued waiters, we use an exclusive wait. This means that when we >+ * get woken with enough journal space to get our reservation, we need to >+ * wake the next waiter on the list. >+ * > * Returns: errno > */ > >-int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks, int wait) >+int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) > { >- unsigned int try = 0; > unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); >+ unsigned wanted = blks + reserved_blks; >+ DEFINE_WAIT(wait); >+ int did_wait = 0; >+ unsigned int free_blocks; > > if (gfs2_assert_warn(sdp, blks) || > gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) > return -EINVAL; >+retry: >+ free_blocks = atomic_read(&sdp->sd_log_blks_free); >+ if (unlikely(free_blocks <= wanted)) { >+ wake_up(&sdp->sd_logd_waitq); >+ do { >+ prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait, >+ TASK_UNINTERRUPTIBLE); >+ did_wait = 1; >+ if (atomic_read(&sdp->sd_log_blks_free) <= wanted) >+ io_schedule(); >+ free_blocks = atomic_read(&sdp->sd_log_blks_free); >+ } while(free_blocks <= wanted); >+ finish_wait(&sdp->sd_log_waitq, &wait); >+ } >+ if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, >+ free_blocks - blks) != free_blocks) >+ goto retry; >+ >+ /* >+ * If we waited, then so might others, wake them up _after_ we get >+ * our share of the log. >+ */ >+ if (unlikely(did_wait)) >+ wake_up(&sdp->sd_log_waitq); > >- mutex_lock(&sdp->sd_log_reserve_mutex); >- gfs2_log_lock(sdp); >- while(sdp->sd_log_blks_free <= (blks + reserved_blks)) { >- gfs2_log_unlock(sdp); >- if (!wait) { >- mutex_unlock(&sdp->sd_log_reserve_mutex); >- return -EBUSY; >- } >- gfs2_ail1_empty(sdp, 0); >- gfs2_log_flush(sdp, NULL); >- >- if (try++) >- gfs2_ail1_start(sdp, 0); >- gfs2_log_lock(sdp); >- } >- sdp->sd_log_blks_free -= blks; >- gfs2_log_unlock(sdp); >+ down_read(&sdp->sd_log_flush_lock); > >- if (wait){ >- mutex_unlock(&sdp->sd_log_reserve_mutex); >- down_read(&sdp->sd_log_flush_lock); >- } >- else { >- if (!down_read_trylock(&sdp->sd_log_flush_lock)) { >- gfs2_log_lock(sdp); >- sdp->sd_log_blks_free += blks; >- gfs2_log_unlock(sdp); >- mutex_unlock(&sdp->sd_log_reserve_mutex); >- return -EBUSY; >- } >- mutex_unlock(&sdp->sd_log_reserve_mutex); >- } > return 0; > } > > /** >- * gfs2_log_release - Release a given number of log blocks >- * @sdp: The GFS2 superblock >- * @blks: The number of blocks >- * >- */ >- >-void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) >-{ >- >- gfs2_log_lock(sdp); >- sdp->sd_log_blks_free += blks; >- gfs2_assert_withdraw(sdp, >- sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); >- gfs2_log_unlock(sdp); >- up_read(&sdp->sd_log_flush_lock); >-} >- >-/** > * log_bmap - Map a logical block number of the current journal to a disk > * block. > * @sdp: The GFS2 superblock >@@ -366,7 +345,7 @@ static u64 log_bmap(struct gfs2_sbd *sdp > > list_for_each_entry(je, &sdp->sd_jdesc->extent_list, extent_list) { > if (lbn >= je->lblock && lbn < je->lblock + je->blocks) >- return je->dblock + lbn; >+ return je->dblock + lbn - je->lblock; > } > > return -1; >@@ -531,7 +510,7 @@ static void gfs2_fake_write_endio(struct > { > struct buffer_head *real_bh = bh->b_private; > struct gfs2_bufdata *bd = bh_to_bufdata(real_bh); >- struct gfs2_sbd *sdp = GFS2_SB(real_bh->b_page->mapping->host); >+ struct gfs2_sbd *sdp = bd->bd_gl->gl_sbd; > > end_buffer_write_sync(bh, uptodate); > free_buffer_head(bh); >@@ -577,10 +556,9 @@ static void log_pull_tail(struct gfs2_sb > > ail2_empty(sdp, new_tail); > >- gfs2_log_lock(sdp); >- sdp->sd_log_blks_free += dist; >- gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); >- gfs2_log_unlock(sdp); >+ atomic_add(dist, &sdp->sd_log_blks_free); >+ gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= >+ sdp->sd_jdesc->jd_blocks); > > sdp->sd_log_tail = new_tail; > } >@@ -711,20 +689,16 @@ static void gfs2_ordered_wait(struct gfs > * > */ > >-void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) >+void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) > { > struct gfs2_ail *ai; > > down_write(&sdp->sd_log_flush_lock); > >- if (gl) { >- gfs2_log_lock(sdp); >- if (list_empty(&gl->gl_le.le_list)) { >- gfs2_log_unlock(sdp); >- up_write(&sdp->sd_log_flush_lock); >- return; >- } >- gfs2_log_unlock(sdp); >+ /* Log might have been flushed while we waited for the flush lock */ >+ if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) { >+ up_write(&sdp->sd_log_flush_lock); >+ return; > } > > ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL); >@@ -756,7 +730,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp > log_flush_commit(sdp); > else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ > gfs2_log_lock(sdp); >- sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */ >+ atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ > gfs2_log_unlock(sdp); > log_write_header(sdp, 0, PULL); > } >@@ -796,12 +770,12 @@ static void log_refund(struct gfs2_sbd * > sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; > gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); > reserved = calc_reserved(sdp); >- old = sdp->sd_log_blks_free; >- sdp->sd_log_blks_free += tr->tr_reserved - >- (reserved - sdp->sd_log_blks_reserved); >+ old = atomic_read(&sdp->sd_log_blks_free); >+ atomic_add(tr->tr_reserved - (reserved - sdp->sd_log_blks_reserved), >+ &sdp->sd_log_blks_free); > >- gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); >- gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= >+ gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) >= old); >+ gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= > sdp->sd_jdesc->jd_blocks); > > sdp->sd_log_blks_reserved = reserved; >@@ -814,6 +788,13 @@ static void log_refund(struct gfs2_sbd * > * @sdp: the filesystem > * @tr: the transaction > * >+ * We wake up gfs2_logd if the number of pinned blocks exceed thresh1 >+ * or the total number of used blocks (pinned blocks plus AIL blocks) >+ * is greater than thresh2. >+ * >+ * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of >+ * journal size. >+ * > * Returns: errno > */ > >@@ -825,10 +806,10 @@ void gfs2_log_commit(struct gfs2_sbd *sd > sdp->sd_vfs->s_dirt = 1; > up_read(&sdp->sd_log_flush_lock); > >- gfs2_log_lock(sdp); >- if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) >- wake_up_process(sdp->sd_logd_process); >- gfs2_log_unlock(sdp); >+ 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)) > >+ atomic_read(&sdp->sd_log_thresh2))) >+ wake_up(&sdp->sd_logd_waitq); > } > > /** >@@ -842,7 +823,6 @@ void gfs2_log_shutdown(struct gfs2_sbd * > down_write(&sdp->sd_log_flush_lock); > > gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); >- gfs2_assert_withdraw(sdp, !sdp->sd_log_num_gl); > gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf); > gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); > gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); >@@ -855,7 +835,7 @@ void gfs2_log_shutdown(struct gfs2_sbd * > log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, > (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); > >- gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); >+ gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); > gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); > gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); > >@@ -876,10 +856,73 @@ void gfs2_meta_syncfs(struct gfs2_sbd *s > { > gfs2_log_flush(sdp, NULL); > for (;;) { >- gfs2_ail1_start(sdp, DIO_ALL); >+ gfs2_ail1_start(sdp); > if (gfs2_ail1_empty(sdp, DIO_ALL)) > break; > msleep(10); > } > } > >+static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) >+{ >+ return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); >+} >+ >+static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) >+{ >+ unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); >+ return used_blocks >= atomic_read(&sdp->sd_log_thresh2); >+} >+ >+/** >+ * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks >+ * @sdp: Pointer to GFS2 superblock >+ * >+ * Also, periodically check to make sure that we're using the most recent >+ * journal index. >+ */ >+ >+int gfs2_logd(void *data) >+{ >+ struct gfs2_sbd *sdp = data; >+ unsigned long t = 1; >+ DEFINE_WAIT(wait); >+ unsigned preflush; >+ >+ while (!kthread_should_stop()) { >+ >+ preflush = atomic_read(&sdp->sd_log_pinned); >+ if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { >+ gfs2_ail1_empty(sdp, DIO_ALL); >+ gfs2_log_flush(sdp, NULL); >+ gfs2_ail1_empty(sdp, DIO_ALL); >+ } >+ >+ if (gfs2_ail_flush_reqd(sdp)) { >+ gfs2_ail1_start(sdp); >+ io_schedule(); >+ gfs2_ail1_empty(sdp, 0); >+ gfs2_log_flush(sdp, NULL); >+ gfs2_ail1_empty(sdp, DIO_ALL); >+ } >+ >+ wake_up(&sdp->sd_log_waitq); >+ t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; >+ if (freezing(current)) >+ refrigerator(); >+ >+ do { >+ prepare_to_wait(&sdp->sd_logd_waitq, &wait, >+ TASK_UNINTERRUPTIBLE); >+ if (!gfs2_ail_flush_reqd(sdp) && >+ !gfs2_jrnl_flush_reqd(sdp) && >+ !kthread_should_stop()) >+ t = schedule_timeout(t); >+ } while(t && !gfs2_ail_flush_reqd(sdp) && >+ !gfs2_jrnl_flush_reqd(sdp) && >+ !kthread_should_stop()); >+ finish_wait(&sdp->sd_logd_waitq, &wait); >+ } >+ >+ return 0; >+} >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/log.h gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/log.h >--- gfs2-kmod-1.53-4.3.3/gfs2/log.h 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/log.h 2007-12-17 11:25:14.000000000 -0600 >@@ -48,20 +48,24 @@ static inline void gfs2_log_pointers_ini > unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, > unsigned int ssize); > >-int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); >- >-int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks, int wait); >-void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks); >+int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); > void gfs2_log_incr_head(struct gfs2_sbd *sdp); > > struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); > struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, > struct buffer_head *real); >-void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); >+void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); >+static inline void gfs2_log_flush(struct gfs2_sbd *sbd, struct gfs2_glock *gl) >+{ >+ if (!gl || test_bit(GLF_LFLUSH, &gl->gl_flags)) >+ __gfs2_log_flush(sbd, gl); >+} >+ > void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); > void gfs2_remove_from_ail(struct gfs2_bufdata *bd); > > void gfs2_log_shutdown(struct gfs2_sbd *sdp); > void gfs2_meta_syncfs(struct gfs2_sbd *sdp); >+int gfs2_logd(void *data); > > #endif /* __LOG_DOT_H__ */ >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/lops.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/lops.c >--- gfs2-kmod-1.53-4.3.3/gfs2/lops.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/lops.c 2007-12-17 11:00:19.000000000 -0600 >@@ -52,6 +52,7 @@ static void gfs2_pin(struct gfs2_sbd *sd > if (bd->bd_ail) > list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list); > get_bh(bh); >+ atomic_inc(&sdp->sd_log_pinned); > } > > /** >@@ -91,8 +92,10 @@ static void gfs2_unpin(struct gfs2_sbd * > } > bd->bd_ail = ai; > list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); >+ clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); > gfs2_log_unlock(sdp); > unlock_buffer(bh); >+ atomic_dec(&sdp->sd_log_pinned); > } > > >@@ -128,48 +131,6 @@ static struct buffer_head *gfs2_get_log_ > return bh; > } > >-static void __glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) >-{ >- struct gfs2_glock *gl; >- struct gfs2_trans *tr = current->journal_info; >- >- tr->tr_touched = 1; >- >- gl = container_of(le, struct gfs2_glock, gl_le); >- if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl))) >- return; >- >- if (!list_empty(&le->le_list)) >- return; >- >- gfs2_glock_hold(gl); >- sdp->sd_log_num_gl++; >- list_add(&le->le_list, &sdp->sd_log_le_gl); >-} >- >-static void glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) >-{ >- gfs2_log_lock(sdp); >- __glock_lo_add(sdp, le); >- gfs2_log_unlock(sdp); >-} >- >-static void glock_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) >-{ >- struct list_head *head = &sdp->sd_log_le_gl; >- struct gfs2_glock *gl; >- >- while (!list_empty(head)) { >- gl = list_entry(head->next, struct gfs2_glock, gl_le.le_list); >- list_del_init(&gl->gl_le.le_list); >- sdp->sd_log_num_gl--; >- >- gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl)); >- gfs2_glock_put(gl); >- } >- gfs2_assert_warn(sdp, !sdp->sd_log_num_gl); >-} >- > static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) > { > struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); >@@ -185,7 +146,7 @@ static void buf_lo_add(struct gfs2_sbd * > list_add(&bd->bd_list_tr, &tr->tr_list_buf); > if (!list_empty(&le->le_list)) > goto out; >- __glock_lo_add(sdp, &bd->bd_gl->gl_le); >+ set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); > gfs2_meta_check(sdp, bd->bd_bh); > gfs2_pin(sdp, bd->bd_bh); > sdp->sd_log_num_buf++; >@@ -564,8 +525,7 @@ static void databuf_lo_add(struct gfs2_s > if (!list_empty(&le->le_list)) > goto out; > >- if (tr) >- __glock_lo_add(sdp, &bd->bd_gl->gl_le); >+ set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); > if (gfs2_is_jdata(ip)) { > gfs2_pin(sdp, bd->bd_bh); > tr->tr_num_databuf_new++; >@@ -764,12 +724,6 @@ static void databuf_lo_after_commit(stru > } > > >-const struct gfs2_log_operations gfs2_glock_lops = { >- .lo_add = glock_lo_add, >- .lo_after_commit = glock_lo_after_commit, >- .lo_name = "glock", >-}; >- > const struct gfs2_log_operations gfs2_buf_lops = { > .lo_add = buf_lo_add, > .lo_incore_commit = buf_lo_incore_commit, >@@ -807,7 +761,6 @@ const struct gfs2_log_operations gfs2_da > }; > > const struct gfs2_log_operations *gfs2_log_ops[] = { >- &gfs2_glock_lops, > &gfs2_databuf_lops, > &gfs2_buf_lops, > &gfs2_rg_lops, >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/meta_io.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/meta_io.c >--- gfs2-kmod-1.53-4.3.3/gfs2/meta_io.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/meta_io.c 2007-12-17 11:27:52.000000000 -0600 >@@ -241,6 +241,7 @@ void gfs2_remove_from_journal(struct buf > struct gfs2_sbd *sdp = GFS2_SB(bh->b_page->mapping->host); > struct gfs2_bufdata *bd = bh_to_bufdata(bh); > if (test_clear_buffer_pinned(bh)) { >+ atomic_dec(&sdp->sd_log_pinned); > list_del_init(&bd->bd_le.le_list); > if (meta) { > gfs2_assert_warn(sdp, sdp->sd_log_num_buf); >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/ops_fstype.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/ops_fstype.c >--- gfs2-kmod-1.53-4.3.3/gfs2/ops_fstype.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/ops_fstype.c 2007-12-17 12:20:41.000000000 -0600 >@@ -78,15 +78,15 @@ static struct gfs2_sbd *init_sbd(struct > mutex_init(&sdp->sd_quota_mutex); > > spin_lock_init(&sdp->sd_log_lock); >- >- INIT_LIST_HEAD(&sdp->sd_log_le_gl); >+ atomic_set(&sdp->sd_log_pinned, 0); > INIT_LIST_HEAD(&sdp->sd_log_le_buf); > INIT_LIST_HEAD(&sdp->sd_log_le_revoke); > INIT_LIST_HEAD(&sdp->sd_log_le_rg); > INIT_LIST_HEAD(&sdp->sd_log_le_databuf); > INIT_LIST_HEAD(&sdp->sd_log_le_ordered); > >- mutex_init(&sdp->sd_log_reserve_mutex); >+ init_waitqueue_head(&sdp->sd_log_waitq); >+ init_waitqueue_head(&sdp->sd_logd_waitq); > INIT_LIST_HEAD(&sdp->sd_ail1_list); > INIT_LIST_HEAD(&sdp->sd_ail2_list); > >@@ -306,6 +306,7 @@ static int init_sb(struct gfs2_sbd *sdp, > if (!sb->s_root) { > fs_err(sdp, "can't get root dentry\n"); > error = -ENOMEM; >+ iput(sdp->sd_meta); > iput(inode); > } > sb->s_root->d_op = &gfs2_dops; >@@ -413,7 +414,9 @@ static int init_journal(struct gfs2_sbd > > if (sdp->sd_args.ar_spectator) { > sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0); >- sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks; >+ atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); >+ atomic_set(&sdp->sd_log_thresh1, 2*sdp->sd_jdesc->jd_blocks/5); >+ atomic_set(&sdp->sd_log_thresh2, 4*sdp->sd_jdesc->jd_blocks/5); > } else { > if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) { > fs_err(sdp, "can't mount journal #%u\n", >@@ -450,7 +453,9 @@ static int init_journal(struct gfs2_sbd > sdp->sd_jdesc->jd_jid, error); > goto fail_jinode_gh; > } >- sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks; >+ atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); >+ atomic_set(&sdp->sd_log_thresh1, 2*sdp->sd_jdesc->jd_blocks/5); >+ atomic_set(&sdp->sd_log_thresh2, 4*sdp->sd_jdesc->jd_blocks/5); > > /* Map the extents for this journal's blocks */ > map_journal_extents(sdp); >@@ -685,9 +690,6 @@ static int init_threads(struct gfs2_sbd > if (undo) > goto fail_quotad; > >- sdp->sd_log_flush_time = jiffies; >- sdp->sd_jindex_refresh_time = jiffies; >- > p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); > error = IS_ERR(p); > if (error) { >@@ -864,7 +866,6 @@ static int fill_super_meta(struct super_ > if (!new->s_root) { > fs_err(sdp, "can't get root dentry\n"); > error = -ENOMEM; >- iput(sdp->sd_meta); > iput(inode); > } else > new->s_root->d_op = &gfs2_dops; >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/ops_super.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/ops_super.c >--- gfs2-kmod-1.53-4.3.3/gfs2/ops_super.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/ops_super.c 2007-12-14 14:23:48.000000000 -0600 >@@ -108,7 +108,6 @@ static void gfs2_put_super(struct super_ > iput(sdp->sd_statfs_inode); > iput(sdp->sd_rindex); > iput(sdp->sd_quota_inode); >- iput(sdp->sd_meta); > > gfs2_glock_put(sdp->sd_rename_gl); > gfs2_glock_put(sdp->sd_trans_gl); >@@ -129,6 +128,8 @@ static void gfs2_put_super(struct super_ > gfs2_jindex_free(sdp); > /* Take apart glock structures and buffer lists */ > gfs2_gl_hash_clear(sdp, WAIT); >+ >+ iput(sdp->sd_meta); > /* Unmount the locking protocol */ > gfs2_lm_unmount(sdp); > >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/super.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/super.c >--- gfs2-kmod-1.53-4.3.3/gfs2/super.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/super.c 2007-12-17 12:24:43.000000000 -0600 >@@ -51,15 +51,9 @@ void gfs2_tune_init(struct gfs2_tune *gt > { > spin_lock_init(>->gt_spin); > >- gt->gt_ilimit = 100; >- gt->gt_ilimit_tries = 3; >- gt->gt_ilimit_min = 1; > gt->gt_demote_secs = 300; >- gt->gt_incore_log_blocks = 1024; >- gt->gt_log_flush_secs = 60; >- gt->gt_jindex_refresh_secs = 60; > gt->gt_recoverd_secs = 60; >- gt->gt_logd_secs = 1; >+ gt->gt_logd_secs = 30; > gt->gt_quotad_secs = 5; > gt->gt_quota_simul_sync = 64; > gt->gt_quota_warn_period = 10; >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/sys.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/sys.c >--- gfs2-kmod-1.53-4.3.3/gfs2/sys.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/sys.c 2007-12-17 11:44:37.000000000 -0600 >@@ -428,9 +428,6 @@ static ssize_t name##_store(struct gfs2_ > TUNE_ATTR_2(name, name##_store) > > TUNE_ATTR(demote_secs, 0); >-TUNE_ATTR(incore_log_blocks, 0); >-TUNE_ATTR(log_flush_secs, 0); >-TUNE_ATTR(jindex_refresh_secs, 0); > TUNE_ATTR(quota_warn_period, 0); > TUNE_ATTR(quota_quantum, 0); > TUNE_ATTR(atime_quantum, 0); >@@ -451,9 +448,6 @@ TUNE_ATTR_3(quota_scale, quota_scale_sho > > static struct attribute *tune_attrs[] = { > &tune_attr_demote_secs.attr, >- &tune_attr_incore_log_blocks.attr, >- &tune_attr_log_flush_secs.attr, >- &tune_attr_jindex_refresh_secs.attr, > &tune_attr_quota_warn_period.attr, > &tune_attr_quota_quantum.attr, > &tune_attr_atime_quantum.attr, >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/trans.c gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/trans.c >--- gfs2-kmod-1.53-4.3.3/gfs2/trans.c 2007-12-13 08:52:26.000000000 -0600 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/trans.c 2007-12-17 12:25:35.000000000 -0600 >@@ -61,7 +61,7 @@ int gfs2_do_trans_begin(struct gfs2_sbd > goto fail_gunlock; > } > >- error = gfs2_log_reserve(sdp, tr->tr_reserved, wait); >+ error = gfs2_log_reserve(sdp, tr->tr_reserved); > if (error) > goto fail_gunlock; > >@@ -79,6 +79,22 @@ fail_holder_uninit: > return error; > } > >+/** >+ * gfs2_log_release - Release a given number of log blocks >+ * @sdp: The GFS2 superblock >+ * @blks: The number of blocks >+ * >+ */ >+ >+static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) >+{ >+ >+ atomic_add(blks, &sdp->sd_log_blks_free); >+ gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= >+ sdp->sd_jdesc->jd_blocks); >+ up_read(&sdp->sd_log_flush_lock); >+} >+ > void gfs2_trans_end(struct gfs2_sbd *sdp) > { > struct gfs2_trans *tr = current->journal_info; >@@ -114,11 +130,6 @@ void gfs2_trans_end(struct gfs2_sbd *sdp > gfs2_log_flush(sdp, NULL); > } > >-void gfs2_trans_add_gl(struct gfs2_glock *gl) >-{ >- lops_add(gl->gl_sbd, &gl->gl_le); >-} >- > /** > * gfs2_trans_add_bh - Add a buffer head into the journal > * @gl: the glock the buffer belongs to >diff -pur gfs2-kmod-1.53-4.3.3/gfs2/trans.h gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/trans.h >--- gfs2-kmod-1.53-4.3.3/gfs2/trans.h 2007-09-25 16:37:23.000000000 -0500 >+++ gfs2-kmod-1.53-4.3.3.bobpatched1217/gfs2/trans.h 2007-12-13 11:30:37.000000000 -0600 >@@ -30,7 +30,6 @@ int gfs2_do_trans_begin(struct gfs2_sbd > > void gfs2_trans_end(struct gfs2_sbd *sdp); > >-void gfs2_trans_add_gl(struct gfs2_glock *gl); > void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta); > void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); > void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 423381
:
287721
|
289381
|
289809
|
289823