diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 370 |
1 files changed, 192 insertions, 178 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 3552110b2e5f..7e8f0b1d6c6e 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/lm_interface.h> | 16 | #include <linux/lm_interface.h> |
17 | #include <linux/prefetch.h> | ||
17 | 18 | ||
18 | #include "gfs2.h" | 19 | #include "gfs2.h" |
19 | #include "incore.h" | 20 | #include "incore.h" |
@@ -33,6 +34,16 @@ | |||
33 | #define BFITNOENT ((u32)~0) | 34 | #define BFITNOENT ((u32)~0) |
34 | #define NO_BLOCK ((u64)~0) | 35 | #define NO_BLOCK ((u64)~0) |
35 | 36 | ||
37 | #if BITS_PER_LONG == 32 | ||
38 | #define LBITMASK (0x55555555UL) | ||
39 | #define LBITSKIP55 (0x55555555UL) | ||
40 | #define LBITSKIP00 (0x00000000UL) | ||
41 | #else | ||
42 | #define LBITMASK (0x5555555555555555UL) | ||
43 | #define LBITSKIP55 (0x5555555555555555UL) | ||
44 | #define LBITSKIP00 (0x0000000000000000UL) | ||
45 | #endif | ||
46 | |||
36 | /* | 47 | /* |
37 | * These routines are used by the resource group routines (rgrp.c) | 48 | * These routines are used by the resource group routines (rgrp.c) |
38 | * to keep track of block allocation. Each block is represented by two | 49 | * to keep track of block allocation. Each block is represented by two |
@@ -53,7 +64,8 @@ static const char valid_change[16] = { | |||
53 | }; | 64 | }; |
54 | 65 | ||
55 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | 66 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, |
56 | unsigned char old_state, unsigned char new_state); | 67 | unsigned char old_state, unsigned char new_state, |
68 | unsigned int *n); | ||
57 | 69 | ||
58 | /** | 70 | /** |
59 | * gfs2_setbit - Set a bit in the bitmaps | 71 | * gfs2_setbit - Set a bit in the bitmaps |
@@ -64,26 +76,32 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
64 | * | 76 | * |
65 | */ | 77 | */ |
66 | 78 | ||
67 | static void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | 79 | static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1, |
68 | unsigned int buflen, u32 block, | 80 | unsigned char *buf2, unsigned int offset, |
69 | unsigned char new_state) | 81 | unsigned int buflen, u32 block, |
82 | unsigned char new_state) | ||
70 | { | 83 | { |
71 | unsigned char *byte, *end, cur_state; | 84 | unsigned char *byte1, *byte2, *end, cur_state; |
72 | unsigned int bit; | 85 | const unsigned int bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; |
73 | 86 | ||
74 | byte = buffer + (block / GFS2_NBBY); | 87 | byte1 = buf1 + offset + (block / GFS2_NBBY); |
75 | bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; | 88 | end = buf1 + offset + buflen; |
76 | end = buffer + buflen; | ||
77 | 89 | ||
78 | gfs2_assert(rgd->rd_sbd, byte < end); | 90 | BUG_ON(byte1 >= end); |
79 | 91 | ||
80 | cur_state = (*byte >> bit) & GFS2_BIT_MASK; | 92 | cur_state = (*byte1 >> bit) & GFS2_BIT_MASK; |
81 | 93 | ||
82 | if (valid_change[new_state * 4 + cur_state]) { | 94 | if (unlikely(!valid_change[new_state * 4 + cur_state])) { |
83 | *byte ^= cur_state << bit; | ||
84 | *byte |= new_state << bit; | ||
85 | } else | ||
86 | gfs2_consist_rgrpd(rgd); | 95 | gfs2_consist_rgrpd(rgd); |
96 | return; | ||
97 | } | ||
98 | *byte1 ^= (cur_state ^ new_state) << bit; | ||
99 | |||
100 | if (buf2) { | ||
101 | byte2 = buf2 + offset + (block / GFS2_NBBY); | ||
102 | cur_state = (*byte2 >> bit) & GFS2_BIT_MASK; | ||
103 | *byte2 ^= (cur_state ^ new_state) << bit; | ||
104 | } | ||
87 | } | 105 | } |
88 | 106 | ||
89 | /** | 107 | /** |
@@ -94,10 +112,12 @@ static void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | |||
94 | * | 112 | * |
95 | */ | 113 | */ |
96 | 114 | ||
97 | static unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | 115 | static inline unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, |
98 | unsigned int buflen, u32 block) | 116 | const unsigned char *buffer, |
117 | unsigned int buflen, u32 block) | ||
99 | { | 118 | { |
100 | unsigned char *byte, *end, cur_state; | 119 | const unsigned char *byte, *end; |
120 | unsigned char cur_state; | ||
101 | unsigned int bit; | 121 | unsigned int bit; |
102 | 122 | ||
103 | byte = buffer + (block / GFS2_NBBY); | 123 | byte = buffer + (block / GFS2_NBBY); |
@@ -126,47 +146,66 @@ static unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | |||
126 | * Return: the block number (bitmap buffer scope) that was found | 146 | * Return: the block number (bitmap buffer scope) that was found |
127 | */ | 147 | */ |
128 | 148 | ||
129 | static u32 gfs2_bitfit(unsigned char *buffer, unsigned int buflen, u32 goal, | 149 | static u32 gfs2_bitfit(const u8 *buffer, unsigned int buflen, u32 goal, |
130 | unsigned char old_state) | 150 | u8 old_state) |
131 | { | 151 | { |
132 | unsigned char *byte; | 152 | const u8 *byte, *start, *end; |
133 | u32 blk = goal; | 153 | int bit, startbit; |
134 | unsigned int bit, bitlong; | 154 | u32 g1, g2, misaligned; |
135 | unsigned long *plong, plong55; | 155 | unsigned long *plong; |
136 | 156 | unsigned long lskipval; | |
137 | byte = buffer + (goal / GFS2_NBBY); | 157 | |
138 | plong = (unsigned long *)(buffer + (goal / GFS2_NBBY)); | 158 | lskipval = (old_state & GFS2_BLKST_USED) ? LBITSKIP00 : LBITSKIP55; |
139 | bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; | 159 | g1 = (goal / GFS2_NBBY); |
140 | bitlong = bit; | 160 | start = buffer + g1; |
141 | #if BITS_PER_LONG == 32 | 161 | byte = start; |
142 | plong55 = 0x55555555; | 162 | end = buffer + buflen; |
143 | #else | 163 | g2 = ALIGN(g1, sizeof(unsigned long)); |
144 | plong55 = 0x5555555555555555; | 164 | plong = (unsigned long *)(buffer + g2); |
145 | #endif | 165 | startbit = bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; |
146 | while (byte < buffer + buflen) { | 166 | misaligned = g2 - g1; |
147 | 167 | if (!misaligned) | |
148 | if (bitlong == 0 && old_state == 0 && *plong == plong55) { | 168 | goto ulong_aligned; |
149 | plong++; | 169 | /* parse the bitmap a byte at a time */ |
150 | byte += sizeof(unsigned long); | 170 | misaligned: |
151 | blk += sizeof(unsigned long) * GFS2_NBBY; | 171 | while (byte < end) { |
152 | continue; | 172 | if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) { |
173 | return goal + | ||
174 | (((byte - start) * GFS2_NBBY) + | ||
175 | ((bit - startbit) >> 1)); | ||
153 | } | 176 | } |
154 | if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) | ||
155 | return blk; | ||
156 | bit += GFS2_BIT_SIZE; | 177 | bit += GFS2_BIT_SIZE; |
157 | if (bit >= 8) { | 178 | if (bit >= GFS2_NBBY * GFS2_BIT_SIZE) { |
158 | bit = 0; | 179 | bit = 0; |
159 | byte++; | 180 | byte++; |
181 | misaligned--; | ||
182 | if (!misaligned) { | ||
183 | plong = (unsigned long *)byte; | ||
184 | goto ulong_aligned; | ||
185 | } | ||
160 | } | 186 | } |
161 | bitlong += GFS2_BIT_SIZE; | ||
162 | if (bitlong >= sizeof(unsigned long) * 8) { | ||
163 | bitlong = 0; | ||
164 | plong++; | ||
165 | } | ||
166 | |||
167 | blk++; | ||
168 | } | 187 | } |
188 | return BFITNOENT; | ||
169 | 189 | ||
190 | /* parse the bitmap a unsigned long at a time */ | ||
191 | ulong_aligned: | ||
192 | /* Stop at "end - 1" or else prefetch can go past the end and segfault. | ||
193 | We could "if" it but we'd lose some of the performance gained. | ||
194 | This way will only slow down searching the very last 4/8 bytes | ||
195 | depending on architecture. I've experimented with several ways | ||
196 | of writing this section such as using an else before the goto | ||
197 | but this one seems to be the fastest. */ | ||
198 | while ((unsigned char *)plong < end - 1) { | ||
199 | prefetch(plong + 1); | ||
200 | if (((*plong) & LBITMASK) != lskipval) | ||
201 | break; | ||
202 | plong++; | ||
203 | } | ||
204 | if ((unsigned char *)plong < end) { | ||
205 | byte = (const u8 *)plong; | ||
206 | misaligned += sizeof(unsigned long) - 1; | ||
207 | goto misaligned; | ||
208 | } | ||
170 | return BFITNOENT; | 209 | return BFITNOENT; |
171 | } | 210 | } |
172 | 211 | ||
@@ -179,14 +218,14 @@ static u32 gfs2_bitfit(unsigned char *buffer, unsigned int buflen, u32 goal, | |||
179 | * Returns: The number of bits | 218 | * Returns: The number of bits |
180 | */ | 219 | */ |
181 | 220 | ||
182 | static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, unsigned char *buffer, | 221 | static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, const u8 *buffer, |
183 | unsigned int buflen, unsigned char state) | 222 | unsigned int buflen, u8 state) |
184 | { | 223 | { |
185 | unsigned char *byte = buffer; | 224 | const u8 *byte = buffer; |
186 | unsigned char *end = buffer + buflen; | 225 | const u8 *end = buffer + buflen; |
187 | unsigned char state1 = state << 2; | 226 | const u8 state1 = state << 2; |
188 | unsigned char state2 = state << 4; | 227 | const u8 state2 = state << 4; |
189 | unsigned char state3 = state << 6; | 228 | const u8 state3 = state << 6; |
190 | u32 count = 0; | 229 | u32 count = 0; |
191 | 230 | ||
192 | for (; byte < end; byte++) { | 231 | for (; byte < end; byte++) { |
@@ -353,7 +392,7 @@ static void clear_rgrpdi(struct gfs2_sbd *sdp) | |||
353 | } | 392 | } |
354 | 393 | ||
355 | kfree(rgd->rd_bits); | 394 | kfree(rgd->rd_bits); |
356 | kfree(rgd); | 395 | kmem_cache_free(gfs2_rgrpd_cachep, rgd); |
357 | } | 396 | } |
358 | } | 397 | } |
359 | 398 | ||
@@ -516,7 +555,7 @@ static int read_rindex_entry(struct gfs2_inode *ip, | |||
516 | return error; | 555 | return error; |
517 | } | 556 | } |
518 | 557 | ||
519 | rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); | 558 | rgd = kmem_cache_zalloc(gfs2_rgrpd_cachep, GFP_NOFS); |
520 | error = -ENOMEM; | 559 | error = -ENOMEM; |
521 | if (!rgd) | 560 | if (!rgd) |
522 | return error; | 561 | return error; |
@@ -539,7 +578,7 @@ static int read_rindex_entry(struct gfs2_inode *ip, | |||
539 | return error; | 578 | return error; |
540 | 579 | ||
541 | rgd->rd_gl->gl_object = rgd; | 580 | rgd->rd_gl->gl_object = rgd; |
542 | rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; | 581 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
543 | rgd->rd_flags |= GFS2_RDF_CHECK; | 582 | rgd->rd_flags |= GFS2_RDF_CHECK; |
544 | return error; | 583 | return error; |
545 | } | 584 | } |
@@ -575,7 +614,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
575 | } | 614 | } |
576 | } | 615 | } |
577 | 616 | ||
578 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; | 617 | sdp->sd_rindex_uptodate = 1; |
579 | return 0; | 618 | return 0; |
580 | } | 619 | } |
581 | 620 | ||
@@ -609,7 +648,7 @@ static int gfs2_ri_update_special(struct gfs2_inode *ip) | |||
609 | } | 648 | } |
610 | } | 649 | } |
611 | 650 | ||
612 | sdp->sd_rindex_vn = ip->i_gl->gl_vn; | 651 | sdp->sd_rindex_uptodate = 1; |
613 | return 0; | 652 | return 0; |
614 | } | 653 | } |
615 | 654 | ||
@@ -642,9 +681,9 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) | |||
642 | return error; | 681 | return error; |
643 | 682 | ||
644 | /* Read new copy from disk if we don't have the latest */ | 683 | /* Read new copy from disk if we don't have the latest */ |
645 | if (sdp->sd_rindex_vn != gl->gl_vn) { | 684 | if (!sdp->sd_rindex_uptodate) { |
646 | mutex_lock(&sdp->sd_rindex_mutex); | 685 | mutex_lock(&sdp->sd_rindex_mutex); |
647 | if (sdp->sd_rindex_vn != gl->gl_vn) { | 686 | if (!sdp->sd_rindex_uptodate) { |
648 | error = gfs2_ri_update(ip); | 687 | error = gfs2_ri_update(ip); |
649 | if (error) | 688 | if (error) |
650 | gfs2_glock_dq_uninit(ri_gh); | 689 | gfs2_glock_dq_uninit(ri_gh); |
@@ -655,21 +694,31 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) | |||
655 | return error; | 694 | return error; |
656 | } | 695 | } |
657 | 696 | ||
658 | static void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) | 697 | static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) |
659 | { | 698 | { |
660 | const struct gfs2_rgrp *str = buf; | 699 | const struct gfs2_rgrp *str = buf; |
700 | struct gfs2_rgrp_host *rg = &rgd->rd_rg; | ||
701 | u32 rg_flags; | ||
661 | 702 | ||
662 | rg->rg_flags = be32_to_cpu(str->rg_flags); | 703 | rg_flags = be32_to_cpu(str->rg_flags); |
704 | if (rg_flags & GFS2_RGF_NOALLOC) | ||
705 | rgd->rd_flags |= GFS2_RDF_NOALLOC; | ||
706 | else | ||
707 | rgd->rd_flags &= ~GFS2_RDF_NOALLOC; | ||
663 | rg->rg_free = be32_to_cpu(str->rg_free); | 708 | rg->rg_free = be32_to_cpu(str->rg_free); |
664 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | 709 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); |
665 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | 710 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); |
666 | } | 711 | } |
667 | 712 | ||
668 | static void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) | 713 | static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) |
669 | { | 714 | { |
670 | struct gfs2_rgrp *str = buf; | 715 | struct gfs2_rgrp *str = buf; |
716 | struct gfs2_rgrp_host *rg = &rgd->rd_rg; | ||
717 | u32 rg_flags = 0; | ||
671 | 718 | ||
672 | str->rg_flags = cpu_to_be32(rg->rg_flags); | 719 | if (rgd->rd_flags & GFS2_RDF_NOALLOC) |
720 | rg_flags |= GFS2_RGF_NOALLOC; | ||
721 | str->rg_flags = cpu_to_be32(rg_flags); | ||
673 | str->rg_free = cpu_to_be32(rg->rg_free); | 722 | str->rg_free = cpu_to_be32(rg->rg_free); |
674 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | 723 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); |
675 | str->__pad = cpu_to_be32(0); | 724 | str->__pad = cpu_to_be32(0); |
@@ -726,9 +775,9 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
726 | } | 775 | } |
727 | } | 776 | } |
728 | 777 | ||
729 | if (rgd->rd_rg_vn != gl->gl_vn) { | 778 | if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) { |
730 | gfs2_rgrp_in(&rgd->rd_rg, (rgd->rd_bits[0].bi_bh)->b_data); | 779 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); |
731 | rgd->rd_rg_vn = gl->gl_vn; | 780 | rgd->rd_flags |= GFS2_RDF_UPTODATE; |
732 | } | 781 | } |
733 | 782 | ||
734 | spin_lock(&sdp->sd_rindex_spin); | 783 | spin_lock(&sdp->sd_rindex_spin); |
@@ -840,7 +889,7 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | |||
840 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 889 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
841 | int ret = 0; | 890 | int ret = 0; |
842 | 891 | ||
843 | if (rgd->rd_rg.rg_flags & GFS2_RGF_NOALLOC) | 892 | if (rgd->rd_flags & GFS2_RDF_NOALLOC) |
844 | return 0; | 893 | return 0; |
845 | 894 | ||
846 | spin_lock(&sdp->sd_rindex_spin); | 895 | spin_lock(&sdp->sd_rindex_spin); |
@@ -866,13 +915,15 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | |||
866 | u32 goal = 0, block; | 915 | u32 goal = 0, block; |
867 | u64 no_addr; | 916 | u64 no_addr; |
868 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 917 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
918 | unsigned int n; | ||
869 | 919 | ||
870 | for(;;) { | 920 | for(;;) { |
871 | if (goal >= rgd->rd_data) | 921 | if (goal >= rgd->rd_data) |
872 | break; | 922 | break; |
873 | down_write(&sdp->sd_log_flush_lock); | 923 | down_write(&sdp->sd_log_flush_lock); |
924 | n = 1; | ||
874 | block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, | 925 | block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, |
875 | GFS2_BLKST_UNLINKED); | 926 | GFS2_BLKST_UNLINKED, &n); |
876 | up_write(&sdp->sd_log_flush_lock); | 927 | up_write(&sdp->sd_log_flush_lock); |
877 | if (block == BFITNOENT) | 928 | if (block == BFITNOENT) |
878 | break; | 929 | break; |
@@ -904,24 +955,20 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | |||
904 | static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, | 955 | static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, |
905 | u64 rglast) | 956 | u64 rglast) |
906 | { | 957 | { |
907 | struct gfs2_rgrpd *rgd = NULL; | 958 | struct gfs2_rgrpd *rgd; |
908 | 959 | ||
909 | spin_lock(&sdp->sd_rindex_spin); | 960 | spin_lock(&sdp->sd_rindex_spin); |
910 | 961 | ||
911 | if (list_empty(&sdp->sd_rindex_recent_list)) | 962 | if (rglast) { |
912 | goto out; | 963 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { |
913 | 964 | if (rgrp_contains_block(rgd, rglast)) | |
914 | if (!rglast) | 965 | goto out; |
915 | goto first; | 966 | } |
916 | |||
917 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { | ||
918 | if (rgd->rd_addr == rglast) | ||
919 | goto out; | ||
920 | } | 967 | } |
921 | 968 | rgd = NULL; | |
922 | first: | 969 | if (!list_empty(&sdp->sd_rindex_recent_list)) |
923 | rgd = list_entry(sdp->sd_rindex_recent_list.next, struct gfs2_rgrpd, | 970 | rgd = list_entry(sdp->sd_rindex_recent_list.next, |
924 | rd_recent); | 971 | struct gfs2_rgrpd, rd_recent); |
925 | out: | 972 | out: |
926 | spin_unlock(&sdp->sd_rindex_spin); | 973 | spin_unlock(&sdp->sd_rindex_spin); |
927 | return rgd; | 974 | return rgd; |
@@ -1067,7 +1114,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1067 | 1114 | ||
1068 | /* Try recently successful rgrps */ | 1115 | /* Try recently successful rgrps */ |
1069 | 1116 | ||
1070 | rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); | 1117 | rgd = recent_rgrp_first(sdp, ip->i_goal); |
1071 | 1118 | ||
1072 | while (rgd) { | 1119 | while (rgd) { |
1073 | rg_locked = 0; | 1120 | rg_locked = 0; |
@@ -1151,8 +1198,6 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1151 | } | 1198 | } |
1152 | 1199 | ||
1153 | out: | 1200 | out: |
1154 | ip->i_last_rg_alloc = rgd->rd_addr; | ||
1155 | |||
1156 | if (begin) { | 1201 | if (begin) { |
1157 | recent_rgrp_add(rgd); | 1202 | recent_rgrp_add(rgd); |
1158 | rgd = gfs2_rgrpd_get_next(rgd); | 1203 | rgd = gfs2_rgrpd_get_next(rgd); |
@@ -1275,6 +1320,7 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | |||
1275 | * @goal: the goal block within the RG (start here to search for avail block) | 1320 | * @goal: the goal block within the RG (start here to search for avail block) |
1276 | * @old_state: GFS2_BLKST_XXX the before-allocation state to find | 1321 | * @old_state: GFS2_BLKST_XXX the before-allocation state to find |
1277 | * @new_state: GFS2_BLKST_XXX the after-allocation block state | 1322 | * @new_state: GFS2_BLKST_XXX the after-allocation block state |
1323 | * @n: The extent length | ||
1278 | * | 1324 | * |
1279 | * Walk rgrp's bitmap to find bits that represent a block in @old_state. | 1325 | * Walk rgrp's bitmap to find bits that represent a block in @old_state. |
1280 | * Add the found bitmap buffer to the transaction. | 1326 | * Add the found bitmap buffer to the transaction. |
@@ -1290,13 +1336,17 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | |||
1290 | */ | 1336 | */ |
1291 | 1337 | ||
1292 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | 1338 | static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, |
1293 | unsigned char old_state, unsigned char new_state) | 1339 | unsigned char old_state, unsigned char new_state, |
1340 | unsigned int *n) | ||
1294 | { | 1341 | { |
1295 | struct gfs2_bitmap *bi = NULL; | 1342 | struct gfs2_bitmap *bi = NULL; |
1296 | u32 length = rgd->rd_length; | 1343 | const u32 length = rgd->rd_length; |
1297 | u32 blk = 0; | 1344 | u32 blk = 0; |
1298 | unsigned int buf, x; | 1345 | unsigned int buf, x; |
1346 | const unsigned int elen = *n; | ||
1347 | const u8 *buffer; | ||
1299 | 1348 | ||
1349 | *n = 0; | ||
1300 | /* Find bitmap block that contains bits for goal block */ | 1350 | /* Find bitmap block that contains bits for goal block */ |
1301 | for (buf = 0; buf < length; buf++) { | 1351 | for (buf = 0; buf < length; buf++) { |
1302 | bi = rgd->rd_bits + buf; | 1352 | bi = rgd->rd_bits + buf; |
@@ -1317,12 +1367,11 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1317 | for (x = 0; x <= length; x++) { | 1367 | for (x = 0; x <= length; x++) { |
1318 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | 1368 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone |
1319 | bitmaps, so we must search the originals for that. */ | 1369 | bitmaps, so we must search the originals for that. */ |
1370 | buffer = bi->bi_bh->b_data + bi->bi_offset; | ||
1320 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) | 1371 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) |
1321 | blk = gfs2_bitfit(bi->bi_clone + bi->bi_offset, | 1372 | buffer = bi->bi_clone + bi->bi_offset; |
1322 | bi->bi_len, goal, old_state); | 1373 | |
1323 | else | 1374 | blk = gfs2_bitfit(buffer, bi->bi_len, goal, old_state); |
1324 | blk = gfs2_bitfit(bi->bi_bh->b_data + bi->bi_offset, | ||
1325 | bi->bi_len, goal, old_state); | ||
1326 | if (blk != BFITNOENT) | 1375 | if (blk != BFITNOENT) |
1327 | break; | 1376 | break; |
1328 | 1377 | ||
@@ -1333,12 +1382,23 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1333 | } | 1382 | } |
1334 | 1383 | ||
1335 | if (blk != BFITNOENT && old_state != new_state) { | 1384 | if (blk != BFITNOENT && old_state != new_state) { |
1385 | *n = 1; | ||
1336 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1386 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1337 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | 1387 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, |
1338 | bi->bi_len, blk, new_state); | 1388 | bi->bi_len, blk, new_state); |
1339 | if (bi->bi_clone) | 1389 | goal = blk; |
1340 | gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, | 1390 | while (*n < elen) { |
1341 | bi->bi_len, blk, new_state); | 1391 | goal++; |
1392 | if (goal >= (bi->bi_len * GFS2_NBBY)) | ||
1393 | break; | ||
1394 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | ||
1395 | GFS2_BLKST_FREE) | ||
1396 | break; | ||
1397 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, | ||
1398 | bi->bi_offset, bi->bi_len, goal, | ||
1399 | new_state); | ||
1400 | (*n)++; | ||
1401 | } | ||
1342 | } | 1402 | } |
1343 | 1403 | ||
1344 | return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk; | 1404 | return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk; |
@@ -1393,7 +1453,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
1393 | bi->bi_len); | 1453 | bi->bi_len); |
1394 | } | 1454 | } |
1395 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1455 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1396 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, | 1456 | gfs2_setbit(rgd, bi->bi_bh->b_data, NULL, bi->bi_offset, |
1397 | bi->bi_len, buf_blk, new_state); | 1457 | bi->bi_len, buf_blk, new_state); |
1398 | } | 1458 | } |
1399 | 1459 | ||
@@ -1401,13 +1461,13 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
1401 | } | 1461 | } |
1402 | 1462 | ||
1403 | /** | 1463 | /** |
1404 | * gfs2_alloc_data - Allocate a data block | 1464 | * gfs2_alloc_block - Allocate a block |
1405 | * @ip: the inode to allocate the data block for | 1465 | * @ip: the inode to allocate the block for |
1406 | * | 1466 | * |
1407 | * Returns: the allocated block | 1467 | * Returns: the allocated block |
1408 | */ | 1468 | */ |
1409 | 1469 | ||
1410 | u64 gfs2_alloc_data(struct gfs2_inode *ip) | 1470 | u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) |
1411 | { | 1471 | { |
1412 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1472 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1413 | struct gfs2_alloc *al = ip->i_alloc; | 1473 | struct gfs2_alloc *al = ip->i_alloc; |
@@ -1415,77 +1475,31 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) | |||
1415 | u32 goal, blk; | 1475 | u32 goal, blk; |
1416 | u64 block; | 1476 | u64 block; |
1417 | 1477 | ||
1418 | if (rgrp_contains_block(rgd, ip->i_di.di_goal_data)) | 1478 | if (rgrp_contains_block(rgd, ip->i_goal)) |
1419 | goal = ip->i_di.di_goal_data - rgd->rd_data0; | 1479 | goal = ip->i_goal - rgd->rd_data0; |
1420 | else | 1480 | else |
1421 | goal = rgd->rd_last_alloc_data; | 1481 | goal = rgd->rd_last_alloc; |
1422 | 1482 | ||
1423 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | 1483 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED, n); |
1424 | BUG_ON(blk == BFITNOENT); | 1484 | BUG_ON(blk == BFITNOENT); |
1425 | rgd->rd_last_alloc_data = blk; | ||
1426 | 1485 | ||
1486 | rgd->rd_last_alloc = blk; | ||
1427 | block = rgd->rd_data0 + blk; | 1487 | block = rgd->rd_data0 + blk; |
1428 | ip->i_di.di_goal_data = block; | 1488 | ip->i_goal = block; |
1429 | 1489 | ||
1430 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | 1490 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free >= *n); |
1431 | rgd->rd_rg.rg_free--; | 1491 | rgd->rd_rg.rg_free -= *n; |
1432 | 1492 | ||
1433 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1493 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1434 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | 1494 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1435 | 1495 | ||
1436 | al->al_alloced++; | 1496 | al->al_alloced += *n; |
1437 | 1497 | ||
1438 | gfs2_statfs_change(sdp, 0, -1, 0); | 1498 | gfs2_statfs_change(sdp, 0, -*n, 0); |
1439 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); | 1499 | gfs2_quota_change(ip, *n, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1440 | 1500 | ||
1441 | spin_lock(&sdp->sd_rindex_spin); | 1501 | spin_lock(&sdp->sd_rindex_spin); |
1442 | rgd->rd_free_clone--; | 1502 | rgd->rd_free_clone -= *n; |
1443 | spin_unlock(&sdp->sd_rindex_spin); | ||
1444 | |||
1445 | return block; | ||
1446 | } | ||
1447 | |||
1448 | /** | ||
1449 | * gfs2_alloc_meta - Allocate a metadata block | ||
1450 | * @ip: the inode to allocate the metadata block for | ||
1451 | * | ||
1452 | * Returns: the allocated block | ||
1453 | */ | ||
1454 | |||
1455 | u64 gfs2_alloc_meta(struct gfs2_inode *ip) | ||
1456 | { | ||
1457 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1458 | struct gfs2_alloc *al = ip->i_alloc; | ||
1459 | struct gfs2_rgrpd *rgd = al->al_rgd; | ||
1460 | u32 goal, blk; | ||
1461 | u64 block; | ||
1462 | |||
1463 | if (rgrp_contains_block(rgd, ip->i_di.di_goal_meta)) | ||
1464 | goal = ip->i_di.di_goal_meta - rgd->rd_data0; | ||
1465 | else | ||
1466 | goal = rgd->rd_last_alloc_meta; | ||
1467 | |||
1468 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | ||
1469 | BUG_ON(blk == BFITNOENT); | ||
1470 | rgd->rd_last_alloc_meta = blk; | ||
1471 | |||
1472 | block = rgd->rd_data0 + blk; | ||
1473 | ip->i_di.di_goal_meta = block; | ||
1474 | |||
1475 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | ||
1476 | rgd->rd_rg.rg_free--; | ||
1477 | |||
1478 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1479 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | ||
1480 | |||
1481 | al->al_alloced++; | ||
1482 | |||
1483 | gfs2_statfs_change(sdp, 0, -1, 0); | ||
1484 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); | ||
1485 | gfs2_trans_add_unrevoke(sdp, block); | ||
1486 | |||
1487 | spin_lock(&sdp->sd_rindex_spin); | ||
1488 | rgd->rd_free_clone--; | ||
1489 | spin_unlock(&sdp->sd_rindex_spin); | 1503 | spin_unlock(&sdp->sd_rindex_spin); |
1490 | 1504 | ||
1491 | return block; | 1505 | return block; |
@@ -1505,12 +1519,13 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) | |||
1505 | struct gfs2_rgrpd *rgd = al->al_rgd; | 1519 | struct gfs2_rgrpd *rgd = al->al_rgd; |
1506 | u32 blk; | 1520 | u32 blk; |
1507 | u64 block; | 1521 | u64 block; |
1522 | unsigned int n = 1; | ||
1508 | 1523 | ||
1509 | blk = rgblk_search(rgd, rgd->rd_last_alloc_meta, | 1524 | blk = rgblk_search(rgd, rgd->rd_last_alloc, |
1510 | GFS2_BLKST_FREE, GFS2_BLKST_DINODE); | 1525 | GFS2_BLKST_FREE, GFS2_BLKST_DINODE, &n); |
1511 | BUG_ON(blk == BFITNOENT); | 1526 | BUG_ON(blk == BFITNOENT); |
1512 | 1527 | ||
1513 | rgd->rd_last_alloc_meta = blk; | 1528 | rgd->rd_last_alloc = blk; |
1514 | 1529 | ||
1515 | block = rgd->rd_data0 + blk; | 1530 | block = rgd->rd_data0 + blk; |
1516 | 1531 | ||
@@ -1519,12 +1534,12 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) | |||
1519 | rgd->rd_rg.rg_dinodes++; | 1534 | rgd->rd_rg.rg_dinodes++; |
1520 | *generation = rgd->rd_rg.rg_igeneration++; | 1535 | *generation = rgd->rd_rg.rg_igeneration++; |
1521 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1536 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1522 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | 1537 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1523 | 1538 | ||
1524 | al->al_alloced++; | 1539 | al->al_alloced++; |
1525 | 1540 | ||
1526 | gfs2_statfs_change(sdp, 0, -1, +1); | 1541 | gfs2_statfs_change(sdp, 0, -1, +1); |
1527 | gfs2_trans_add_unrevoke(sdp, block); | 1542 | gfs2_trans_add_unrevoke(sdp, block, 1); |
1528 | 1543 | ||
1529 | spin_lock(&sdp->sd_rindex_spin); | 1544 | spin_lock(&sdp->sd_rindex_spin); |
1530 | rgd->rd_free_clone--; | 1545 | rgd->rd_free_clone--; |
@@ -1553,7 +1568,7 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1553 | rgd->rd_rg.rg_free += blen; | 1568 | rgd->rd_rg.rg_free += blen; |
1554 | 1569 | ||
1555 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1570 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1556 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | 1571 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1557 | 1572 | ||
1558 | gfs2_trans_add_rg(rgd); | 1573 | gfs2_trans_add_rg(rgd); |
1559 | 1574 | ||
@@ -1581,7 +1596,7 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1581 | rgd->rd_rg.rg_free += blen; | 1596 | rgd->rd_rg.rg_free += blen; |
1582 | 1597 | ||
1583 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1598 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1584 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | 1599 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1585 | 1600 | ||
1586 | gfs2_trans_add_rg(rgd); | 1601 | gfs2_trans_add_rg(rgd); |
1587 | 1602 | ||
@@ -1601,7 +1616,7 @@ void gfs2_unlink_di(struct inode *inode) | |||
1601 | if (!rgd) | 1616 | if (!rgd) |
1602 | return; | 1617 | return; |
1603 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1618 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1604 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | 1619 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1605 | gfs2_trans_add_rg(rgd); | 1620 | gfs2_trans_add_rg(rgd); |
1606 | } | 1621 | } |
1607 | 1622 | ||
@@ -1621,7 +1636,7 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1621 | rgd->rd_rg.rg_free++; | 1636 | rgd->rd_rg.rg_free++; |
1622 | 1637 | ||
1623 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1638 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1624 | gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data); | 1639 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1625 | 1640 | ||
1626 | gfs2_statfs_change(sdp, 0, +1, -1); | 1641 | gfs2_statfs_change(sdp, 0, +1, -1); |
1627 | gfs2_trans_add_rg(rgd); | 1642 | gfs2_trans_add_rg(rgd); |
@@ -1699,8 +1714,7 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, | |||
1699 | * | 1714 | * |
1700 | */ | 1715 | */ |
1701 | 1716 | ||
1702 | void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, | 1717 | void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state) |
1703 | int flags) | ||
1704 | { | 1718 | { |
1705 | unsigned int x; | 1719 | unsigned int x; |
1706 | 1720 | ||
@@ -1708,7 +1722,7 @@ void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, | |||
1708 | GFP_NOFS | __GFP_NOFAIL); | 1722 | GFP_NOFS | __GFP_NOFAIL); |
1709 | for (x = 0; x < rlist->rl_rgrps; x++) | 1723 | for (x = 0; x < rlist->rl_rgrps; x++) |
1710 | gfs2_holder_init(rlist->rl_rgd[x]->rd_gl, | 1724 | gfs2_holder_init(rlist->rl_rgd[x]->rd_gl, |
1711 | state, flags, | 1725 | state, 0, |
1712 | &rlist->rl_ghs[x]); | 1726 | &rlist->rl_ghs[x]); |
1713 | } | 1727 | } |
1714 | 1728 | ||