Blame view
fs/ufs/balloc.c
27.2 KB
1da177e4c
|
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
|
7 8 |
* * UFS2 write support Evgeniy Dushistov <dushistov@mail.ru>, 2007 |
1da177e4c
|
9 10 11 |
*/ #include <linux/fs.h> |
1da177e4c
|
12 13 14 |
#include <linux/stat.h> #include <linux/time.h> #include <linux/string.h> |
1da177e4c
|
15 |
#include <linux/buffer_head.h> |
16f7e0fe2
|
16 |
#include <linux/capability.h> |
1da177e4c
|
17 18 |
#include <linux/bitops.h> #include <asm/byteorder.h> |
e54205988
|
19 |
#include "ufs_fs.h" |
bcd6d4ecf
|
20 |
#include "ufs.h" |
1da177e4c
|
21 22 |
#include "swab.h" #include "util.h" |
54fb996ac
|
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
|
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
|
35 |
void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) |
6ef4d6bf8
|
36 |
{ |
1da177e4c
|
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
|
42 43 |
unsigned cgno, bit, end_bit, bbase, blkmap, i; u64 blkno; |
1da177e4c
|
44 45 46 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2
|
47 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c
|
48 |
|
54fb996ac
|
49 50 51 |
UFSD("ENTER, fragment %llu, count %u ", (unsigned long long)fragment, count); |
1da177e4c
|
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
|
58 59 |
cgno = ufs_dtog(uspi, fragment); bit = ufs_dtogd(uspi, fragment); |
1da177e4c
|
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
|
68 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c
|
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
|
76 |
blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); |
1da177e4c
|
77 78 |
ufs_fragacct (sb, blkmap, ucg->cg_frsum, -1); for (i = bit; i < end_bit; i++) { |
9695ef16e
|
79 80 |
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, i)) ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, i); |
7b4ee73e2
|
81 82 83 |
else ufs_error (sb, "ufs_free_fragments", "bit already cleared for fragment %u", i); |
1da177e4c
|
84 85 |
} |
1da177e4c
|
86 |
fs32_add(sb, &ucg->cg_cs.cs_nffree, count); |
ee3ffd6c1
|
87 |
uspi->cs_total.cs_nffree += count; |
1da177e4c
|
88 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
9695ef16e
|
89 |
blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase); |
1da177e4c
|
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
|
96 |
if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { |
1da177e4c
|
97 |
fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb); |
ee3ffd6c1
|
98 |
uspi->cs_total.cs_nffree -= uspi->s_fpb; |
1da177e4c
|
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
|
103 |
uspi->cs_total.cs_nbfree++; |
1da177e4c
|
104 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
54fb996ac
|
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
|
112 113 |
} |
9695ef16e
|
114 115 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60
|
116 117 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c
|
118 119 120 |
sb->s_dirt = 1; unlock_super (sb); |
abf5d15fd
|
121 122 |
UFSD("EXIT "); |
1da177e4c
|
123 124 125 126 |
return; failed: unlock_super (sb); |
abf5d15fd
|
127 128 |
UFSD("EXIT (FAILED) "); |
1da177e4c
|
129 130 131 132 133 134 |
return; } /* * Free 'count' fragments from fragment number 'fragment' (free whole blocks) */ |
54fb996ac
|
135 |
void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) |
6ef4d6bf8
|
136 |
{ |
1da177e4c
|
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
|
142 143 |
unsigned overflow, cgno, bit, end_bit, i; u64 blkno; |
1da177e4c
|
144 145 146 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2
|
147 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c
|
148 |
|
54fb996ac
|
149 150 151 |
UFSD("ENTER, fragment %llu, count %u ", (unsigned long long)fragment, count); |
1da177e4c
|
152 153 154 |
if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { ufs_error (sb, "ufs_free_blocks", "internal error, " |
54fb996ac
|
155 156 157 |
"fragment %llu, count %u ", (unsigned long long)fragment, count); |
1da177e4c
|
158 159 160 161 162 163 164 |
goto failed; } lock_super(sb); do_more: overflow = 0; |
54fb996ac
|
165 166 |
cgno = ufs_dtog(uspi, fragment); bit = ufs_dtogd(uspi, fragment); |
1da177e4c
|
167 168 |
if (cgno >= uspi->s_ncg) { ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); |
2e006393b
|
169 |
goto failed_unlock; |
1da177e4c
|
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
|
180 |
goto failed_unlock; |
9695ef16e
|
181 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c
|
182 183 |
if (!ufs_cg_chkmagic(sb, ucg)) { ufs_panic (sb, "ufs_free_blocks", "internal error, bad magic number on cg %u", cgno); |
2e006393b
|
184 |
goto failed_unlock; |
1da177e4c
|
185 186 187 188 |
} for (i = bit; i < end_bit; i += uspi->s_fpb) { blkno = ufs_fragstoblks(i); |
9695ef16e
|
189 |
if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) { |
1da177e4c
|
190 191 |
ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); } |
9695ef16e
|
192 |
ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
1da177e4c
|
193 194 |
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, 1); |
1da177e4c
|
195 196 |
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
ee3ffd6c1
|
197 |
uspi->cs_total.cs_nbfree++; |
1da177e4c
|
198 |
fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
54fb996ac
|
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
|
207 |
} |
9695ef16e
|
208 209 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60
|
210 211 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c
|
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
|
221 222 |
UFSD("EXIT "); |
1da177e4c
|
223 |
return; |
2e006393b
|
224 |
failed_unlock: |
1da177e4c
|
225 |
unlock_super (sb); |
2e006393b
|
226 |
failed: |
abf5d15fd
|
227 228 |
UFSD("EXIT (FAILED) "); |
1da177e4c
|
229 230 |
return; } |
6ef4d6bf8
|
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
|
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
|
244 |
{ |
5431bf97c
|
245 246 247 |
const unsigned blks_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); const unsigned mask = blks_per_page - 1; |
efee2b812
|
248 |
struct address_space * const mapping = inode->i_mapping; |
5431bf97c
|
249 250 251 |
pgoff_t index, cur_index, last_index; unsigned pos, j, lblock; sector_t end, i; |
6ef4d6bf8
|
252 253 |
struct page *page; struct buffer_head *head, *bh; |
5431bf97c
|
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
|
258 |
|
a685e26ff
|
259 |
BUG_ON(!locked_page); |
6ef4d6bf8
|
260 |
BUG_ON(!PageLocked(locked_page)); |
a685e26ff
|
261 |
cur_index = locked_page->index; |
5431bf97c
|
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
|
266 267 268 |
if (likely(cur_index != index)) { page = ufs_get_locked_page(mapping, index); |
5431bf97c
|
269 270 271 |
if (!page)/* it was truncated */ continue; if (IS_ERR(page)) {/* or EIO */ |
9746077a7
|
272 |
ufs_error(inode->i_sb, __func__, |
5431bf97c
|
273 274 275 |
"read of page %llu failed ", (unsigned long long)index); |
6ef4d6bf8
|
276 |
continue; |
5431bf97c
|
277 |
} |
6ef4d6bf8
|
278 279 |
} else page = locked_page; |
6ef4d6bf8
|
280 281 |
head = page_buffers(page); bh = head; |
5431bf97c
|
282 |
pos = i & mask; |
efee2b812
|
283 284 |
for (j = 0; j < pos; ++j) bh = bh->b_this_page; |
5431bf97c
|
285 286 287 288 289 290 |
if (unlikely(index == last_index)) lblock = end & mask; else lblock = blks_per_page; |
6ef4d6bf8
|
291 |
do { |
5431bf97c
|
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
|
302 |
ufs_error(inode->i_sb, __func__, |
5431bf97c
|
303 304 305 |
"read of block failed "); break; |
efee2b812
|
306 |
} |
6ef4d6bf8
|
307 |
} |
5431bf97c
|
308 309 |
UFSD(" change from %llu to %llu, pos %u ", |
9df130392
|
310 311 |
(unsigned long long)(pos + oldb), (unsigned long long)(pos + newb), pos); |
5431bf97c
|
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
|
318 319 |
bh = bh->b_this_page; } while (bh != head); |
10e5dce07
|
320 321 |
if (likely(cur_index != index)) ufs_put_locked_page(page); |
6ef4d6bf8
|
322 |
} |
abf5d15fd
|
323 324 |
UFSD("EXIT "); |
6ef4d6bf8
|
325 |
} |
d63b70902
|
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
|
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
|
347 348 349 350 |
{ struct super_block * sb; struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; |
54fb996ac
|
351 352 |
unsigned cgno, oldcount, newcount; u64 tmp, request, result; |
1da177e4c
|
353 |
|
54fb996ac
|
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
|
358 359 360 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2
|
361 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c
|
362 363 364 |
*err = -ENOSPC; lock_super (sb); |
54fb996ac
|
365 |
tmp = ufs_data_ptr_to_cpu(sb, p); |
1da177e4c
|
366 |
if (count + ufs_fragnum(fragment) > uspi->s_fpb) { |
54fb996ac
|
367 368 369 |
ufs_warning(sb, "ufs_new_fragments", "internal warning" " fragment %llu, count %u", (unsigned long long)fragment, count); |
1da177e4c
|
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
|
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
|
387 388 |
} if (fragment < UFS_I(inode)->i_lastfrag) { |
abf5d15fd
|
389 390 |
UFSD("EXIT (ALREADY ALLOCATED) "); |
1da177e4c
|
391 392 393 394 395 396 |
unlock_super (sb); return 0; } } else { if (tmp) { |
abf5d15fd
|
397 398 |
UFSD("EXIT (ALREADY ALLOCATED) "); |
1da177e4c
|
399 400 401 402 403 404 405 406 |
unlock_super(sb); return 0; } } /* * There is not enough space for user on the device */ |
ee3ffd6c1
|
407 |
if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { |
1da177e4c
|
408 |
unlock_super (sb); |
abf5d15fd
|
409 410 |
UFSD("EXIT (FAILED) "); |
1da177e4c
|
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
|
419 |
cgno = ufs_dtog(uspi, goal); |
1da177e4c
|
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
|
427 |
ufs_cpu_to_data_ptr(sb, p, result); |
1da177e4c
|
428 |
*err = 0; |
54fb996ac
|
429 |
UFS_I(inode)->i_lastfrag = |
1d5827235
|
430 |
max(UFS_I(inode)->i_lastfrag, fragment + count); |
54fb996ac
|
431 432 |
ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); |
1da177e4c
|
433 434 |
} unlock_super(sb); |
54fb996ac
|
435 436 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c
|
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
|
446 447 |
UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, fragment + count); |
d63b70902
|
448 449 |
ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); |
1da177e4c
|
450 |
unlock_super(sb); |
54fb996ac
|
451 452 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c
|
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
|
462 463 |
if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree > uspi->s_dsize * uspi->s_minfree / (2 * 100)) |
1da177e4c
|
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
|
472 |
if (uspi->cs_total.cs_nffree < uspi->s_dsize * |
1da177e4c
|
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
|
480 481 |
ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); |
4b25a37e2
|
482 483 484 |
ufs_change_blocknr(inode, fragment - oldcount, oldcount, uspi->s_sbbase + tmp, uspi->s_sbbase + result, locked_page); |
54fb996ac
|
485 |
ufs_cpu_to_data_ptr(sb, p, result); |
1da177e4c
|
486 |
*err = 0; |
1d5827235
|
487 488 |
UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, fragment + count); |
1da177e4c
|
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
|
493 494 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c
|
495 496 497 498 |
return result; } unlock_super(sb); |
abf5d15fd
|
499 500 |
UFSD("EXIT (FAILED) "); |
1da177e4c
|
501 502 |
return 0; } |
54fb996ac
|
503 504 |
static u64 ufs_add_fragments(struct inode *inode, u64 fragment, unsigned oldcount, unsigned newcount, int *err) |
1da177e4c
|
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
|
513 514 515 |
UFSD("ENTER, fragment %llu, oldcount %u, newcount %u ", (unsigned long long)fragment, oldcount, newcount); |
1da177e4c
|
516 517 518 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2
|
519 |
usb1 = ubh_get_usb_first (uspi); |
1da177e4c
|
520 521 |
count = newcount - oldcount; |
54fb996ac
|
522 |
cgno = ufs_dtog(uspi, fragment); |
1da177e4c
|
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
|
530 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c
|
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
|
536 |
fragno = ufs_dtogd(uspi, fragment); |
1da177e4c
|
537 538 |
fragoff = ufs_fragnum (fragno); for (i = oldcount; i < newcount; i++) |
9695ef16e
|
539 |
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
1da177e4c
|
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
|
546 |
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
1da177e4c
|
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
|
556 |
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); |
1da177e4c
|
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
|
560 |
uspi->cs_total.cs_nffree -= count; |
1da177e4c
|
561 |
|
9695ef16e
|
562 563 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60
|
564 565 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c
|
566 |
sb->s_dirt = 1; |
54fb996ac
|
567 568 |
UFSD("EXIT, fragment %llu ", (unsigned long long)fragment); |
1da177e4c
|
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
|
580 581 |
static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno, u64 goal, unsigned count, int *err) |
1da177e4c
|
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
|
588 589 |
unsigned oldcg, i, j, k, allocsize; u64 result; |
1da177e4c
|
590 |
|
54fb996ac
|
591 592 593 |
UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u ", inode->i_ino, cgno, (unsigned long long)goal, count); |
1da177e4c
|
594 595 596 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2
|
597 |
usb1 = ubh_get_usb_first(uspi); |
1da177e4c
|
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
|
627 628 |
UFSD("EXIT (FAILED) "); |
1da177e4c
|
629 630 631 632 633 634 |
return 0; cg_found: ucpi = ufs_load_cylinder (sb, cgno); if (!ucpi) return 0; |
9695ef16e
|
635 |
ucg = ubh_get_ucg (UCPI_UBH(ucpi)); |
1da177e4c
|
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
|
643 |
if (result == INVBLOCK) |
1da177e4c
|
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
|
654 |
if (result == INVBLOCK) |
1da177e4c
|
655 |
return 0; |
54fb996ac
|
656 |
goal = ufs_dtogd(uspi, result); |
1da177e4c
|
657 |
for (i = count; i < uspi->s_fpb; i++) |
9695ef16e
|
658 |
ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); |
1da177e4c
|
659 |
i = uspi->s_fpb - count; |
1da177e4c
|
660 661 |
fs32_add(sb, &ucg->cg_cs.cs_nffree, i); |
ee3ffd6c1
|
662 |
uspi->cs_total.cs_nffree += i; |
1da177e4c
|
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
|
669 |
if (result == INVBLOCK) |
1da177e4c
|
670 |
return 0; |
1da177e4c
|
671 |
for (i = 0; i < count; i++) |
9695ef16e
|
672 |
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); |
1da177e4c
|
673 674 |
fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); |
ee3ffd6c1
|
675 |
uspi->cs_total.cs_nffree -= count; |
1da177e4c
|
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
|
683 684 |
ubh_mark_buffer_dirty (USPI_UBH(uspi)); ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
9cb569d60
|
685 686 |
if (sb->s_flags & MS_SYNCHRONOUS) ubh_sync_block(UCPI_UBH(ucpi)); |
1da177e4c
|
687 688 689 |
sb->s_dirt = 1; result += cgno * uspi->s_fpg; |
54fb996ac
|
690 691 |
UFSD("EXIT3, result %llu ", (unsigned long long)result); |
1da177e4c
|
692 693 |
return result; } |
54fb996ac
|
694 695 696 |
static u64 ufs_alloccg_block(struct inode *inode, struct ufs_cg_private_info *ucpi, u64 goal, int *err) |
1da177e4c
|
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
|
702 |
u64 result, blkno; |
1da177e4c
|
703 |
|
54fb996ac
|
704 705 |
UFSD("ENTER, goal %llu ", (unsigned long long)goal); |
1da177e4c
|
706 707 708 |
sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; |
7b4ee73e2
|
709 |
usb1 = ubh_get_usb_first(uspi); |
9695ef16e
|
710 |
ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
1da177e4c
|
711 712 713 714 715 716 |
if (goal == 0) { goal = ucpi->c_rotor; goto norot; } goal = ufs_blknum (goal); |
54fb996ac
|
717 |
goal = ufs_dtogd(uspi, goal); |
1da177e4c
|
718 719 720 721 |
/* * If the requested block is available, use it. */ |
9695ef16e
|
722 |
if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, ufs_fragstoblks(goal))) { |
1da177e4c
|
723 724 725 726 727 728 |
result = goal; goto gotit; } norot: result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb); |
54fb996ac
|
729 730 |
if (result == INVBLOCK) return INVBLOCK; |
1da177e4c
|
731 732 733 |
ucpi->c_rotor = result; gotit: blkno = ufs_fragstoblks(result); |
9695ef16e
|
734 |
ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
1da177e4c
|
735 736 |
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) ufs_clusteracct (sb, ucpi, blkno, -1); |
1da177e4c
|
737 738 |
fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); |
ee3ffd6c1
|
739 |
uspi->cs_total.cs_nbfree--; |
1da177e4c
|
740 |
fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); |
54fb996ac
|
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
|
749 |
|
54fb996ac
|
750 751 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
1da177e4c
|
752 753 754 |
return result; } |
3e41f597b
|
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
|
759 |
{ |
3e41f597b
|
760 761 |
unsigned rest, offset; unsigned char *cp; |
1da177e4c
|
762 |
|
1da177e4c
|
763 |
|
3e41f597b
|
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
|
790 791 792 |
static u64 ufs_bitmap_search(struct super_block *sb, struct ufs_cg_private_info *ucpi, u64 goal, unsigned count) |
3e41f597b
|
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
|
807 |
unsigned start, length, loc; |
3e41f597b
|
808 |
unsigned pos, want, blockmap, mask, end; |
54fb996ac
|
809 |
u64 result; |
3e41f597b
|
810 |
|
54fb996ac
|
811 812 813 |
UFSD("ENTER, cg %u, goal %llu, count %u ", ucpi->c_cgx, (unsigned long long)goal, count); |
3e41f597b
|
814 |
|
7b4ee73e2
|
815 |
usb1 = ubh_get_usb_first (uspi); |
9695ef16e
|
816 |
ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
1da177e4c
|
817 818 |
if (goal) |
54fb996ac
|
819 |
start = ufs_dtogd(uspi, goal) >> 3; |
1da177e4c
|
820 821 822 823 |
else start = ucpi->c_frotor >> 3; length = ((uspi->s_fpg + 7) >> 3) - start; |
3e41f597b
|
824 |
loc = ubh_scanc(uspi, UCPI_UBH(ucpi), ucpi->c_freeoff + start, length, |
1da177e4c
|
825 826 |
(uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, 1 << (count - 1 + (uspi->s_fpb & 7))); |
3e41f597b
|
827 |
if (loc == 0) { |
1da177e4c
|
828 |
length = start + 1; |
3e41f597b
|
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
|
840 |
return INVBLOCK; |
1da177e4c
|
841 842 843 |
} start = 0; } |
3e41f597b
|
844 |
result = (start + length - loc) << 3; |
1da177e4c
|
845 846 847 848 849 |
ucpi->c_frotor = result; /* * found the byte in the map */ |
3e41f597b
|
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
|
858 859 860 |
UFSD("EXIT, result %llu ", (unsigned long long)result); |
3e41f597b
|
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
|
871 872 |
UFSD("EXIT (FAILED) "); |
54fb996ac
|
873 |
return INVBLOCK; |
1da177e4c
|
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
|
887 |
ubh_setbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); |
1da177e4c
|
888 |
else |
9695ef16e
|
889 |
ubh_clrbit(UCPI_UBH(ucpi), ucpi->c_clusteroff, blkno); |
1da177e4c
|
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
|
898 |
i = ubh_find_next_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, end, start); |
1da177e4c
|
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
|
910 |
i = ubh_find_last_zero_bit (UCPI_UBH(ucpi), ucpi->c_clusteroff, start, end); |
1da177e4c
|
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
|
922 |
fs32_add(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (i << 2)), cnt); |
1da177e4c
|
923 |
if (back > 0) |
9695ef16e
|
924 |
fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (back << 2)), cnt); |
1da177e4c
|
925 |
if (forw > 0) |
9695ef16e
|
926 |
fs32_sub(sb, (__fs32*)ubh_get_addr(UCPI_UBH(ucpi), ucpi->c_clustersumoff + (forw << 2)), cnt); |
1da177e4c
|
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, }; |