aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/lops.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2012-04-16 04:40:00 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-04-24 11:44:35 -0400
commitdad30e9031c5927c30b402f73ac57ffbe09dc9ee (patch)
tree01384e81d04644da848477b0cb51182d18229b59 /fs/gfs2/lops.c
parente8c92ed769008cfc799497f0a34c8faf46243c4d (diff)
GFS2: Remove duplicate log code
The main part of this patch merges the two functions used to write metadata and data buffers to the log. Most of the code is common between the two functions, so this provides a nice clean up, and makes the code more readable. The gfs2_get_log_desc() function is also extended to take two more arguments, and thus avoid having to set the length and data1 fields of this strucuture as a separate operation. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/lops.c')
-rw-r--r--fs/gfs2/lops.c175
1 files changed, 59 insertions, 116 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 872d3e6ae05e..7882671bfe09 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -372,7 +372,8 @@ void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
372 gfs2_log_write(sdp, page, sb->s_blocksize, 0); 372 gfs2_log_write(sdp, page, sb->s_blocksize, 0);
373} 373}
374 374
375static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type) 375static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type,
376 u32 ld_length, u32 ld_data1)
376{ 377{
377 void *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); 378 void *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
378 struct gfs2_log_descriptor *ld = page_address(page); 379 struct gfs2_log_descriptor *ld = page_address(page);
@@ -381,8 +382,8 @@ static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
381 ld->ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD); 382 ld->ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD);
382 ld->ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD); 383 ld->ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD);
383 ld->ld_type = cpu_to_be32(ld_type); 384 ld->ld_type = cpu_to_be32(ld_type);
384 ld->ld_length = 0; 385 ld->ld_length = cpu_to_be32(ld_length);
385 ld->ld_data1 = 0; 386 ld->ld_data1 = cpu_to_be32(ld_data1);
386 ld->ld_data2 = 0; 387 ld->ld_data2 = 0;
387 return page; 388 return page;
388} 389}
@@ -418,39 +419,49 @@ out:
418 unlock_buffer(bd->bd_bh); 419 unlock_buffer(bd->bd_bh);
419} 420}
420 421
421static void buf_lo_before_commit(struct gfs2_sbd *sdp) 422static void gfs2_check_magic(struct buffer_head *bh)
423{
424 void *kaddr;
425 __be32 *ptr;
426
427 clear_buffer_escaped(bh);
428 kaddr = kmap_atomic(bh->b_page);
429 ptr = kaddr + bh_offset(bh);
430 if (*ptr == cpu_to_be32(GFS2_MAGIC))
431 set_buffer_escaped(bh);
432 kunmap_atomic(kaddr);
433}
434
435static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
436 unsigned int total, struct list_head *blist,
437 bool is_databuf)
422{ 438{
423 struct gfs2_log_descriptor *ld; 439 struct gfs2_log_descriptor *ld;
424 struct gfs2_bufdata *bd1 = NULL, *bd2; 440 struct gfs2_bufdata *bd1 = NULL, *bd2;
425 struct page *page; 441 struct page *page;
426 unsigned int total;
427 unsigned int limit;
428 unsigned int num; 442 unsigned int num;
429 unsigned n; 443 unsigned n;
430 __be64 *ptr; 444 __be64 *ptr;
431 445
432 limit = buf_limit(sdp);
433 /* for 4k blocks, limit = 503 */
434
435 gfs2_log_lock(sdp); 446 gfs2_log_lock(sdp);
436 total = sdp->sd_log_num_buf; 447 bd1 = bd2 = list_prepare_entry(bd1, blist, bd_le.le_list);
437 bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list);
438 while(total) { 448 while(total) {
439 num = total; 449 num = total;
440 if (total > limit) 450 if (total > limit)
441 num = limit; 451 num = limit;
442 gfs2_log_unlock(sdp); 452 gfs2_log_unlock(sdp);
443 page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA); 453 page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num);
444 ld = page_address(page); 454 ld = page_address(page);
445 gfs2_log_lock(sdp); 455 gfs2_log_lock(sdp);
446 ptr = (__be64 *)(ld + 1); 456 ptr = (__be64 *)(ld + 1);
447 ld->ld_length = cpu_to_be32(num + 1);
448 ld->ld_data1 = cpu_to_be32(num);
449 457
450 n = 0; 458 n = 0;
451 list_for_each_entry_continue(bd1, &sdp->sd_log_le_buf, 459 list_for_each_entry_continue(bd1, blist, bd_le.le_list) {
452 bd_le.le_list) {
453 *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); 460 *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr);
461 if (is_databuf) {
462 gfs2_check_magic(bd1->bd_bh);
463 *ptr++ = cpu_to_be64(buffer_escaped(bd1->bd_bh) ? 1 : 0);
464 }
454 if (++n >= num) 465 if (++n >= num)
455 break; 466 break;
456 } 467 }
@@ -460,12 +471,27 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
460 gfs2_log_lock(sdp); 471 gfs2_log_lock(sdp);
461 472
462 n = 0; 473 n = 0;
463 list_for_each_entry_continue(bd2, &sdp->sd_log_le_buf, 474 list_for_each_entry_continue(bd2, blist, bd_le.le_list) {
464 bd_le.le_list) {
465 get_bh(bd2->bd_bh); 475 get_bh(bd2->bd_bh);
466 gfs2_log_unlock(sdp); 476 gfs2_log_unlock(sdp);
467 lock_buffer(bd2->bd_bh); 477 lock_buffer(bd2->bd_bh);
468 gfs2_log_write_bh(sdp, bd2->bd_bh); 478
479 if (buffer_escaped(bd2->bd_bh)) {
480 void *kaddr;
481 page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
482 ptr = page_address(page);
483 kaddr = kmap_atomic(bd2->bd_bh->b_page);
484 memcpy(ptr, kaddr + bh_offset(bd2->bd_bh),
485 bd2->bd_bh->b_size);
486 kunmap_atomic(kaddr);
487 *(__be32 *)ptr = 0;
488 clear_buffer_escaped(bd2->bd_bh);
489 unlock_buffer(bd2->bd_bh);
490 brelse(bd2->bd_bh);
491 gfs2_log_write_page(sdp, page);
492 } else {
493 gfs2_log_write_bh(sdp, bd2->bd_bh);
494 }
469 gfs2_log_lock(sdp); 495 gfs2_log_lock(sdp);
470 if (++n >= num) 496 if (++n >= num)
471 break; 497 break;
@@ -477,6 +503,14 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
477 gfs2_log_unlock(sdp); 503 gfs2_log_unlock(sdp);
478} 504}
479 505
506static void buf_lo_before_commit(struct gfs2_sbd *sdp)
507{
508 unsigned int limit = buf_limit(sdp); /* 503 for 4k blocks */
509
510 gfs2_before_commit(sdp, limit, sdp->sd_log_num_buf,
511 &sdp->sd_log_le_buf, 0);
512}
513
480static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) 514static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
481{ 515{
482 struct list_head *head = &sdp->sd_log_le_buf; 516 struct list_head *head = &sdp->sd_log_le_buf;
@@ -594,15 +628,14 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
594 struct list_head *head = &sdp->sd_log_le_revoke; 628 struct list_head *head = &sdp->sd_log_le_revoke;
595 struct gfs2_bufdata *bd; 629 struct gfs2_bufdata *bd;
596 struct page *page; 630 struct page *page;
631 unsigned int length;
597 632
598 if (!sdp->sd_log_num_revoke) 633 if (!sdp->sd_log_num_revoke)
599 return; 634 return;
600 635
601 page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE); 636 length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64));
637 page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke);
602 ld = page_address(page); 638 ld = page_address(page);
603 ld->ld_length = cpu_to_be32(gfs2_struct2blk(sdp, sdp->sd_log_num_revoke,
604 sizeof(u64)));
605 ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke);
606 offset = sizeof(struct gfs2_log_descriptor); 639 offset = sizeof(struct gfs2_log_descriptor);
607 640
608 list_for_each_entry(bd, head, bd_le.le_list) { 641 list_for_each_entry(bd, head, bd_le.le_list) {
@@ -775,66 +808,6 @@ out:
775 unlock_buffer(bd->bd_bh); 808 unlock_buffer(bd->bd_bh);
776} 809}
777 810
778static void gfs2_check_magic(struct buffer_head *bh)
779{
780 void *kaddr;
781 __be32 *ptr;
782
783 clear_buffer_escaped(bh);
784 kaddr = kmap_atomic(bh->b_page);
785 ptr = kaddr + bh_offset(bh);
786 if (*ptr == cpu_to_be32(GFS2_MAGIC))
787 set_buffer_escaped(bh);
788 kunmap_atomic(kaddr);
789}
790
791static void gfs2_write_blocks(struct gfs2_sbd *sdp,
792 struct gfs2_log_descriptor *ld,
793 struct page *page,
794 struct list_head *list, struct list_head *done,
795 unsigned int n)
796{
797 struct gfs2_bufdata *bd;
798 __be64 *ptr;
799
800 if (!ld)
801 return;
802
803 ld->ld_length = cpu_to_be32(n + 1);
804 ld->ld_data1 = cpu_to_be32(n);
805 ptr = (__force __be64 *)(ld + 1);
806
807 gfs2_log_write_page(sdp, page);
808 gfs2_log_lock(sdp);
809 while (!list_empty(list)) {
810 bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list);
811 list_move_tail(&bd->bd_le.le_list, done);
812 get_bh(bd->bd_bh);
813 gfs2_log_unlock(sdp);
814 lock_buffer(bd->bd_bh);
815 if (buffer_escaped(bd->bd_bh)) {
816 void *kaddr;
817 page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
818 ptr = page_address(page);
819 kaddr = kmap_atomic(bd->bd_bh->b_page);
820 memcpy(ptr, kaddr + bh_offset(bd->bd_bh),
821 bd->bd_bh->b_size);
822 kunmap_atomic(kaddr);
823 *(__be32 *)ptr = 0;
824 clear_buffer_escaped(bd->bd_bh);
825 unlock_buffer(bd->bd_bh);
826 brelse(bd->bd_bh);
827 gfs2_log_write_page(sdp, page);
828 } else {
829 gfs2_log_write_bh(sdp, bd->bd_bh);
830 }
831 n--;
832 gfs2_log_lock(sdp);
833 }
834 gfs2_log_unlock(sdp);
835 BUG_ON(n != 0);
836}
837
838/** 811/**
839 * databuf_lo_before_commit - Scan the data buffers, writing as we go 812 * databuf_lo_before_commit - Scan the data buffers, writing as we go
840 * 813 *
@@ -842,40 +815,10 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp,
842 815
843static void databuf_lo_before_commit(struct gfs2_sbd *sdp) 816static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
844{ 817{
845 struct gfs2_bufdata *bd = NULL; 818 unsigned int limit = buf_limit(sdp) / 2;
846 struct gfs2_log_descriptor *ld = NULL;
847 struct page *page = NULL;
848 unsigned int n = 0;
849 __be64 *ptr = NULL, *end = NULL;
850 LIST_HEAD(processed);
851 LIST_HEAD(in_progress);
852 819
853 gfs2_log_lock(sdp); 820 gfs2_before_commit(sdp, limit, sdp->sd_log_num_databuf,
854 while (!list_empty(&sdp->sd_log_le_databuf)) { 821 &sdp->sd_log_le_databuf, 1);
855 if (ptr == end) {
856 gfs2_log_unlock(sdp);
857 gfs2_write_blocks(sdp, ld, page, &in_progress, &processed, n);
858 n = 0;
859 page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_JDATA);
860 ld = page_address(page);
861 ptr = (__force __be64 *)(ld + 1);
862 end = (__force __be64 *)(page_address(page) + sdp->sd_vfs->s_blocksize);
863 end--;
864 gfs2_log_lock(sdp);
865 continue;
866 }
867 bd = list_entry(sdp->sd_log_le_databuf.next, struct gfs2_bufdata, bd_le.le_list);
868 list_move_tail(&bd->bd_le.le_list, &in_progress);
869 gfs2_check_magic(bd->bd_bh);
870 *ptr++ = cpu_to_be64(bd->bd_bh->b_blocknr);
871 *ptr++ = cpu_to_be64(buffer_escaped(bd->bd_bh) ? 1 : 0);
872 n++;
873 }
874 gfs2_log_unlock(sdp);
875 gfs2_write_blocks(sdp, ld, page, &in_progress, &processed, n);
876 gfs2_log_lock(sdp);
877 list_splice(&processed, &sdp->sd_log_le_databuf);
878 gfs2_log_unlock(sdp);
879} 822}
880 823
881static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start, 824static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,