Blame view
fs/ufs/balloc.c
27.2 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 |
/* * linux/fs/ufs/balloc.c * * Copyright (C) 1998 * Daniel Pirkl <daniel.pirkl@email.cz> * Charles University, Faculty of Mathematics and Physics |
54fb996ac [PATCH] ufs2 writ... |
7 8 |
* * UFS2 write support Evgeniy Dushistov <dushistov@mail.ru>, 2007 |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 |
*/ #include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 14 |
#include <linux/stat.h> #include <linux/time.h> #include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/buffer_head.h> |
16f7e0fe2 [PATCH] capable/c... |
16 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 |
#include <linux/bitops.h> #include <asm/byteorder.h> |
e54205988 drop linux/ufs_fs... |
19 |
#include "ufs_fs.h" |
bcd6d4ecf ufs: move non-lay... |
20 |
#include "ufs.h" |
1da177e4c Linux-2.6.12-rc2 |
21 22 |
#include "swab.h" #include "util.h" |
54fb996ac [PATCH] ufs2 writ... |
23 24 25 26 27 28 |
#define INVBLOCK ((u64)-1L) static u64 ufs_add_fragments(struct inode *, u64, unsigned, unsigned, int *); static u64 ufs_alloc_fragments(struct inode *, unsigned, u64, unsigned, int *); static u64 ufs_alloccg_block(struct inode *, struct ufs_cg_private_info *, u64, int *); static u64 ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, u64, unsigned); |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 32 33 34 |
static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[]; static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int); /* * Free 'count' fragments from fragment number 'fragment' */ |
54fb996ac [PATCH] ufs2 writ... |
35 |
void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) |
6ef4d6bf8 [PATCH] ufs: chan... |
36 |
{ |
1da177e4c Linux-2.6.12-rc2 |
37 38 39 40 41 |
struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; struct ufs_cg_private_info * ucpi; struct ufs_cylinder_group * ucg; |
54fb996ac [PATCH] ufs2 writ... |
42 43 |
unsigned cgno, bit, end_bit, bbase, blkmap, i; u64 blkno; |
1da177e4c Linux-2.6.12-rc2 |
44 45 46 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2 [PATCH] ufs cleanup |
47 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c Linux-2.6.12-rc2 |
48 |
|
54fb996ac [PATCH] ufs2 writ... |
49 50 51 |
UFSD("ENTER, fragment %llu, count %u ", (unsigned long long)fragment, count); |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 55 56 57 |
if (ufs_fragnum(fragment) + count > uspi->s_fpg) ufs_error (sb, "ufs_free_fragments", "internal error"); lock_super(sb); |
54fb996ac [PATCH] ufs2 writ... |
58 59 |
cgno = ufs_dtog(uspi, fragment); bit = ufs_dtogd(uspi, fragment); |
1da177e4c Linux-2.6.12-rc2 |
60 61 62 63 64 65 66 67 |
if (cgno >= uspi->s_ncg) { ufs_panic (sb, "ufs_free_fragments", "freeing blocks are outside device"); goto failed; } ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) goto failed; |
9695ef16e [PATCH] ufs: wron... |
68 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
69 70 71 72 73 74 75 |
if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_free_fragments", "internal error, bad magic number on cg %u", cgno); goto failed; } end_bit = bit + count; bbase = ufs_blknum (bit); |
9695ef16e [PATCH] ufs: wron... |
76 |
blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); |
1da177e4c Linux-2.6.12-rc2 |
77 78 |
ufs_fragacct (sb, blkmap, ucg->cg_frsum, -1); for (i = bit; i < end_bit; i++) { |
9695ef16e [PATCH] ufs: wron... |
79 80 |
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, i)) ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, i); |
7b4ee73e2 [PATCH] ufs cleanup |
81 82 83 |
else ufs_error (sb, "ufs_free_fragments", "bit already cleared for fragment %u", i); |
1da177e4c Linux-2.6.12-rc2 |
84 85 |
} |
1da177e4c Linux-2.6.12-rc2 |
86 |
fs32_add(sb, &ucg->cg_cs.cs_nffree, count); |
ee3ffd6c1 [PATCH] ufs: make... |
87 |
uspi->cs_total.cs_nffree += count; |
1da177e4c Linux-2.6.12-rc2 |
88 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
9695ef16e [PATCH] ufs: wron... |
89 |
blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 93 94 95 |
ufs_fragacct(sb, blkmap, ucg->cg_frsum, 1); /* * Trying to reassemble free fragments into block */ blkno = ufs_fragstoblks (bbase); |
9695ef16e [PATCH] ufs: wron... |
96 |
if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { |
1da177e4c Linux-2.6.12-rc2 |
97 |
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb); |
ee3ffd6c1 [PATCH] ufs: make... |
98 |
uspi->cs_total.cs_nffree -= uspi->s_fpb; |
1da177e4c Linux-2.6.12-rc2 |
99 100 101 102 |
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb); if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, 1); fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
ee3ffd6c1 [PATCH] ufs: make... |
103 |
uspi->cs_total.cs_nbfree++; |
1da177e4c Linux-2.6.12-rc2 |
104 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
54fb996ac [PATCH] ufs2 writ... |
105 106 107 108 109 110 111 |
if (uspi->fs_magic != UFS2_MAGIC) { unsigned cylno = ufs_cbtocylno (bbase); fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1); fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); } |
1da177e4c Linux-2.6.12-rc2 |
112 113 |
} |
9695ef16e [PATCH] ufs: wron... |
114 115 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60 remove SWRITE* I/... |
116 117 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
118 119 120 |
sb->s_dirt = 1; unlock_super (sb); |
abf5d15fd [PATCH] ufs: easy... |
121 122 |
UFSD("EXIT "); |
1da177e4c Linux-2.6.12-rc2 |
123 124 125 126 |
return; failed: unlock_super (sb); |
abf5d15fd [PATCH] ufs: easy... |
127 128 |
UFSD("EXIT (FAILED) "); |
1da177e4c Linux-2.6.12-rc2 |
129 130 131 132 133 134 |
return; } /* * Free 'count' fragments from fragment number 'fragment' (free whole blocks) */ |
54fb996ac [PATCH] ufs2 writ... |
135 |
void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) |
6ef4d6bf8 [PATCH] ufs: chan... |
136 |
{ |
1da177e4c Linux-2.6.12-rc2 |
137 138 139 140 141 |
struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; struct ufs_cg_private_info * ucpi; struct ufs_cylinder_group * ucg; |
54fb996ac [PATCH] ufs2 writ... |
142 143 |
unsigned overflow, cgno, bit, end_bit, i; u64 blkno; |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2 [PATCH] ufs cleanup |
147 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c Linux-2.6.12-rc2 |
148 |
|
54fb996ac [PATCH] ufs2 writ... |
149 150 151 |
UFSD("ENTER, fragment %llu, count %u ", (unsigned long long)fragment, count); |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 |
if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { ufs_error (sb, "ufs_free_blocks", "internal error, " |
54fb996ac [PATCH] ufs2 writ... |
155 156 157 |
"fragment %llu, count %u ", (unsigned long long)fragment, count); |
1da177e4c Linux-2.6.12-rc2 |
158 159 160 161 162 163 164 |
goto failed; } lock_super(sb); do_more: overflow = 0; |
54fb996ac [PATCH] ufs2 writ... |
165 166 |
cgno = ufs_dtog(uspi, fragment); bit = ufs_dtogd(uspi, fragment); |
1da177e4c Linux-2.6.12-rc2 |
167 168 |
if (cgno >= uspi->s_ncg) { ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); |
2e006393b [PATCH] ufs: unlo... |
169 |
goto failed_unlock; |
1da177e4c Linux-2.6.12-rc2 |
170 171 172 173 174 175 176 177 178 179 |
} end_bit = bit + count; if (end_bit > uspi->s_fpg) { overflow = bit + count - uspi->s_fpg; count -= overflow; end_bit -= overflow; } ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) |
2e006393b [PATCH] ufs: unlo... |
180 |
goto failed_unlock; |
9695ef16e [PATCH] ufs: wron... |
181 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
182 183 |
if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_free_blocks", "internal error, bad magic number on cg %u", cgno); |
2e006393b [PATCH] ufs: unlo... |
184 |
goto failed_unlock; |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 188 |
} for (i = bit; i < end_bit; i += uspi->s_fpb) { blkno = ufs_fragstoblks(i); |
9695ef16e [PATCH] ufs: wron... |
189 |
if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { |
1da177e4c Linux-2.6.12-rc2 |
190 191 |
ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); } |
9695ef16e [PATCH] ufs: wron... |
192 |
ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
1da177e4c Linux-2.6.12-rc2 |
193 194 |
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, 1); |
1da177e4c Linux-2.6.12-rc2 |
195 196 |
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
ee3ffd6c1 [PATCH] ufs: make... |
197 |
uspi->cs_total.cs_nbfree++; |
1da177e4c Linux-2.6.12-rc2 |
198 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
54fb996ac [PATCH] ufs2 writ... |
199 200 201 202 203 204 205 206 |
if (uspi->fs_magic != UFS2_MAGIC) { unsigned cylno = ufs_cbtocylno(i); fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(i)), 1); fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); } |
1da177e4c Linux-2.6.12-rc2 |
207 |
} |
9695ef16e [PATCH] ufs: wron... |
208 209 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60 remove SWRITE* I/... |
210 211 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
212 213 214 215 216 217 218 219 220 |
if (overflow) { fragment += count; count = overflow; goto do_more; } sb->s_dirt = 1; unlock_super (sb); |
abf5d15fd [PATCH] ufs: easy... |
221 222 |
UFSD("EXIT "); |
1da177e4c Linux-2.6.12-rc2 |
223 |
return; |
2e006393b [PATCH] ufs: unlo... |
224 |
failed_unlock: |
1da177e4c Linux-2.6.12-rc2 |
225 |
unlock_super (sb); |
2e006393b [PATCH] ufs: unlo... |
226 |
failed: |
abf5d15fd [PATCH] ufs: easy... |
227 228 |
UFSD("EXIT (FAILED) "); |
1da177e4c Linux-2.6.12-rc2 |
229 230 |
return; } |
6ef4d6bf8 [PATCH] ufs: chan... |
231 232 233 234 235 236 237 238 239 240 |
/* * Modify inode page cache in such way: * have - blocks with b_blocknr equal to oldb...oldb+count-1 * get - blocks with b_blocknr equal to newb...newb+count-1 * also we suppose that oldb...oldb+count-1 blocks * situated at the end of file. * * We can come here from ufs_writepage or ufs_prepare_write, * locked_page is argument of these functions, so we already lock it. */ |
5431bf97c [PATCH] ufs: prep... |
241 242 243 |
static void ufs_change_blocknr(struct inode *inode, sector_t beg, unsigned int count, sector_t oldb, sector_t newb, struct page *locked_page) |
6ef4d6bf8 [PATCH] ufs: chan... |
244 |
{ |
5431bf97c [PATCH] ufs: prep... |
245 246 247 |
const unsigned blks_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); const unsigned mask = blks_per_page - 1; |
efee2b812 [PATCH] ufs: real... |
248 |
struct address_space * const mapping = inode->i_mapping; |
5431bf97c [PATCH] ufs: prep... |
249 250 251 |
pgoff_t index, cur_index, last_index; unsigned pos, j, lblock; sector_t end, i; |
6ef4d6bf8 [PATCH] ufs: chan... |
252 253 |
struct page *page; struct buffer_head *head, *bh; |
5431bf97c [PATCH] ufs: prep... |
254 255 256 257 |
UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu ", inode->i_ino, count, (unsigned long long)oldb, (unsigned long long)newb); |
6ef4d6bf8 [PATCH] ufs: chan... |
258 |
|
a685e26ff [PATCH] ufs: allo... |
259 |
BUG_ON(!locked_page); |
6ef4d6bf8 [PATCH] ufs: chan... |
260 |
BUG_ON(!PageLocked(locked_page)); |
a685e26ff [PATCH] ufs: allo... |
261 |
cur_index = locked_page->index; |
5431bf97c [PATCH] ufs: prep... |
262 263 264 265 |
end = count + beg; last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits); for (i = beg; i < end; i = (i | mask) + 1) { index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits); |
6ef4d6bf8 [PATCH] ufs: chan... |
266 267 268 |
if (likely(cur_index != index)) { page = ufs_get_locked_page(mapping, index); |
5431bf97c [PATCH] ufs: prep... |
269 270 271 |
if (!page)/* it was truncated */ continue; if (IS_ERR(page)) {/* or EIO */ |
9746077a7 ufs: replace rema... |
272 |
ufs_error(inode->i_sb, __func__, |
5431bf97c [PATCH] ufs: prep... |
273 274 275 |
"read of page %llu failed ", (unsigned long long)index); |
6ef4d6bf8 [PATCH] ufs: chan... |
276 |
continue; |
5431bf97c [PATCH] ufs: prep... |
277 |
} |
6ef4d6bf8 [PATCH] ufs: chan... |
278 279 |
} else page = locked_page; |
6ef4d6bf8 [PATCH] ufs: chan... |
280 281 |
head = page_buffers(page); bh = head; |
5431bf97c [PATCH] ufs: prep... |
282 |
pos = i & mask; |
efee2b812 [PATCH] ufs: real... |
283 284 |
for (j = 0; j < pos; ++j) bh = bh->b_this_page; |
5431bf97c [PATCH] ufs: prep... |
285 286 287 288 289 290 |
if (unlikely(index == last_index)) lblock = end & mask; else lblock = blks_per_page; |
6ef4d6bf8 [PATCH] ufs: chan... |
291 |
do { |
5431bf97c [PATCH] ufs: prep... |
292 293 294 295 296 297 298 299 300 301 |
if (j >= lblock) break; pos = (i - beg) + j; if (!buffer_mapped(bh)) map_bh(bh, inode->i_sb, oldb + pos); if (!buffer_uptodate(bh)) { ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); if (!buffer_uptodate(bh)) { |
9746077a7 ufs: replace rema... |
302 |
ufs_error(inode->i_sb, __func__, |
5431bf97c [PATCH] ufs: prep... |
303 304 305 |
"read of block failed "); break; |
efee2b812 [PATCH] ufs: real... |
306 |
} |
6ef4d6bf8 [PATCH] ufs: chan... |
307 |
} |
5431bf97c [PATCH] ufs: prep... |
308 309 |
UFSD(" change from %llu to %llu, pos %u ", |
9df130392 fs/ufs/balloc.c: ... |
310 311 |
(unsigned long long)(pos + oldb), (unsigned long long)(pos + newb), pos); |
5431bf97c [PATCH] ufs: prep... |
312 313 314 315 316 317 |
bh->b_blocknr = newb + pos; unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); mark_buffer_dirty(bh); ++j; |
6ef4d6bf8 [PATCH] ufs: chan... |
318 319 |
bh = bh->b_this_page; } while (bh != head); |
10e5dce07 [PATCH] ufs: trun... |
320 321 |
if (likely(cur_index != index)) ufs_put_locked_page(page); |
6ef4d6bf8 [PATCH] ufs: chan... |
322 |
} |
abf5d15fd [PATCH] ufs: easy... |
323 324 |
UFSD("EXIT "); |
6ef4d6bf8 [PATCH] ufs: chan... |
325 |
} |
d63b70902 [PATCH] fix garba... |
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
static void ufs_clear_frags(struct inode *inode, sector_t beg, unsigned int n, int sync) { struct buffer_head *bh; sector_t end = beg + n; for (; beg < end; ++beg) { bh = sb_getblk(inode->i_sb, beg); lock_buffer(bh); memset(bh->b_data, 0, inode->i_sb->s_blocksize); set_buffer_uptodate(bh); mark_buffer_dirty(bh); unlock_buffer(bh); if (IS_SYNC(inode) || sync) sync_dirty_buffer(bh); brelse(bh); } } |
54fb996ac [PATCH] ufs2 writ... |
344 345 346 |
u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, u64 goal, unsigned count, int *err, struct page *locked_page) |
1da177e4c Linux-2.6.12-rc2 |
347 348 349 350 |
{ struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; |
54fb996ac [PATCH] ufs2 writ... |
351 352 |
unsigned cgno, oldcount, newcount; u64 tmp, request, result; |
1da177e4c Linux-2.6.12-rc2 |
353 |
|
54fb996ac [PATCH] ufs2 writ... |
354 355 356 357 |
UFSD("ENTER, ino %lu, fragment %llu, goal %llu, count %u ", inode->i_ino, (unsigned long long)fragment, (unsigned long long)goal, count); |
1da177e4c Linux-2.6.12-rc2 |
358 359 360 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2 [PATCH] ufs cleanup |
361 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c Linux-2.6.12-rc2 |
362 363 364 |
*err = -ENOSPC; lock_super (sb); |
54fb996ac [PATCH] ufs2 writ... |
365 |
tmp = ufs_data_ptr_to_cpu(sb, p); |
1da177e4c Linux-2.6.12-rc2 |
366 |
if (count + ufs_fragnum(fragment) > uspi->s_fpb) { |
54fb996ac [PATCH] ufs2 writ... |
367 368 369 |
ufs_warning(sb, "ufs_new_fragments", "internal warning" " fragment %llu, count %u", (unsigned long long)fragment, count); |
1da177e4c Linux-2.6.12-rc2 |
370 371 372 373 374 375 376 377 378 379 |
count = uspi->s_fpb - ufs_fragnum(fragment); } oldcount = ufs_fragnum (fragment); newcount = oldcount + count; /* * Somebody else has just allocated our fragments */ if (oldcount) { if (!tmp) { |
54fb996ac [PATCH] ufs2 writ... |
380 381 382 383 384 385 386 |
ufs_error(sb, "ufs_new_fragments", "internal error, " "fragment %llu, tmp %llu ", (unsigned long long)fragment, (unsigned long long)tmp); unlock_super(sb); return INVBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
387 388 |
} if (fragment < UFS_I(inode)->i_lastfrag) { |
abf5d15fd [PATCH] ufs: easy... |
389 390 |
UFSD("EXIT (ALREADY ALLOCATED) "); |
1da177e4c Linux-2.6.12-rc2 |
391 392 393 394 395 396 |
unlock_super (sb); return 0; } } else { if (tmp) { |
abf5d15fd [PATCH] ufs: easy... |
397 398 |
UFSD("EXIT (ALREADY ALLOCATED) "); |
1da177e4c Linux-2.6.12-rc2 |
399 400 401 402 403 404 405 406 |
unlock_super(sb); return 0; } } /* * There is not enough space for user on the device */ |
ee3ffd6c1 [PATCH] ufs: make... |
407 |
if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { |
1da177e4c Linux-2.6.12-rc2 |
408 |
unlock_super (sb); |
abf5d15fd [PATCH] ufs: easy... |
409 410 |
UFSD("EXIT (FAILED) "); |
1da177e4c Linux-2.6.12-rc2 |
411 412 413 414 415 416 417 418 |
return 0; } if (goal >= uspi->s_size) goal = 0; if (goal == 0) cgno = ufs_inotocg (inode->i_ino); else |
54fb996ac [PATCH] ufs2 writ... |
419 |
cgno = ufs_dtog(uspi, goal); |
1da177e4c Linux-2.6.12-rc2 |
420 421 422 423 424 425 426 |
/* * allocate new fragment */ if (oldcount == 0) { result = ufs_alloc_fragments (inode, cgno, goal, count, err); if (result) { |
54fb996ac [PATCH] ufs2 writ... |
427 |
ufs_cpu_to_data_ptr(sb, p, result); |
1da177e4c Linux-2.6.12-rc2 |
428 |
*err = 0; |
54fb996ac [PATCH] ufs2 writ... |
429 |
UFS_I(inode)->i_lastfrag = |
1d5827235 ufs: fix truncate... |
430 |
max(UFS_I(inode)->i_lastfrag, fragment + count); |
54fb996ac [PATCH] ufs2 writ... |
431 432 |
ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); |
1da177e4c Linux-2.6.12-rc2 |
433 434 |
} unlock_super(sb); |
54fb996ac [PATCH] ufs2 writ... |
435 436 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c Linux-2.6.12-rc2 |
437 438 439 440 441 442 443 444 445 |
return result; } /* * resize block */ result = ufs_add_fragments (inode, tmp, oldcount, newcount, err); if (result) { *err = 0; |
1d5827235 ufs: fix truncate... |
446 447 |
UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, fragment + count); |
d63b70902 [PATCH] fix garba... |
448 449 |
ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); |
1da177e4c Linux-2.6.12-rc2 |
450 |
unlock_super(sb); |
54fb996ac [PATCH] ufs2 writ... |
451 452 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c Linux-2.6.12-rc2 |
453 454 455 456 457 458 459 460 461 |
return result; } /* * allocate new block and move data */ switch (fs32_to_cpu(sb, usb1->fs_optim)) { case UFS_OPTSPACE: request = newcount; |
ee3ffd6c1 [PATCH] ufs: make... |
462 463 |
if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree > uspi->s_dsize * uspi->s_minfree / (2 * 100)) |
1da177e4c Linux-2.6.12-rc2 |
464 465 466 467 468 469 470 471 |
break; usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); break; default: usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); case UFS_OPTTIME: request = uspi->s_fpb; |
ee3ffd6c1 [PATCH] ufs: make... |
472 |
if (uspi->cs_total.cs_nffree < uspi->s_dsize * |
1da177e4c Linux-2.6.12-rc2 |
473 474 475 476 477 478 479 |
(uspi->s_minfree - 2) / 100) break; usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); break; } result = ufs_alloc_fragments (inode, cgno, goal, request, err); if (result) { |
efee2b812 [PATCH] ufs: real... |
480 481 |
ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); |
4b25a37e2 [PATCH] ufs: zero... |
482 483 484 |
ufs_change_blocknr(inode, fragment - oldcount, oldcount, uspi->s_sbbase + tmp, uspi->s_sbbase + result, locked_page); |
54fb996ac [PATCH] ufs2 writ... |
485 |
ufs_cpu_to_data_ptr(sb, p, result); |
1da177e4c Linux-2.6.12-rc2 |
486 |
*err = 0; |
1d5827235 ufs: fix truncate... |
487 488 |
UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, fragment + count); |
1da177e4c Linux-2.6.12-rc2 |
489 490 491 492 |
unlock_super(sb); if (newcount < request) ufs_free_fragments (inode, result + newcount, request - newcount); ufs_free_fragments (inode, tmp, oldcount); |
54fb996ac [PATCH] ufs2 writ... |
493 494 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c Linux-2.6.12-rc2 |
495 496 497 498 |
return result; } unlock_super(sb); |
abf5d15fd [PATCH] ufs: easy... |
499 500 |
UFSD("EXIT (FAILED) "); |
1da177e4c Linux-2.6.12-rc2 |
501 502 |
return 0; } |
54fb996ac [PATCH] ufs2 writ... |
503 504 |
static u64 ufs_add_fragments(struct inode *inode, u64 fragment, unsigned oldcount, unsigned newcount, int *err) |
1da177e4c Linux-2.6.12-rc2 |
505 506 507 508 509 510 511 512 |
{ struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; struct ufs_cg_private_info * ucpi; struct ufs_cylinder_group * ucg; unsigned cgno, fragno, fragoff, count, fragsize, i; |
54fb996ac [PATCH] ufs2 writ... |
513 514 515 |
UFSD("ENTER, fragment %llu, oldcount %u, newcount %u ", (unsigned long long)fragment, oldcount, newcount); |
1da177e4c Linux-2.6.12-rc2 |
516 517 518 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2 [PATCH] ufs cleanup |
519 |
usb1 = ubh_get_usb_first (uspi); |
1da177e4c Linux-2.6.12-rc2 |
520 521 |
count = newcount - oldcount; |
54fb996ac [PATCH] ufs2 writ... |
522 |
cgno = ufs_dtog(uspi, fragment); |
1da177e4c Linux-2.6.12-rc2 |
523 524 525 526 527 528 529 |
if (fs32_to_cpu(sb, UFS_SB(sb)->fs_cs(cgno).cs_nffree) < count) return 0; if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb) return 0; ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) return 0; |
9695ef16e [PATCH] ufs: wron... |
530 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
531 532 533 534 535 |
if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_add_fragments", "internal error, bad magic number on cg %u", cgno); return 0; } |
54fb996ac [PATCH] ufs2 writ... |
536 |
fragno = ufs_dtogd(uspi, fragment); |
1da177e4c Linux-2.6.12-rc2 |
537 538 |
fragoff = ufs_fragnum (fragno); for (i = oldcount; i < newcount; i++) |
9695ef16e [PATCH] ufs: wron... |
539 |
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
1da177e4c Linux-2.6.12-rc2 |
540 541 542 543 544 545 |
return 0; /* * Block can be extended */ ucg->cg_time = cpu_to_fs32(sb, get_seconds()); for (i = newcount; i < (uspi->s_fpb - fragoff); i++) |
9695ef16e [PATCH] ufs: wron... |
546 |
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
1da177e4c Linux-2.6.12-rc2 |
547 548 549 550 551 552 553 554 555 |
break; fragsize = i - oldcount; if (!fs32_to_cpu(sb, ucg->cg_frsum[fragsize])) ufs_panic (sb, "ufs_add_fragments", "internal error or corrupted bitmap on cg %u", cgno); fs32_sub(sb, &ucg->cg_frsum[fragsize], 1); if (fragsize != count) fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); for (i = oldcount; i < newcount; i++) |
9695ef16e [PATCH] ufs: wron... |
556 |
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); |
1da177e4c Linux-2.6.12-rc2 |
557 558 559 |
fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
ee3ffd6c1 [PATCH] ufs: make... |
560 |
uspi->cs_total.cs_nffree -= count; |
1da177e4c Linux-2.6.12-rc2 |
561 |
|
9695ef16e [PATCH] ufs: wron... |
562 563 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60 remove SWRITE* I/... |
564 565 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
566 |
sb->s_dirt = 1; |
54fb996ac [PATCH] ufs2 writ... |
567 568 |
UFSD("EXIT, fragment %llu ", (unsigned long long)fragment); |
1da177e4c Linux-2.6.12-rc2 |
569 570 571 572 573 574 575 576 577 578 579 |
return fragment; } #define UFS_TEST_FREE_SPACE_CG \ ucg = (struct ufs_cylinder_group *) UFS_SB(sb)->s_ucg[cgno]->b_data; \ if (fs32_to_cpu(sb, ucg->cg_cs.cs_nbfree)) \ goto cg_found; \ for (k = count; k < uspi->s_fpb; k++) \ if (fs32_to_cpu(sb, ucg->cg_frsum[k])) \ goto cg_found; |
54fb996ac [PATCH] ufs2 writ... |
580 581 |
static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno, u64 goal, unsigned count, int *err) |
1da177e4c Linux-2.6.12-rc2 |
582 583 584 585 586 587 |
{ struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; struct ufs_cg_private_info * ucpi; struct ufs_cylinder_group * ucg; |
54fb996ac [PATCH] ufs2 writ... |
588 589 |
unsigned oldcg, i, j, k, allocsize; u64 result; |
1da177e4c Linux-2.6.12-rc2 |
590 |
|
54fb996ac [PATCH] ufs2 writ... |
591 592 593 |
UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u ", inode->i_ino, cgno, (unsigned long long)goal, count); |
1da177e4c Linux-2.6.12-rc2 |
594 595 596 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2 [PATCH] ufs cleanup |
597 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c Linux-2.6.12-rc2 |
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
oldcg = cgno; /* * 1. searching on preferred cylinder group */ UFS_TEST_FREE_SPACE_CG /* * 2. quadratic rehash */ for (j = 1; j < uspi->s_ncg; j *= 2) { cgno += j; if (cgno >= uspi->s_ncg) cgno -= uspi->s_ncg; UFS_TEST_FREE_SPACE_CG } /* * 3. brute force search * We start at i = 2 ( 0 is checked at 1.step, 1 at 2.step ) */ cgno = (oldcg + 1) % uspi->s_ncg; for (j = 2; j < uspi->s_ncg; j++) { cgno++; if (cgno >= uspi->s_ncg) cgno = 0; UFS_TEST_FREE_SPACE_CG } |
abf5d15fd [PATCH] ufs: easy... |
627 628 |
UFSD("EXIT (FAILED) "); |
1da177e4c Linux-2.6.12-rc2 |
629 630 631 632 633 634 |
return 0; cg_found: ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) return 0; |
9695ef16e [PATCH] ufs: wron... |
635 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
636 637 638 639 640 641 642 |
if (!ufs_cg_chkmagic(sb, ucg)) ufs_panic (sb, "ufs_alloc_fragments", "internal error, bad magic number on cg %u", cgno); ucg->cg_time = cpu_to_fs32(sb, get_seconds()); if (count == uspi->s_fpb) { result = ufs_alloccg_block (inode, ucpi, goal, err); |
54fb996ac [PATCH] ufs2 writ... |
643 |
if (result == INVBLOCK) |
1da177e4c Linux-2.6.12-rc2 |
644 645 646 647 648 649 650 651 652 653 |
return 0; goto succed; } for (allocsize = count; allocsize < uspi->s_fpb; allocsize++) if (fs32_to_cpu(sb, ucg->cg_frsum[allocsize]) != 0) break; if (allocsize == uspi->s_fpb) { result = ufs_alloccg_block (inode, ucpi, goal, err); |
54fb996ac [PATCH] ufs2 writ... |
654 |
if (result == INVBLOCK) |
1da177e4c Linux-2.6.12-rc2 |
655 |
return 0; |
54fb996ac [PATCH] ufs2 writ... |
656 |
goal = ufs_dtogd(uspi, result); |
1da177e4c Linux-2.6.12-rc2 |
657 |
for (i = count; i < uspi->s_fpb; i++) |
9695ef16e [PATCH] ufs: wron... |
658 |
ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); |
1da177e4c Linux-2.6.12-rc2 |
659 |
i = uspi->s_fpb - count; |
1da177e4c Linux-2.6.12-rc2 |
660 661 |
fs32_add(sb, &ucg->cg_cs.cs_nffree, i); |
ee3ffd6c1 [PATCH] ufs: make... |
662 |
uspi->cs_total.cs_nffree += i; |
1da177e4c Linux-2.6.12-rc2 |
663 664 665 666 667 668 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); fs32_add(sb, &ucg->cg_frsum[i], 1); goto succed; } result = ufs_bitmap_search (sb, ucpi, goal, allocsize); |
54fb996ac [PATCH] ufs2 writ... |
669 |
if (result == INVBLOCK) |
1da177e4c Linux-2.6.12-rc2 |
670 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
671 |
for (i = 0; i < count; i++) |
9695ef16e [PATCH] ufs: wron... |
672 |
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); |
1da177e4c Linux-2.6.12-rc2 |
673 674 |
fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); |
ee3ffd6c1 [PATCH] ufs: make... |
675 |
uspi->cs_total.cs_nffree -= count; |
1da177e4c Linux-2.6.12-rc2 |
676 677 678 679 680 681 682 |
fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); fs32_sub(sb, &ucg->cg_frsum[allocsize], 1); if (count != allocsize) fs32_add(sb, &ucg->cg_frsum[allocsize - count], 1); succed: |
9695ef16e [PATCH] ufs: wron... |
683 684 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60 remove SWRITE* I/... |
685 686 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
687 688 689 |
sb->s_dirt = 1; result += cgno * uspi->s_fpg; |
54fb996ac [PATCH] ufs2 writ... |
690 691 |
UFSD("EXIT3, result %llu ", (unsigned long long)result); |
1da177e4c Linux-2.6.12-rc2 |
692 693 |
return result; } |
54fb996ac [PATCH] ufs2 writ... |
694 695 696 |
static u64 ufs_alloccg_block(struct inode *inode, struct ufs_cg_private_info *ucpi, u64 goal, int *err) |
1da177e4c Linux-2.6.12-rc2 |
697 698 699 700 701 |
{ struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; struct ufs_cylinder_group * ucg; |
54fb996ac [PATCH] ufs2 writ... |
702 |
u64 result, blkno; |
1da177e4c Linux-2.6.12-rc2 |
703 |
|
54fb996ac [PATCH] ufs2 writ... |
704 705 |
UFSD("ENTER, goal %llu ", (unsigned long long)goal); |
1da177e4c Linux-2.6.12-rc2 |
706 707 708 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2 [PATCH] ufs cleanup |
709 |
usb1 = ubh_get_usb_first(uspi); |
9695ef16e [PATCH] ufs: wron... |
710 |
ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
711 712 713 714 715 716 |
if (goal == 0) { goal = ucpi->c_rotor; goto norot; } goal = ufs_blknum (goal); |
54fb996ac [PATCH] ufs2 writ... |
717 |
goal = ufs_dtogd(uspi, goal); |
1da177e4c Linux-2.6.12-rc2 |
718 719 720 721 |
/* * If the requested block is available, use it. */ |
9695ef16e [PATCH] ufs: wron... |
722 |
if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) { |
1da177e4c Linux-2.6.12-rc2 |
723 724 725 726 727 728 |
result = goal; goto gotit; } norot: result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb); |
54fb996ac [PATCH] ufs2 writ... |
729 730 |
if (result == INVBLOCK) return INVBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
731 732 733 |
ucpi->c_rotor = result; gotit: blkno = ufs_fragstoblks(result); |
9695ef16e [PATCH] ufs: wron... |
734 |
ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
1da177e4c Linux-2.6.12-rc2 |
735 736 |
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, -1); |
1da177e4c Linux-2.6.12-rc2 |
737 738 |
fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); |
ee3ffd6c1 [PATCH] ufs: make... |
739 |
uspi->cs_total.cs_nbfree--; |
1da177e4c Linux-2.6.12-rc2 |
740 |
fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); |
54fb996ac [PATCH] ufs2 writ... |
741 742 743 744 745 746 747 748 |
if (uspi->fs_magic != UFS2_MAGIC) { unsigned cylno = ufs_cbtocylno((unsigned)result); fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos((unsigned)result)), 1); fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1); } |
1da177e4c Linux-2.6.12-rc2 |
749 |
|
54fb996ac [PATCH] ufs2 writ... |
750 751 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c Linux-2.6.12-rc2 |
752 753 754 |
return result; } |
3e41f597b [PATCH] ufs: not ... |
755 756 757 758 |
static unsigned ubh_scanc(struct ufs_sb_private_info *uspi, struct ufs_buffer_head *ubh, unsigned begin, unsigned size, unsigned char *table, unsigned char mask) |
1da177e4c Linux-2.6.12-rc2 |
759 |
{ |
3e41f597b [PATCH] ufs: not ... |
760 761 |
unsigned rest, offset; unsigned char *cp; |
1da177e4c Linux-2.6.12-rc2 |
762 |
|
1da177e4c Linux-2.6.12-rc2 |
763 |
|
3e41f597b [PATCH] ufs: not ... |
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 |
offset = begin & ~uspi->s_fmask; begin >>= uspi->s_fshift; for (;;) { if ((offset + size) < uspi->s_fsize) rest = size; else rest = uspi->s_fsize - offset; size -= rest; cp = ubh->bh[begin]->b_data + offset; while ((table[*cp++] & mask) == 0 && --rest) ; if (rest || !size) break; begin++; offset = 0; } return (size + rest); } /* * Find a block of the specified size in the specified cylinder group. * @sp: pointer to super block * @ucpi: pointer to cylinder group info * @goal: near which block we want find new one * @count: specified size */ |
54fb996ac [PATCH] ufs2 writ... |
790 791 792 |
static u64 ufs_bitmap_search(struct super_block *sb, struct ufs_cg_private_info *ucpi, u64 goal, unsigned count) |
3e41f597b [PATCH] ufs: not ... |
793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
{ /* * Bit patterns for identifying fragments in the block map * used as ((map & mask_arr) == want_arr) */ static const int mask_arr[9] = { 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff }; static const int want_arr[9] = { 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe }; struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; struct ufs_super_block_first *usb1; struct ufs_cylinder_group *ucg; |
54fb996ac [PATCH] ufs2 writ... |
807 |
unsigned start, length, loc; |
3e41f597b [PATCH] ufs: not ... |
808 |
unsigned pos, want, blockmap, mask, end; |
54fb996ac [PATCH] ufs2 writ... |
809 |
u64 result; |
3e41f597b [PATCH] ufs: not ... |
810 |
|
54fb996ac [PATCH] ufs2 writ... |
811 812 813 |
UFSD("ENTER, cg %u, goal %llu, count %u ", ucpi->c_cgx, (unsigned long long)goal, count); |
3e41f597b [PATCH] ufs: not ... |
814 |
|
7b4ee73e2 [PATCH] ufs cleanup |
815 |
usb1 = ubh_get_usb_first (uspi); |
9695ef16e [PATCH] ufs: wron... |
816 |
ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
1da177e4c Linux-2.6.12-rc2 |
817 818 |
if (goal) |
54fb996ac [PATCH] ufs2 writ... |
819 |
start = ufs_dtogd(uspi, goal) >> 3; |
1da177e4c Linux-2.6.12-rc2 |
820 821 822 823 |
else start = ucpi->c_frotor >> 3; length = ((uspi->s_fpg + 7) >> 3) - start; |
3e41f597b [PATCH] ufs: not ... |
824 |
loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff + start, length, |
1da177e4c Linux-2.6.12-rc2 |
825 826 |
(uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, 1 << (count - 1 + (uspi->s_fpb & 7))); |
3e41f597b [PATCH] ufs: not ... |
827 |
if (loc == 0) { |
1da177e4c Linux-2.6.12-rc2 |
828 |
length = start + 1; |
3e41f597b [PATCH] ufs: not ... |
829 830 831 832 833 834 835 836 837 838 839 |
loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff, length, (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, 1 << (count - 1 + (uspi->s_fpb & 7))); if (loc == 0) { ufs_error(sb, "ufs_bitmap_search", "bitmap corrupted on cg %u, start %u," " length %u, count %u, freeoff %u ", ucpi->c_cgx, start, length, count, ucpi->c_freeoff); |
54fb996ac [PATCH] ufs2 writ... |
840 |
return INVBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
841 842 843 |
} start = 0; } |
3e41f597b [PATCH] ufs: not ... |
844 |
result = (start + length - loc) << 3; |
1da177e4c Linux-2.6.12-rc2 |
845 846 847 848 849 |
ucpi->c_frotor = result; /* * found the byte in the map */ |
3e41f597b [PATCH] ufs: not ... |
850 851 852 853 854 855 856 857 |
for (end = result + 8; result < end; result += uspi->s_fpb) { blockmap = ubh_blkmap(UCPI_UBH(ucpi), ucpi->c_freeoff, result); blockmap <<= 1; mask = mask_arr[count]; want = want_arr[count]; for (pos = 0; pos <= uspi->s_fpb - count; pos++) { if ((blockmap & mask) == want) { |
54fb996ac [PATCH] ufs2 writ... |
858 859 860 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
3e41f597b [PATCH] ufs: not ... |
861 862 863 864 865 866 867 868 869 870 |
return result + pos; } mask <<= 1; want <<= 1; } } ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u ", ucpi->c_cgx); |
abf5d15fd [PATCH] ufs: easy... |
871 872 |
UFSD("EXIT (FAILED) "); |
54fb996ac [PATCH] ufs2 writ... |
873 |
return INVBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
874 875 876 877 878 879 880 881 882 883 884 885 886 |
} static void ufs_clusteracct(struct super_block * sb, struct ufs_cg_private_info * ucpi, unsigned blkno, int cnt) { struct ufs_sb_private_info * uspi; int i, start, end, forw, back; uspi = UFS_SB(sb)->s_uspi; if (uspi->s_contigsumsize <= 0) return; if (cnt > 0) |
9695ef16e [PATCH] ufs: wron... |
887 |
ubh_setbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); |
1da177e4c Linux-2.6.12-rc2 |
888 |
else |
9695ef16e [PATCH] ufs: wron... |
889 |
ubh_clrbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); |
1da177e4c Linux-2.6.12-rc2 |
890 891 892 893 894 895 896 897 |
/* * Find the size of the cluster going forward. */ start = blkno + 1; end = start + uspi->s_contigsumsize; if ( end >= ucpi->c_nclusterblks) end = ucpi->c_nclusterblks; |
9695ef16e [PATCH] ufs: wron... |
898 |
i = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, end, start); |
1da177e4c Linux-2.6.12-rc2 |
899 900 901 902 903 904 905 906 907 908 909 |
if (i > end) i = end; forw = i - start; /* * Find the size of the cluster going backward. */ start = blkno - 1; end = start - uspi->s_contigsumsize; if (end < 0 ) end = -1; |
9695ef16e [PATCH] ufs: wron... |
910 |
i = ubh_find_last_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, start, end); |
1da177e4c Linux-2.6.12-rc2 |
911 912 913 914 915 916 917 918 919 920 921 |
if ( i < end) i = end; back = start - i; /* * Account for old cluster and the possibly new forward and * back clusters. */ i = back + forw + 1; if (i > uspi->s_contigsumsize) i = uspi->s_contigsumsize; |
9695ef16e [PATCH] ufs: wron... |
922 |
fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (i << 2)), cnt); |
1da177e4c Linux-2.6.12-rc2 |
923 |
if (back > 0) |
9695ef16e [PATCH] ufs: wron... |
924 |
fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (back << 2)), cnt); |
1da177e4c Linux-2.6.12-rc2 |
925 |
if (forw > 0) |
9695ef16e [PATCH] ufs: wron... |
926 |
fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (forw << 2)), cnt); |
1da177e4c Linux-2.6.12-rc2 |
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
} static unsigned char ufs_fragtable_8fpb[] = { 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0A, 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x08, 0x09, 0x09, 0x0A, 0x10, 0x11, 0x20, 0x40, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0A, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0A, 0x12, 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0C, 0x08, 0x09, 0x09, 0x0A, 0x09, 0x09, 0x0A, 0x0C, 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, }; static unsigned char ufs_fragtable_other[] = { 0x00, 0x16, 0x16, 0x2A, 0x16, 0x16, 0x26, 0x4E, 0x16, 0x16, 0x16, 0x3E, 0x2A, 0x3E, 0x4E, 0x8A, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x2A, 0x3E, 0x3E, 0x2A, 0x3E, 0x3E, 0x2E, 0x6E, 0x3E, 0x3E, 0x3E, 0x3E, 0x2A, 0x3E, 0x6E, 0xAA, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x26, 0x36, 0x36, 0x2E, 0x36, 0x36, 0x26, 0x6E, 0x36, 0x36, 0x36, 0x3E, 0x2E, 0x3E, 0x6E, 0xAE, 0x4E, 0x5E, 0x5E, 0x6E, 0x5E, 0x5E, 0x6E, 0x4E, 0x5E, 0x5E, 0x5E, 0x7E, 0x6E, 0x7E, 0x4E, 0xCE, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xBE, 0x2A, 0x3E, 0x3E, 0x2A, 0x3E, 0x3E, 0x2E, 0x6E, 0x3E, 0x3E, 0x3E, 0x3E, 0x2A, 0x3E, 0x6E, 0xAA, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xBE, 0x4E, 0x5E, 0x5E, 0x6E, 0x5E, 0x5E, 0x6E, 0x4E, 0x5E, 0x5E, 0x5E, 0x7E, 0x6E, 0x7E, 0x4E, 0xCE, 0x8A, 0x9E, 0x9E, 0xAA, 0x9E, 0x9E, 0xAE, 0xCE, 0x9E, 0x9E, 0x9E, 0xBE, 0xAA, 0xBE, 0xCE, 0x8A, }; |