aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c104
1 files changed, 60 insertions, 44 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 708c287e1d0e..3552110b2e5f 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -25,10 +25,10 @@
25#include "rgrp.h" 25#include "rgrp.h"
26#include "super.h" 26#include "super.h"
27#include "trans.h" 27#include "trans.h"
28#include "ops_file.h"
29#include "util.h" 28#include "util.h"
30#include "log.h" 29#include "log.h"
31#include "inode.h" 30#include "inode.h"
31#include "ops_address.h"
32 32
33#define BFITNOENT ((u32)~0) 33#define BFITNOENT ((u32)~0)
34#define NO_BLOCK ((u64)~0) 34#define NO_BLOCK ((u64)~0)
@@ -126,41 +126,43 @@ static unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer,
126 * Return: the block number (bitmap buffer scope) that was found 126 * Return: the block number (bitmap buffer scope) that was found
127 */ 127 */
128 128
129static u32 gfs2_bitfit(struct gfs2_rgrpd *rgd, unsigned char *buffer, 129static u32 gfs2_bitfit(unsigned char *buffer, unsigned int buflen, u32 goal,
130 unsigned int buflen, u32 goal, 130 unsigned char old_state)
131 unsigned char old_state)
132{ 131{
133 unsigned char *byte, *end, alloc; 132 unsigned char *byte;
134 u32 blk = goal; 133 u32 blk = goal;
135 unsigned int bit; 134 unsigned int bit, bitlong;
135 unsigned long *plong, plong55;
136 136
137 byte = buffer + (goal / GFS2_NBBY); 137 byte = buffer + (goal / GFS2_NBBY);
138 plong = (unsigned long *)(buffer + (goal / GFS2_NBBY));
138 bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; 139 bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
139 end = buffer + buflen; 140 bitlong = bit;
140 alloc = (old_state == GFS2_BLKST_FREE) ? 0x55 : 0; 141#if BITS_PER_LONG == 32
141 142 plong55 = 0x55555555;
142 while (byte < end) { 143#else
143 /* If we're looking for a free block we can eliminate all 144 plong55 = 0x5555555555555555;
144 bitmap settings with 0x55, which represents four data 145#endif
145 blocks in a row. If we're looking for a data block, we can 146 while (byte < buffer + buflen) {
146 eliminate 0x00 which corresponds to four free blocks. */ 147
147 if ((*byte & 0x55) == alloc) { 148 if (bitlong == 0 && old_state == 0 && *plong == plong55) {
148 blk += (8 - bit) >> 1; 149 plong++;
149 150 byte += sizeof(unsigned long);
150 bit = 0; 151 blk += sizeof(unsigned long) * GFS2_NBBY;
151 byte++;
152
153 continue; 152 continue;
154 } 153 }
155
156 if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) 154 if (((*byte >> bit) & GFS2_BIT_MASK) == old_state)
157 return blk; 155 return blk;
158
159 bit += GFS2_BIT_SIZE; 156 bit += GFS2_BIT_SIZE;
160 if (bit >= 8) { 157 if (bit >= 8) {
161 bit = 0; 158 bit = 0;
162 byte++; 159 byte++;
163 } 160 }
161 bitlong += GFS2_BIT_SIZE;
162 if (bitlong >= sizeof(unsigned long) * 8) {
163 bitlong = 0;
164 plong++;
165 }
164 166
165 blk++; 167 blk++;
166 } 168 }
@@ -817,11 +819,9 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
817 819
818struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) 820struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip)
819{ 821{
820 struct gfs2_alloc *al = &ip->i_alloc; 822 BUG_ON(ip->i_alloc != NULL);
821 823 ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_KERNEL);
822 /* FIXME: Should assert that the correct locks are held here... */ 824 return ip->i_alloc;
823 memset(al, 0, sizeof(*al));
824 return al;
825} 825}
826 826
827/** 827/**
@@ -1059,26 +1059,34 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1059 struct inode *inode = NULL; 1059 struct inode *inode = NULL;
1060 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1060 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1061 struct gfs2_rgrpd *rgd, *begin = NULL; 1061 struct gfs2_rgrpd *rgd, *begin = NULL;
1062 struct gfs2_alloc *al = &ip->i_alloc; 1062 struct gfs2_alloc *al = ip->i_alloc;
1063 int flags = LM_FLAG_TRY; 1063 int flags = LM_FLAG_TRY;
1064 int skipped = 0; 1064 int skipped = 0;
1065 int loops = 0; 1065 int loops = 0;
1066 int error; 1066 int error, rg_locked;
1067 1067
1068 /* Try recently successful rgrps */ 1068 /* Try recently successful rgrps */
1069 1069
1070 rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); 1070 rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc);
1071 1071
1072 while (rgd) { 1072 while (rgd) {
1073 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 1073 rg_locked = 0;
1074 LM_FLAG_TRY, &al->al_rgd_gh); 1074
1075 if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) {
1076 rg_locked = 1;
1077 error = 0;
1078 } else {
1079 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
1080 LM_FLAG_TRY, &al->al_rgd_gh);
1081 }
1075 switch (error) { 1082 switch (error) {
1076 case 0: 1083 case 0:
1077 if (try_rgrp_fit(rgd, al)) 1084 if (try_rgrp_fit(rgd, al))
1078 goto out; 1085 goto out;
1079 if (rgd->rd_flags & GFS2_RDF_CHECK) 1086 if (rgd->rd_flags & GFS2_RDF_CHECK)
1080 inode = try_rgrp_unlink(rgd, last_unlinked); 1087 inode = try_rgrp_unlink(rgd, last_unlinked);
1081 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1088 if (!rg_locked)
1089 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1082 if (inode) 1090 if (inode)
1083 return inode; 1091 return inode;
1084 rgd = recent_rgrp_next(rgd, 1); 1092 rgd = recent_rgrp_next(rgd, 1);
@@ -1098,15 +1106,23 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1098 begin = rgd = forward_rgrp_get(sdp); 1106 begin = rgd = forward_rgrp_get(sdp);
1099 1107
1100 for (;;) { 1108 for (;;) {
1101 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, 1109 rg_locked = 0;
1102 &al->al_rgd_gh); 1110
1111 if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) {
1112 rg_locked = 1;
1113 error = 0;
1114 } else {
1115 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags,
1116 &al->al_rgd_gh);
1117 }
1103 switch (error) { 1118 switch (error) {
1104 case 0: 1119 case 0:
1105 if (try_rgrp_fit(rgd, al)) 1120 if (try_rgrp_fit(rgd, al))
1106 goto out; 1121 goto out;
1107 if (rgd->rd_flags & GFS2_RDF_CHECK) 1122 if (rgd->rd_flags & GFS2_RDF_CHECK)
1108 inode = try_rgrp_unlink(rgd, last_unlinked); 1123 inode = try_rgrp_unlink(rgd, last_unlinked);
1109 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1124 if (!rg_locked)
1125 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1110 if (inode) 1126 if (inode)
1111 return inode; 1127 return inode;
1112 break; 1128 break;
@@ -1158,7 +1174,7 @@ out:
1158int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) 1174int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1159{ 1175{
1160 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1176 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1161 struct gfs2_alloc *al = &ip->i_alloc; 1177 struct gfs2_alloc *al = ip->i_alloc;
1162 struct inode *inode; 1178 struct inode *inode;
1163 int error = 0; 1179 int error = 0;
1164 u64 last_unlinked = NO_BLOCK; 1180 u64 last_unlinked = NO_BLOCK;
@@ -1204,7 +1220,7 @@ try_again:
1204void gfs2_inplace_release(struct gfs2_inode *ip) 1220void gfs2_inplace_release(struct gfs2_inode *ip)
1205{ 1221{
1206 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1222 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1207 struct gfs2_alloc *al = &ip->i_alloc; 1223 struct gfs2_alloc *al = ip->i_alloc;
1208 1224
1209 if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1) 1225 if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1)
1210 fs_warn(sdp, "al_alloced = %u, al_requested = %u " 1226 fs_warn(sdp, "al_alloced = %u, al_requested = %u "
@@ -1213,7 +1229,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1213 al->al_line); 1229 al->al_line);
1214 1230
1215 al->al_rgd = NULL; 1231 al->al_rgd = NULL;
1216 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1232 if (al->al_rgd_gh.gh_gl)
1233 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1217 if (ip != GFS2_I(sdp->sd_rindex)) 1234 if (ip != GFS2_I(sdp->sd_rindex))
1218 gfs2_glock_dq_uninit(&al->al_ri_gh); 1235 gfs2_glock_dq_uninit(&al->al_ri_gh);
1219} 1236}
@@ -1301,11 +1318,10 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1301 /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone 1318 /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone
1302 bitmaps, so we must search the originals for that. */ 1319 bitmaps, so we must search the originals for that. */
1303 if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) 1320 if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone)
1304 blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, 1321 blk = gfs2_bitfit(bi->bi_clone + bi->bi_offset,
1305 bi->bi_len, goal, old_state); 1322 bi->bi_len, goal, old_state);
1306 else 1323 else
1307 blk = gfs2_bitfit(rgd, 1324 blk = gfs2_bitfit(bi->bi_bh->b_data + bi->bi_offset,
1308 bi->bi_bh->b_data + bi->bi_offset,
1309 bi->bi_len, goal, old_state); 1325 bi->bi_len, goal, old_state);
1310 if (blk != BFITNOENT) 1326 if (blk != BFITNOENT)
1311 break; 1327 break;
@@ -1394,7 +1410,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
1394u64 gfs2_alloc_data(struct gfs2_inode *ip) 1410u64 gfs2_alloc_data(struct gfs2_inode *ip)
1395{ 1411{
1396 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1412 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1397 struct gfs2_alloc *al = &ip->i_alloc; 1413 struct gfs2_alloc *al = ip->i_alloc;
1398 struct gfs2_rgrpd *rgd = al->al_rgd; 1414 struct gfs2_rgrpd *rgd = al->al_rgd;
1399 u32 goal, blk; 1415 u32 goal, blk;
1400 u64 block; 1416 u64 block;
@@ -1439,7 +1455,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip)
1439u64 gfs2_alloc_meta(struct gfs2_inode *ip) 1455u64 gfs2_alloc_meta(struct gfs2_inode *ip)
1440{ 1456{
1441 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1457 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1442 struct gfs2_alloc *al = &ip->i_alloc; 1458 struct gfs2_alloc *al = ip->i_alloc;
1443 struct gfs2_rgrpd *rgd = al->al_rgd; 1459 struct gfs2_rgrpd *rgd = al->al_rgd;
1444 u32 goal, blk; 1460 u32 goal, blk;
1445 u64 block; 1461 u64 block;
@@ -1485,7 +1501,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip)
1485u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) 1501u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
1486{ 1502{
1487 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 1503 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
1488 struct gfs2_alloc *al = &dip->i_alloc; 1504 struct gfs2_alloc *al = dip->i_alloc;
1489 struct gfs2_rgrpd *rgd = al->al_rgd; 1505 struct gfs2_rgrpd *rgd = al->al_rgd;
1490 u32 blk; 1506 u32 blk;
1491 u64 block; 1507 u64 block;