diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/incore.h | 10 | ||||
-rw-r--r-- | fs/gfs2/log.c | 157 | ||||
-rw-r--r-- | fs/gfs2/log.h | 1 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 2 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 17 | ||||
-rw-r--r-- | fs/gfs2/super.c | 8 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 4 | ||||
-rw-r--r-- | fs/gfs2/trans.c | 18 |
9 files changed, 126 insertions, 92 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 3aac46f6853e..08dd65745473 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -439,9 +439,6 @@ struct gfs2_args { | |||
439 | struct gfs2_tune { | 439 | struct gfs2_tune { |
440 | spinlock_t gt_spin; | 440 | spinlock_t gt_spin; |
441 | 441 | ||
442 | unsigned int gt_incore_log_blocks; | ||
443 | unsigned int gt_log_flush_secs; | ||
444 | |||
445 | unsigned int gt_logd_secs; | 442 | unsigned int gt_logd_secs; |
446 | 443 | ||
447 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ | 444 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ |
@@ -618,6 +615,7 @@ struct gfs2_sbd { | |||
618 | unsigned int sd_log_commited_databuf; | 615 | unsigned int sd_log_commited_databuf; |
619 | int sd_log_commited_revoke; | 616 | int sd_log_commited_revoke; |
620 | 617 | ||
618 | atomic_t sd_log_pinned; | ||
621 | unsigned int sd_log_num_buf; | 619 | unsigned int sd_log_num_buf; |
622 | unsigned int sd_log_num_revoke; | 620 | unsigned int sd_log_num_revoke; |
623 | unsigned int sd_log_num_rg; | 621 | unsigned int sd_log_num_rg; |
@@ -629,15 +627,17 @@ struct gfs2_sbd { | |||
629 | struct list_head sd_log_le_databuf; | 627 | struct list_head sd_log_le_databuf; |
630 | struct list_head sd_log_le_ordered; | 628 | struct list_head sd_log_le_ordered; |
631 | 629 | ||
630 | atomic_t sd_log_thresh1; | ||
631 | atomic_t sd_log_thresh2; | ||
632 | atomic_t sd_log_blks_free; | 632 | atomic_t sd_log_blks_free; |
633 | struct mutex sd_log_reserve_mutex; | 633 | wait_queue_head_t sd_log_waitq; |
634 | wait_queue_head_t sd_logd_waitq; | ||
634 | 635 | ||
635 | u64 sd_log_sequence; | 636 | u64 sd_log_sequence; |
636 | unsigned int sd_log_head; | 637 | unsigned int sd_log_head; |
637 | unsigned int sd_log_tail; | 638 | unsigned int sd_log_tail; |
638 | int sd_log_idle; | 639 | int sd_log_idle; |
639 | 640 | ||
640 | unsigned long sd_log_flush_time; | ||
641 | struct rw_semaphore sd_log_flush_lock; | 641 | struct rw_semaphore sd_log_flush_lock; |
642 | atomic_t sd_log_in_flight; | 642 | atomic_t sd_log_in_flight; |
643 | wait_queue_head_t sd_log_flush_wait; | 643 | wait_queue_head_t sd_log_flush_wait; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index e5bf4b59d46e..d5959df6deb2 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -168,12 +168,11 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl | |||
168 | return list_empty(&ai->ai_ail1_list); | 168 | return list_empty(&ai->ai_ail1_list); |
169 | } | 169 | } |
170 | 170 | ||
171 | static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) | 171 | static void gfs2_ail1_start(struct gfs2_sbd *sdp) |
172 | { | 172 | { |
173 | struct list_head *head; | 173 | struct list_head *head; |
174 | u64 sync_gen; | 174 | u64 sync_gen; |
175 | struct list_head *first; | 175 | struct gfs2_ail *ai; |
176 | struct gfs2_ail *first_ai, *ai, *tmp; | ||
177 | int done = 0; | 176 | int done = 0; |
178 | 177 | ||
179 | gfs2_log_lock(sdp); | 178 | gfs2_log_lock(sdp); |
@@ -184,21 +183,9 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) | |||
184 | } | 183 | } |
185 | sync_gen = sdp->sd_ail_sync_gen++; | 184 | sync_gen = sdp->sd_ail_sync_gen++; |
186 | 185 | ||
187 | first = head->prev; | ||
188 | first_ai = list_entry(first, struct gfs2_ail, ai_list); | ||
189 | first_ai->ai_sync_gen = sync_gen; | ||
190 | gfs2_ail1_start_one(sdp, first_ai); /* This may drop log lock */ | ||
191 | |||
192 | if (flags & DIO_ALL) | ||
193 | first = NULL; | ||
194 | |||
195 | while(!done) { | 186 | while(!done) { |
196 | if (first && (head->prev != first || | ||
197 | gfs2_ail1_empty_one(sdp, first_ai, 0))) | ||
198 | break; | ||
199 | |||
200 | done = 1; | 187 | done = 1; |
201 | list_for_each_entry_safe_reverse(ai, tmp, head, ai_list) { | 188 | list_for_each_entry_reverse(ai, head, ai_list) { |
202 | if (ai->ai_sync_gen >= sync_gen) | 189 | if (ai->ai_sync_gen >= sync_gen) |
203 | continue; | 190 | continue; |
204 | ai->ai_sync_gen = sync_gen; | 191 | ai->ai_sync_gen = sync_gen; |
@@ -290,58 +277,57 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
290 | * flush time, so we ensure that we have just enough free blocks at all | 277 | * flush time, so we ensure that we have just enough free blocks at all |
291 | * times to avoid running out during a log flush. | 278 | * times to avoid running out during a log flush. |
292 | * | 279 | * |
280 | * We no longer flush the log here, instead we wake up logd to do that | ||
281 | * for us. To avoid the thundering herd and to ensure that we deal fairly | ||
282 | * with queued waiters, we use an exclusive wait. This means that when we | ||
283 | * get woken with enough journal space to get our reservation, we need to | ||
284 | * wake the next waiter on the list. | ||
285 | * | ||
293 | * Returns: errno | 286 | * Returns: errno |
294 | */ | 287 | */ |
295 | 288 | ||
296 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | 289 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) |
297 | { | 290 | { |
298 | unsigned int try = 0; | ||
299 | unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); | 291 | unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); |
292 | unsigned wanted = blks + reserved_blks; | ||
293 | DEFINE_WAIT(wait); | ||
294 | int did_wait = 0; | ||
295 | unsigned int free_blocks; | ||
300 | 296 | ||
301 | if (gfs2_assert_warn(sdp, blks) || | 297 | if (gfs2_assert_warn(sdp, blks) || |
302 | gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) | 298 | gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) |
303 | return -EINVAL; | 299 | return -EINVAL; |
304 | 300 | retry: | |
305 | mutex_lock(&sdp->sd_log_reserve_mutex); | 301 | free_blocks = atomic_read(&sdp->sd_log_blks_free); |
306 | gfs2_log_lock(sdp); | 302 | if (unlikely(free_blocks <= wanted)) { |
307 | while(atomic_read(&sdp->sd_log_blks_free) <= (blks + reserved_blks)) { | 303 | do { |
308 | gfs2_log_unlock(sdp); | 304 | prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait, |
309 | gfs2_ail1_empty(sdp, 0); | 305 | TASK_UNINTERRUPTIBLE); |
310 | gfs2_log_flush(sdp, NULL); | 306 | wake_up(&sdp->sd_logd_waitq); |
311 | 307 | did_wait = 1; | |
312 | if (try++) | 308 | if (atomic_read(&sdp->sd_log_blks_free) <= wanted) |
313 | gfs2_ail1_start(sdp, 0); | 309 | io_schedule(); |
314 | gfs2_log_lock(sdp); | 310 | free_blocks = atomic_read(&sdp->sd_log_blks_free); |
311 | } while(free_blocks <= wanted); | ||
312 | finish_wait(&sdp->sd_log_waitq, &wait); | ||
315 | } | 313 | } |
316 | atomic_sub(blks, &sdp->sd_log_blks_free); | 314 | if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, |
315 | free_blocks - blks) != free_blocks) | ||
316 | goto retry; | ||
317 | trace_gfs2_log_blocks(sdp, -blks); | 317 | trace_gfs2_log_blocks(sdp, -blks); |
318 | gfs2_log_unlock(sdp); | 318 | |
319 | mutex_unlock(&sdp->sd_log_reserve_mutex); | 319 | /* |
320 | * If we waited, then so might others, wake them up _after_ we get | ||
321 | * our share of the log. | ||
322 | */ | ||
323 | if (unlikely(did_wait)) | ||
324 | wake_up(&sdp->sd_log_waitq); | ||
320 | 325 | ||
321 | down_read(&sdp->sd_log_flush_lock); | 326 | down_read(&sdp->sd_log_flush_lock); |
322 | 327 | ||
323 | return 0; | 328 | return 0; |
324 | } | 329 | } |
325 | 330 | ||
326 | /** | ||
327 | * gfs2_log_release - Release a given number of log blocks | ||
328 | * @sdp: The GFS2 superblock | ||
329 | * @blks: The number of blocks | ||
330 | * | ||
331 | */ | ||
332 | |||
333 | void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) | ||
334 | { | ||
335 | |||
336 | gfs2_log_lock(sdp); | ||
337 | atomic_add(blks, &sdp->sd_log_blks_free); | ||
338 | trace_gfs2_log_blocks(sdp, blks); | ||
339 | gfs2_assert_withdraw(sdp, | ||
340 | atomic_read(&sdp->sd_log_blks_free) <= sdp->sd_jdesc->jd_blocks); | ||
341 | gfs2_log_unlock(sdp); | ||
342 | up_read(&sdp->sd_log_flush_lock); | ||
343 | } | ||
344 | |||
345 | static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) | 331 | static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) |
346 | { | 332 | { |
347 | struct gfs2_journal_extent *je; | 333 | struct gfs2_journal_extent *je; |
@@ -559,11 +545,10 @@ static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
559 | 545 | ||
560 | ail2_empty(sdp, new_tail); | 546 | ail2_empty(sdp, new_tail); |
561 | 547 | ||
562 | gfs2_log_lock(sdp); | ||
563 | atomic_add(dist, &sdp->sd_log_blks_free); | 548 | atomic_add(dist, &sdp->sd_log_blks_free); |
564 | trace_gfs2_log_blocks(sdp, dist); | 549 | trace_gfs2_log_blocks(sdp, dist); |
565 | gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= sdp->sd_jdesc->jd_blocks); | 550 | gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= |
566 | gfs2_log_unlock(sdp); | 551 | sdp->sd_jdesc->jd_blocks); |
567 | 552 | ||
568 | sdp->sd_log_tail = new_tail; | 553 | sdp->sd_log_tail = new_tail; |
569 | } | 554 | } |
@@ -822,6 +807,13 @@ static void buf_lo_incore_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
822 | * @sdp: the filesystem | 807 | * @sdp: the filesystem |
823 | * @tr: the transaction | 808 | * @tr: the transaction |
824 | * | 809 | * |
810 | * We wake up gfs2_logd if the number of pinned blocks exceed thresh1 | ||
811 | * or the total number of used blocks (pinned blocks plus AIL blocks) | ||
812 | * is greater than thresh2. | ||
813 | * | ||
814 | * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of | ||
815 | * journal size. | ||
816 | * | ||
825 | * Returns: errno | 817 | * Returns: errno |
826 | */ | 818 | */ |
827 | 819 | ||
@@ -832,10 +824,10 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
832 | 824 | ||
833 | up_read(&sdp->sd_log_flush_lock); | 825 | up_read(&sdp->sd_log_flush_lock); |
834 | 826 | ||
835 | gfs2_log_lock(sdp); | 827 | if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) || |
836 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) | 828 | ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) > |
837 | wake_up_process(sdp->sd_logd_process); | 829 | atomic_read(&sdp->sd_log_thresh2))) |
838 | gfs2_log_unlock(sdp); | 830 | wake_up(&sdp->sd_logd_waitq); |
839 | } | 831 | } |
840 | 832 | ||
841 | /** | 833 | /** |
@@ -882,13 +874,23 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | |||
882 | { | 874 | { |
883 | gfs2_log_flush(sdp, NULL); | 875 | gfs2_log_flush(sdp, NULL); |
884 | for (;;) { | 876 | for (;;) { |
885 | gfs2_ail1_start(sdp, DIO_ALL); | 877 | gfs2_ail1_start(sdp); |
886 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | 878 | if (gfs2_ail1_empty(sdp, DIO_ALL)) |
887 | break; | 879 | break; |
888 | msleep(10); | 880 | msleep(10); |
889 | } | 881 | } |
890 | } | 882 | } |
891 | 883 | ||
884 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) | ||
885 | { | ||
886 | return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); | ||
887 | } | ||
888 | |||
889 | static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) | ||
890 | { | ||
891 | unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); | ||
892 | return used_blocks >= atomic_read(&sdp->sd_log_thresh2); | ||
893 | } | ||
892 | 894 | ||
893 | /** | 895 | /** |
894 | * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks | 896 | * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks |
@@ -901,28 +903,43 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | |||
901 | int gfs2_logd(void *data) | 903 | int gfs2_logd(void *data) |
902 | { | 904 | { |
903 | struct gfs2_sbd *sdp = data; | 905 | struct gfs2_sbd *sdp = data; |
904 | unsigned long t; | 906 | unsigned long t = 1; |
905 | int need_flush; | 907 | DEFINE_WAIT(wait); |
908 | unsigned preflush; | ||
906 | 909 | ||
907 | while (!kthread_should_stop()) { | 910 | while (!kthread_should_stop()) { |
908 | /* Advance the log tail */ | ||
909 | 911 | ||
910 | t = sdp->sd_log_flush_time + | 912 | preflush = atomic_read(&sdp->sd_log_pinned); |
911 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; | 913 | if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { |
914 | gfs2_ail1_empty(sdp, DIO_ALL); | ||
915 | gfs2_log_flush(sdp, NULL); | ||
916 | gfs2_ail1_empty(sdp, DIO_ALL); | ||
917 | } | ||
912 | 918 | ||
913 | gfs2_ail1_empty(sdp, DIO_ALL); | 919 | if (gfs2_ail_flush_reqd(sdp)) { |
914 | gfs2_log_lock(sdp); | 920 | gfs2_ail1_start(sdp); |
915 | need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); | 921 | io_schedule(); |
916 | gfs2_log_unlock(sdp); | 922 | gfs2_ail1_empty(sdp, 0); |
917 | if (need_flush || time_after_eq(jiffies, t)) { | ||
918 | gfs2_log_flush(sdp, NULL); | 923 | gfs2_log_flush(sdp, NULL); |
919 | sdp->sd_log_flush_time = jiffies; | 924 | gfs2_ail1_empty(sdp, DIO_ALL); |
920 | } | 925 | } |
921 | 926 | ||
927 | wake_up(&sdp->sd_log_waitq); | ||
922 | t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; | 928 | t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; |
923 | if (freezing(current)) | 929 | if (freezing(current)) |
924 | refrigerator(); | 930 | refrigerator(); |
925 | schedule_timeout_interruptible(t); | 931 | |
932 | do { | ||
933 | prepare_to_wait(&sdp->sd_logd_waitq, &wait, | ||
934 | TASK_UNINTERRUPTIBLE); | ||
935 | if (!gfs2_ail_flush_reqd(sdp) && | ||
936 | !gfs2_jrnl_flush_reqd(sdp) && | ||
937 | !kthread_should_stop()) | ||
938 | t = schedule_timeout(t); | ||
939 | } while(t && !gfs2_ail_flush_reqd(sdp) && | ||
940 | !gfs2_jrnl_flush_reqd(sdp) && | ||
941 | !kthread_should_stop()); | ||
942 | finish_wait(&sdp->sd_logd_waitq, &wait); | ||
926 | } | 943 | } |
927 | 944 | ||
928 | return 0; | 945 | return 0; |
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 7c64510ccfd2..eb570b4ad443 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -51,7 +51,6 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | |||
51 | unsigned int ssize); | 51 | unsigned int ssize); |
52 | 52 | ||
53 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); | 53 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); |
54 | void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks); | ||
55 | void gfs2_log_incr_head(struct gfs2_sbd *sdp); | 54 | void gfs2_log_incr_head(struct gfs2_sbd *sdp); |
56 | 55 | ||
57 | struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); | 56 | struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index adc260fbea90..bf33f822058d 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -54,6 +54,7 @@ static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
54 | if (bd->bd_ail) | 54 | if (bd->bd_ail) |
55 | list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list); | 55 | list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list); |
56 | get_bh(bh); | 56 | get_bh(bh); |
57 | atomic_inc(&sdp->sd_log_pinned); | ||
57 | trace_gfs2_pin(bd, 1); | 58 | trace_gfs2_pin(bd, 1); |
58 | } | 59 | } |
59 | 60 | ||
@@ -94,6 +95,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
94 | trace_gfs2_pin(bd, 0); | 95 | trace_gfs2_pin(bd, 0); |
95 | gfs2_log_unlock(sdp); | 96 | gfs2_log_unlock(sdp); |
96 | unlock_buffer(bh); | 97 | unlock_buffer(bh); |
98 | atomic_dec(&sdp->sd_log_pinned); | ||
97 | } | 99 | } |
98 | 100 | ||
99 | 101 | ||
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 0bb12c80937a..abafda1f637b 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -313,6 +313,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int | |||
313 | struct gfs2_bufdata *bd = bh->b_private; | 313 | struct gfs2_bufdata *bd = bh->b_private; |
314 | 314 | ||
315 | if (test_clear_buffer_pinned(bh)) { | 315 | if (test_clear_buffer_pinned(bh)) { |
316 | atomic_dec(&sdp->sd_log_pinned); | ||
316 | list_del_init(&bd->bd_le.le_list); | 317 | list_del_init(&bd->bd_le.le_list); |
317 | if (meta) { | 318 | if (meta) { |
318 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); | 319 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index dc35f3470271..3593b3a7290e 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -57,8 +57,6 @@ static void gfs2_tune_init(struct gfs2_tune *gt) | |||
57 | { | 57 | { |
58 | spin_lock_init(>->gt_spin); | 58 | spin_lock_init(>->gt_spin); |
59 | 59 | ||
60 | gt->gt_incore_log_blocks = 1024; | ||
61 | gt->gt_logd_secs = 1; | ||
62 | gt->gt_quota_simul_sync = 64; | 60 | gt->gt_quota_simul_sync = 64; |
63 | gt->gt_quota_warn_period = 10; | 61 | gt->gt_quota_warn_period = 10; |
64 | gt->gt_quota_scale_num = 1; | 62 | gt->gt_quota_scale_num = 1; |
@@ -101,14 +99,15 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
101 | spin_lock_init(&sdp->sd_trunc_lock); | 99 | spin_lock_init(&sdp->sd_trunc_lock); |
102 | 100 | ||
103 | spin_lock_init(&sdp->sd_log_lock); | 101 | spin_lock_init(&sdp->sd_log_lock); |
104 | 102 | atomic_set(&sdp->sd_log_pinned, 0); | |
105 | INIT_LIST_HEAD(&sdp->sd_log_le_buf); | 103 | INIT_LIST_HEAD(&sdp->sd_log_le_buf); |
106 | INIT_LIST_HEAD(&sdp->sd_log_le_revoke); | 104 | INIT_LIST_HEAD(&sdp->sd_log_le_revoke); |
107 | INIT_LIST_HEAD(&sdp->sd_log_le_rg); | 105 | INIT_LIST_HEAD(&sdp->sd_log_le_rg); |
108 | INIT_LIST_HEAD(&sdp->sd_log_le_databuf); | 106 | INIT_LIST_HEAD(&sdp->sd_log_le_databuf); |
109 | INIT_LIST_HEAD(&sdp->sd_log_le_ordered); | 107 | INIT_LIST_HEAD(&sdp->sd_log_le_ordered); |
110 | 108 | ||
111 | mutex_init(&sdp->sd_log_reserve_mutex); | 109 | init_waitqueue_head(&sdp->sd_log_waitq); |
110 | init_waitqueue_head(&sdp->sd_logd_waitq); | ||
112 | INIT_LIST_HEAD(&sdp->sd_ail1_list); | 111 | INIT_LIST_HEAD(&sdp->sd_ail1_list); |
113 | INIT_LIST_HEAD(&sdp->sd_ail2_list); | 112 | INIT_LIST_HEAD(&sdp->sd_ail2_list); |
114 | 113 | ||
@@ -733,6 +732,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
733 | if (sdp->sd_args.ar_spectator) { | 732 | if (sdp->sd_args.ar_spectator) { |
734 | sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0); | 733 | sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0); |
735 | atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); | 734 | atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); |
735 | atomic_set(&sdp->sd_log_thresh1, 2*sdp->sd_jdesc->jd_blocks/5); | ||
736 | atomic_set(&sdp->sd_log_thresh2, 4*sdp->sd_jdesc->jd_blocks/5); | ||
736 | } else { | 737 | } else { |
737 | if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) { | 738 | if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) { |
738 | fs_err(sdp, "can't mount journal #%u\n", | 739 | fs_err(sdp, "can't mount journal #%u\n", |
@@ -770,6 +771,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
770 | goto fail_jinode_gh; | 771 | goto fail_jinode_gh; |
771 | } | 772 | } |
772 | atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); | 773 | atomic_set(&sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); |
774 | atomic_set(&sdp->sd_log_thresh1, 2*sdp->sd_jdesc->jd_blocks/5); | ||
775 | atomic_set(&sdp->sd_log_thresh2, 4*sdp->sd_jdesc->jd_blocks/5); | ||
773 | 776 | ||
774 | /* Map the extents for this journal's blocks */ | 777 | /* Map the extents for this journal's blocks */ |
775 | map_journal_extents(sdp); | 778 | map_journal_extents(sdp); |
@@ -951,8 +954,6 @@ static int init_threads(struct gfs2_sbd *sdp, int undo) | |||
951 | if (undo) | 954 | if (undo) |
952 | goto fail_quotad; | 955 | goto fail_quotad; |
953 | 956 | ||
954 | sdp->sd_log_flush_time = jiffies; | ||
955 | |||
956 | p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); | 957 | p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); |
957 | error = IS_ERR(p); | 958 | error = IS_ERR(p); |
958 | if (error) { | 959 | if (error) { |
@@ -1160,7 +1161,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent | |||
1160 | GFS2_BASIC_BLOCK_SHIFT; | 1161 | GFS2_BASIC_BLOCK_SHIFT; |
1161 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; | 1162 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; |
1162 | 1163 | ||
1163 | sdp->sd_tune.gt_log_flush_secs = sdp->sd_args.ar_commit; | 1164 | sdp->sd_tune.gt_logd_secs = sdp->sd_args.ar_commit; |
1164 | sdp->sd_tune.gt_quota_quantum = sdp->sd_args.ar_quota_quantum; | 1165 | sdp->sd_tune.gt_quota_quantum = sdp->sd_args.ar_quota_quantum; |
1165 | if (sdp->sd_args.ar_statfs_quantum) { | 1166 | if (sdp->sd_args.ar_statfs_quantum) { |
1166 | sdp->sd_tune.gt_statfs_slow = 0; | 1167 | sdp->sd_tune.gt_statfs_slow = 0; |
@@ -1323,7 +1324,7 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags, | |||
1323 | memset(&args, 0, sizeof(args)); | 1324 | memset(&args, 0, sizeof(args)); |
1324 | args.ar_quota = GFS2_QUOTA_DEFAULT; | 1325 | args.ar_quota = GFS2_QUOTA_DEFAULT; |
1325 | args.ar_data = GFS2_DATA_DEFAULT; | 1326 | args.ar_data = GFS2_DATA_DEFAULT; |
1326 | args.ar_commit = 60; | 1327 | args.ar_commit = 30; |
1327 | args.ar_statfs_quantum = 30; | 1328 | args.ar_statfs_quantum = 30; |
1328 | args.ar_quota_quantum = 60; | 1329 | args.ar_quota_quantum = 60; |
1329 | args.ar_errors = GFS2_ERRORS_DEFAULT; | 1330 | args.ar_errors = GFS2_ERRORS_DEFAULT; |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 50aac606b990..7a93e9ff7d3c 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -1113,7 +1113,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1113 | int error; | 1113 | int error; |
1114 | 1114 | ||
1115 | spin_lock(>->gt_spin); | 1115 | spin_lock(>->gt_spin); |
1116 | args.ar_commit = gt->gt_log_flush_secs; | 1116 | args.ar_commit = gt->gt_logd_secs; |
1117 | args.ar_quota_quantum = gt->gt_quota_quantum; | 1117 | args.ar_quota_quantum = gt->gt_quota_quantum; |
1118 | if (gt->gt_statfs_slow) | 1118 | if (gt->gt_statfs_slow) |
1119 | args.ar_statfs_quantum = 0; | 1119 | args.ar_statfs_quantum = 0; |
@@ -1160,7 +1160,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1160 | else | 1160 | else |
1161 | clear_bit(SDF_NOBARRIERS, &sdp->sd_flags); | 1161 | clear_bit(SDF_NOBARRIERS, &sdp->sd_flags); |
1162 | spin_lock(>->gt_spin); | 1162 | spin_lock(>->gt_spin); |
1163 | gt->gt_log_flush_secs = args.ar_commit; | 1163 | gt->gt_logd_secs = args.ar_commit; |
1164 | gt->gt_quota_quantum = args.ar_quota_quantum; | 1164 | gt->gt_quota_quantum = args.ar_quota_quantum; |
1165 | if (args.ar_statfs_quantum) { | 1165 | if (args.ar_statfs_quantum) { |
1166 | gt->gt_statfs_slow = 0; | 1166 | gt->gt_statfs_slow = 0; |
@@ -1305,8 +1305,8 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1305 | } | 1305 | } |
1306 | if (args->ar_discard) | 1306 | if (args->ar_discard) |
1307 | seq_printf(s, ",discard"); | 1307 | seq_printf(s, ",discard"); |
1308 | val = sdp->sd_tune.gt_log_flush_secs; | 1308 | val = sdp->sd_tune.gt_logd_secs; |
1309 | if (val != 60) | 1309 | if (val != 30) |
1310 | seq_printf(s, ",commit=%d", val); | 1310 | seq_printf(s, ",commit=%d", val); |
1311 | val = sdp->sd_tune.gt_statfs_quantum; | 1311 | val = sdp->sd_tune.gt_statfs_quantum; |
1312 | if (val != 30) | 1312 | if (val != 30) |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 419042f7f0b6..2ac845d9c46c 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -469,8 +469,6 @@ static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | |||
469 | } \ | 469 | } \ |
470 | TUNE_ATTR_2(name, name##_store) | 470 | TUNE_ATTR_2(name, name##_store) |
471 | 471 | ||
472 | TUNE_ATTR(incore_log_blocks, 0); | ||
473 | TUNE_ATTR(log_flush_secs, 0); | ||
474 | TUNE_ATTR(quota_warn_period, 0); | 472 | TUNE_ATTR(quota_warn_period, 0); |
475 | TUNE_ATTR(quota_quantum, 0); | 473 | TUNE_ATTR(quota_quantum, 0); |
476 | TUNE_ATTR(max_readahead, 0); | 474 | TUNE_ATTR(max_readahead, 0); |
@@ -482,8 +480,6 @@ TUNE_ATTR(statfs_quantum, 1); | |||
482 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 480 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
483 | 481 | ||
484 | static struct attribute *tune_attrs[] = { | 482 | static struct attribute *tune_attrs[] = { |
485 | &tune_attr_incore_log_blocks.attr, | ||
486 | &tune_attr_log_flush_secs.attr, | ||
487 | &tune_attr_quota_warn_period.attr, | 483 | &tune_attr_quota_warn_period.attr, |
488 | &tune_attr_quota_quantum.attr, | 484 | &tune_attr_quota_quantum.attr, |
489 | &tune_attr_max_readahead.attr, | 485 | &tune_attr_max_readahead.attr, |
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 4ef0e9fa3549..9ec73a854111 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "meta_io.h" | 23 | #include "meta_io.h" |
24 | #include "trans.h" | 24 | #include "trans.h" |
25 | #include "util.h" | 25 | #include "util.h" |
26 | #include "trace_gfs2.h" | ||
26 | 27 | ||
27 | int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | 28 | int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, |
28 | unsigned int revokes) | 29 | unsigned int revokes) |
@@ -75,6 +76,23 @@ fail_holder_uninit: | |||
75 | return error; | 76 | return error; |
76 | } | 77 | } |
77 | 78 | ||
79 | /** | ||
80 | * gfs2_log_release - Release a given number of log blocks | ||
81 | * @sdp: The GFS2 superblock | ||
82 | * @blks: The number of blocks | ||
83 | * | ||
84 | */ | ||
85 | |||
86 | static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) | ||
87 | { | ||
88 | |||
89 | atomic_add(blks, &sdp->sd_log_blks_free); | ||
90 | trace_gfs2_log_blocks(sdp, blks); | ||
91 | gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <= | ||
92 | sdp->sd_jdesc->jd_blocks); | ||
93 | up_read(&sdp->sd_log_flush_lock); | ||
94 | } | ||
95 | |||
78 | void gfs2_trans_end(struct gfs2_sbd *sdp) | 96 | void gfs2_trans_end(struct gfs2_sbd *sdp) |
79 | { | 97 | { |
80 | struct gfs2_trans *tr = current->journal_info; | 98 | struct gfs2_trans *tr = current->journal_info; |