diff options
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/balloc.c | 197 | ||||
-rw-r--r-- | fs/ufs/inode.c | 82 | ||||
-rw-r--r-- | fs/ufs/truncate.c | 139 | ||||
-rw-r--r-- | fs/ufs/util.h | 57 |
4 files changed, 297 insertions, 178 deletions
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 638f4c585e89..0e97a4f79c31 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 1998 | 4 | * Copyright (C) 1998 |
5 | * Daniel Pirkl <daniel.pirkl@email.cz> | 5 | * Daniel Pirkl <daniel.pirkl@email.cz> |
6 | * Charles University, Faculty of Mathematics and Physics | 6 | * Charles University, Faculty of Mathematics and Physics |
7 | * | ||
8 | * UFS2 write support Evgeniy Dushistov <dushistov@mail.ru>, 2007 | ||
7 | */ | 9 | */ |
8 | 10 | ||
9 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
@@ -21,38 +23,42 @@ | |||
21 | #include "swab.h" | 23 | #include "swab.h" |
22 | #include "util.h" | 24 | #include "util.h" |
23 | 25 | ||
24 | static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *); | 26 | #define INVBLOCK ((u64)-1L) |
25 | static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *); | 27 | |
26 | static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *); | 28 | static u64 ufs_add_fragments(struct inode *, u64, unsigned, unsigned, int *); |
27 | static unsigned ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, unsigned, unsigned); | 29 | static u64 ufs_alloc_fragments(struct inode *, unsigned, u64, unsigned, int *); |
30 | static u64 ufs_alloccg_block(struct inode *, struct ufs_cg_private_info *, u64, int *); | ||
31 | static u64 ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, u64, unsigned); | ||
28 | static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[]; | 32 | static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[]; |
29 | static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int); | 33 | static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int); |
30 | 34 | ||
31 | /* | 35 | /* |
32 | * Free 'count' fragments from fragment number 'fragment' | 36 | * Free 'count' fragments from fragment number 'fragment' |
33 | */ | 37 | */ |
34 | void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) | 38 | void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) |
35 | { | 39 | { |
36 | struct super_block * sb; | 40 | struct super_block * sb; |
37 | struct ufs_sb_private_info * uspi; | 41 | struct ufs_sb_private_info * uspi; |
38 | struct ufs_super_block_first * usb1; | 42 | struct ufs_super_block_first * usb1; |
39 | struct ufs_cg_private_info * ucpi; | 43 | struct ufs_cg_private_info * ucpi; |
40 | struct ufs_cylinder_group * ucg; | 44 | struct ufs_cylinder_group * ucg; |
41 | unsigned cgno, bit, end_bit, bbase, blkmap, i, blkno, cylno; | 45 | unsigned cgno, bit, end_bit, bbase, blkmap, i; |
46 | u64 blkno; | ||
42 | 47 | ||
43 | sb = inode->i_sb; | 48 | sb = inode->i_sb; |
44 | uspi = UFS_SB(sb)->s_uspi; | 49 | uspi = UFS_SB(sb)->s_uspi; |
45 | usb1 = ubh_get_usb_first(uspi); | 50 | usb1 = ubh_get_usb_first(uspi); |
46 | 51 | ||
47 | UFSD("ENTER, fragment %u, count %u\n", fragment, count); | 52 | UFSD("ENTER, fragment %llu, count %u\n", |
53 | (unsigned long long)fragment, count); | ||
48 | 54 | ||
49 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) | 55 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) |
50 | ufs_error (sb, "ufs_free_fragments", "internal error"); | 56 | ufs_error (sb, "ufs_free_fragments", "internal error"); |
51 | 57 | ||
52 | lock_super(sb); | 58 | lock_super(sb); |
53 | 59 | ||
54 | cgno = ufs_dtog(fragment); | 60 | cgno = ufs_dtog(uspi, fragment); |
55 | bit = ufs_dtogd(fragment); | 61 | bit = ufs_dtogd(uspi, fragment); |
56 | if (cgno >= uspi->s_ncg) { | 62 | if (cgno >= uspi->s_ncg) { |
57 | ufs_panic (sb, "ufs_free_fragments", "freeing blocks are outside device"); | 63 | ufs_panic (sb, "ufs_free_fragments", "freeing blocks are outside device"); |
58 | goto failed; | 64 | goto failed; |
@@ -101,9 +107,13 @@ void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) | |||
101 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); | 107 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
102 | uspi->cs_total.cs_nbfree++; | 108 | uspi->cs_total.cs_nbfree++; |
103 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); | 109 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
104 | cylno = ufs_cbtocylno (bbase); | 110 | if (uspi->fs_magic != UFS2_MAGIC) { |
105 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1); | 111 | unsigned cylno = ufs_cbtocylno (bbase); |
106 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); | 112 | |
113 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, | ||
114 | ufs_cbtorpos(bbase)), 1); | ||
115 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); | ||
116 | } | ||
107 | } | 117 | } |
108 | 118 | ||
109 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 119 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
@@ -127,24 +137,27 @@ failed: | |||
127 | /* | 137 | /* |
128 | * Free 'count' fragments from fragment number 'fragment' (free whole blocks) | 138 | * Free 'count' fragments from fragment number 'fragment' (free whole blocks) |
129 | */ | 139 | */ |
130 | void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count) | 140 | void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) |
131 | { | 141 | { |
132 | struct super_block * sb; | 142 | struct super_block * sb; |
133 | struct ufs_sb_private_info * uspi; | 143 | struct ufs_sb_private_info * uspi; |
134 | struct ufs_super_block_first * usb1; | 144 | struct ufs_super_block_first * usb1; |
135 | struct ufs_cg_private_info * ucpi; | 145 | struct ufs_cg_private_info * ucpi; |
136 | struct ufs_cylinder_group * ucg; | 146 | struct ufs_cylinder_group * ucg; |
137 | unsigned overflow, cgno, bit, end_bit, blkno, i, cylno; | 147 | unsigned overflow, cgno, bit, end_bit, i; |
148 | u64 blkno; | ||
138 | 149 | ||
139 | sb = inode->i_sb; | 150 | sb = inode->i_sb; |
140 | uspi = UFS_SB(sb)->s_uspi; | 151 | uspi = UFS_SB(sb)->s_uspi; |
141 | usb1 = ubh_get_usb_first(uspi); | 152 | usb1 = ubh_get_usb_first(uspi); |
142 | 153 | ||
143 | UFSD("ENTER, fragment %u, count %u\n", fragment, count); | 154 | UFSD("ENTER, fragment %llu, count %u\n", |
155 | (unsigned long long)fragment, count); | ||
144 | 156 | ||
145 | if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { | 157 | if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) { |
146 | ufs_error (sb, "ufs_free_blocks", "internal error, " | 158 | ufs_error (sb, "ufs_free_blocks", "internal error, " |
147 | "fragment %u, count %u\n", fragment, count); | 159 | "fragment %llu, count %u\n", |
160 | (unsigned long long)fragment, count); | ||
148 | goto failed; | 161 | goto failed; |
149 | } | 162 | } |
150 | 163 | ||
@@ -152,8 +165,8 @@ void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count) | |||
152 | 165 | ||
153 | do_more: | 166 | do_more: |
154 | overflow = 0; | 167 | overflow = 0; |
155 | cgno = ufs_dtog (fragment); | 168 | cgno = ufs_dtog(uspi, fragment); |
156 | bit = ufs_dtogd (fragment); | 169 | bit = ufs_dtogd(uspi, fragment); |
157 | if (cgno >= uspi->s_ncg) { | 170 | if (cgno >= uspi->s_ncg) { |
158 | ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); | 171 | ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device"); |
159 | goto failed_unlock; | 172 | goto failed_unlock; |
@@ -187,9 +200,14 @@ do_more: | |||
187 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); | 200 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
188 | uspi->cs_total.cs_nbfree++; | 201 | uspi->cs_total.cs_nbfree++; |
189 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); | 202 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1); |
190 | cylno = ufs_cbtocylno(i); | 203 | |
191 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(i)), 1); | 204 | if (uspi->fs_magic != UFS2_MAGIC) { |
192 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); | 205 | unsigned cylno = ufs_cbtocylno(i); |
206 | |||
207 | fs16_add(sb, &ubh_cg_blks(ucpi, cylno, | ||
208 | ufs_cbtorpos(i)), 1); | ||
209 | fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1); | ||
210 | } | ||
193 | } | 211 | } |
194 | 212 | ||
195 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 213 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
@@ -308,15 +326,19 @@ static void ufs_clear_frags(struct inode *inode, sector_t beg, unsigned int n, | |||
308 | } | 326 | } |
309 | } | 327 | } |
310 | 328 | ||
311 | unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | 329 | u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, |
312 | unsigned goal, unsigned count, int * err, struct page *locked_page) | 330 | u64 goal, unsigned count, int *err, |
331 | struct page *locked_page) | ||
313 | { | 332 | { |
314 | struct super_block * sb; | 333 | struct super_block * sb; |
315 | struct ufs_sb_private_info * uspi; | 334 | struct ufs_sb_private_info * uspi; |
316 | struct ufs_super_block_first * usb1; | 335 | struct ufs_super_block_first * usb1; |
317 | unsigned cgno, oldcount, newcount, tmp, request, result; | 336 | unsigned cgno, oldcount, newcount; |
337 | u64 tmp, request, result; | ||
318 | 338 | ||
319 | UFSD("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count); | 339 | UFSD("ENTER, ino %lu, fragment %llu, goal %llu, count %u\n", |
340 | inode->i_ino, (unsigned long long)fragment, | ||
341 | (unsigned long long)goal, count); | ||
320 | 342 | ||
321 | sb = inode->i_sb; | 343 | sb = inode->i_sb; |
322 | uspi = UFS_SB(sb)->s_uspi; | 344 | uspi = UFS_SB(sb)->s_uspi; |
@@ -324,11 +346,12 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
324 | *err = -ENOSPC; | 346 | *err = -ENOSPC; |
325 | 347 | ||
326 | lock_super (sb); | 348 | lock_super (sb); |
327 | 349 | tmp = ufs_data_ptr_to_cpu(sb, p); | |
328 | tmp = fs32_to_cpu(sb, *p); | 350 | |
329 | if (count + ufs_fragnum(fragment) > uspi->s_fpb) { | 351 | if (count + ufs_fragnum(fragment) > uspi->s_fpb) { |
330 | ufs_warning (sb, "ufs_new_fragments", "internal warning" | 352 | ufs_warning(sb, "ufs_new_fragments", "internal warning" |
331 | " fragment %u, count %u", fragment, count); | 353 | " fragment %llu, count %u", |
354 | (unsigned long long)fragment, count); | ||
332 | count = uspi->s_fpb - ufs_fragnum(fragment); | 355 | count = uspi->s_fpb - ufs_fragnum(fragment); |
333 | } | 356 | } |
334 | oldcount = ufs_fragnum (fragment); | 357 | oldcount = ufs_fragnum (fragment); |
@@ -339,10 +362,12 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
339 | */ | 362 | */ |
340 | if (oldcount) { | 363 | if (oldcount) { |
341 | if (!tmp) { | 364 | if (!tmp) { |
342 | ufs_error (sb, "ufs_new_fragments", "internal error, " | 365 | ufs_error(sb, "ufs_new_fragments", "internal error, " |
343 | "fragment %u, tmp %u\n", fragment, tmp); | 366 | "fragment %llu, tmp %llu\n", |
344 | unlock_super (sb); | 367 | (unsigned long long)fragment, |
345 | return (unsigned)-1; | 368 | (unsigned long long)tmp); |
369 | unlock_super(sb); | ||
370 | return INVBLOCK; | ||
346 | } | 371 | } |
347 | if (fragment < UFS_I(inode)->i_lastfrag) { | 372 | if (fragment < UFS_I(inode)->i_lastfrag) { |
348 | UFSD("EXIT (ALREADY ALLOCATED)\n"); | 373 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
@@ -372,7 +397,7 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
372 | if (goal == 0) | 397 | if (goal == 0) |
373 | cgno = ufs_inotocg (inode->i_ino); | 398 | cgno = ufs_inotocg (inode->i_ino); |
374 | else | 399 | else |
375 | cgno = ufs_dtog (goal); | 400 | cgno = ufs_dtog(uspi, goal); |
376 | 401 | ||
377 | /* | 402 | /* |
378 | * allocate new fragment | 403 | * allocate new fragment |
@@ -380,14 +405,16 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
380 | if (oldcount == 0) { | 405 | if (oldcount == 0) { |
381 | result = ufs_alloc_fragments (inode, cgno, goal, count, err); | 406 | result = ufs_alloc_fragments (inode, cgno, goal, count, err); |
382 | if (result) { | 407 | if (result) { |
383 | *p = cpu_to_fs32(sb, result); | 408 | ufs_cpu_to_data_ptr(sb, p, result); |
384 | *err = 0; | 409 | *err = 0; |
385 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 410 | UFS_I(inode)->i_lastfrag = |
386 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | 411 | max_t(u32, UFS_I(inode)->i_lastfrag, |
387 | locked_page != NULL); | 412 | fragment + count); |
413 | ufs_clear_frags(inode, result + oldcount, | ||
414 | newcount - oldcount, locked_page != NULL); | ||
388 | } | 415 | } |
389 | unlock_super(sb); | 416 | unlock_super(sb); |
390 | UFSD("EXIT, result %u\n", result); | 417 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
391 | return result; | 418 | return result; |
392 | } | 419 | } |
393 | 420 | ||
@@ -401,7 +428,7 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
401 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | 428 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, |
402 | locked_page != NULL); | 429 | locked_page != NULL); |
403 | unlock_super(sb); | 430 | unlock_super(sb); |
404 | UFSD("EXIT, result %u\n", result); | 431 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
405 | return result; | 432 | return result; |
406 | } | 433 | } |
407 | 434 | ||
@@ -433,15 +460,14 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
433 | locked_page != NULL); | 460 | locked_page != NULL); |
434 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, | 461 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, |
435 | result, locked_page); | 462 | result, locked_page); |
436 | 463 | ufs_cpu_to_data_ptr(sb, p, result); | |
437 | *p = cpu_to_fs32(sb, result); | ||
438 | *err = 0; | 464 | *err = 0; |
439 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 465 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
440 | unlock_super(sb); | 466 | unlock_super(sb); |
441 | if (newcount < request) | 467 | if (newcount < request) |
442 | ufs_free_fragments (inode, result + newcount, request - newcount); | 468 | ufs_free_fragments (inode, result + newcount, request - newcount); |
443 | ufs_free_fragments (inode, tmp, oldcount); | 469 | ufs_free_fragments (inode, tmp, oldcount); |
444 | UFSD("EXIT, result %u\n", result); | 470 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
445 | return result; | 471 | return result; |
446 | } | 472 | } |
447 | 473 | ||
@@ -450,9 +476,8 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
450 | return 0; | 476 | return 0; |
451 | } | 477 | } |
452 | 478 | ||
453 | static unsigned | 479 | static u64 ufs_add_fragments(struct inode *inode, u64 fragment, |
454 | ufs_add_fragments (struct inode * inode, unsigned fragment, | 480 | unsigned oldcount, unsigned newcount, int *err) |
455 | unsigned oldcount, unsigned newcount, int * err) | ||
456 | { | 481 | { |
457 | struct super_block * sb; | 482 | struct super_block * sb; |
458 | struct ufs_sb_private_info * uspi; | 483 | struct ufs_sb_private_info * uspi; |
@@ -461,14 +486,15 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
461 | struct ufs_cylinder_group * ucg; | 486 | struct ufs_cylinder_group * ucg; |
462 | unsigned cgno, fragno, fragoff, count, fragsize, i; | 487 | unsigned cgno, fragno, fragoff, count, fragsize, i; |
463 | 488 | ||
464 | UFSD("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount); | 489 | UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n", |
490 | (unsigned long long)fragment, oldcount, newcount); | ||
465 | 491 | ||
466 | sb = inode->i_sb; | 492 | sb = inode->i_sb; |
467 | uspi = UFS_SB(sb)->s_uspi; | 493 | uspi = UFS_SB(sb)->s_uspi; |
468 | usb1 = ubh_get_usb_first (uspi); | 494 | usb1 = ubh_get_usb_first (uspi); |
469 | count = newcount - oldcount; | 495 | count = newcount - oldcount; |
470 | 496 | ||
471 | cgno = ufs_dtog(fragment); | 497 | cgno = ufs_dtog(uspi, fragment); |
472 | if (fs32_to_cpu(sb, UFS_SB(sb)->fs_cs(cgno).cs_nffree) < count) | 498 | if (fs32_to_cpu(sb, UFS_SB(sb)->fs_cs(cgno).cs_nffree) < count) |
473 | return 0; | 499 | return 0; |
474 | if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb) | 500 | if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb) |
@@ -483,7 +509,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
483 | return 0; | 509 | return 0; |
484 | } | 510 | } |
485 | 511 | ||
486 | fragno = ufs_dtogd (fragment); | 512 | fragno = ufs_dtogd(uspi, fragment); |
487 | fragoff = ufs_fragnum (fragno); | 513 | fragoff = ufs_fragnum (fragno); |
488 | for (i = oldcount; i < newcount; i++) | 514 | for (i = oldcount; i < newcount; i++) |
489 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) | 515 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
@@ -521,7 +547,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
521 | } | 547 | } |
522 | sb->s_dirt = 1; | 548 | sb->s_dirt = 1; |
523 | 549 | ||
524 | UFSD("EXIT, fragment %u\n", fragment); | 550 | UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment); |
525 | 551 | ||
526 | return fragment; | 552 | return fragment; |
527 | } | 553 | } |
@@ -534,17 +560,19 @@ ufs_add_fragments (struct inode * inode, unsigned fragment, | |||
534 | if (fs32_to_cpu(sb, ucg->cg_frsum[k])) \ | 560 | if (fs32_to_cpu(sb, ucg->cg_frsum[k])) \ |
535 | goto cg_found; | 561 | goto cg_found; |
536 | 562 | ||
537 | static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno, | 563 | static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno, |
538 | unsigned goal, unsigned count, int * err) | 564 | u64 goal, unsigned count, int *err) |
539 | { | 565 | { |
540 | struct super_block * sb; | 566 | struct super_block * sb; |
541 | struct ufs_sb_private_info * uspi; | 567 | struct ufs_sb_private_info * uspi; |
542 | struct ufs_super_block_first * usb1; | 568 | struct ufs_super_block_first * usb1; |
543 | struct ufs_cg_private_info * ucpi; | 569 | struct ufs_cg_private_info * ucpi; |
544 | struct ufs_cylinder_group * ucg; | 570 | struct ufs_cylinder_group * ucg; |
545 | unsigned oldcg, i, j, k, result, allocsize; | 571 | unsigned oldcg, i, j, k, allocsize; |
572 | u64 result; | ||
546 | 573 | ||
547 | UFSD("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count); | 574 | UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n", |
575 | inode->i_ino, cgno, (unsigned long long)goal, count); | ||
548 | 576 | ||
549 | sb = inode->i_sb; | 577 | sb = inode->i_sb; |
550 | uspi = UFS_SB(sb)->s_uspi; | 578 | uspi = UFS_SB(sb)->s_uspi; |
@@ -593,7 +621,7 @@ cg_found: | |||
593 | 621 | ||
594 | if (count == uspi->s_fpb) { | 622 | if (count == uspi->s_fpb) { |
595 | result = ufs_alloccg_block (inode, ucpi, goal, err); | 623 | result = ufs_alloccg_block (inode, ucpi, goal, err); |
596 | if (result == (unsigned)-1) | 624 | if (result == INVBLOCK) |
597 | return 0; | 625 | return 0; |
598 | goto succed; | 626 | goto succed; |
599 | } | 627 | } |
@@ -604,9 +632,9 @@ cg_found: | |||
604 | 632 | ||
605 | if (allocsize == uspi->s_fpb) { | 633 | if (allocsize == uspi->s_fpb) { |
606 | result = ufs_alloccg_block (inode, ucpi, goal, err); | 634 | result = ufs_alloccg_block (inode, ucpi, goal, err); |
607 | if (result == (unsigned)-1) | 635 | if (result == INVBLOCK) |
608 | return 0; | 636 | return 0; |
609 | goal = ufs_dtogd (result); | 637 | goal = ufs_dtogd(uspi, result); |
610 | for (i = count; i < uspi->s_fpb; i++) | 638 | for (i = count; i < uspi->s_fpb; i++) |
611 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); | 639 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); |
612 | i = uspi->s_fpb - count; | 640 | i = uspi->s_fpb - count; |
@@ -620,7 +648,7 @@ cg_found: | |||
620 | } | 648 | } |
621 | 649 | ||
622 | result = ufs_bitmap_search (sb, ucpi, goal, allocsize); | 650 | result = ufs_bitmap_search (sb, ucpi, goal, allocsize); |
623 | if (result == (unsigned)-1) | 651 | if (result == INVBLOCK) |
624 | return 0; | 652 | return 0; |
625 | if(DQUOT_ALLOC_BLOCK(inode, count)) { | 653 | if(DQUOT_ALLOC_BLOCK(inode, count)) { |
626 | *err = -EDQUOT; | 654 | *err = -EDQUOT; |
@@ -647,20 +675,21 @@ succed: | |||
647 | sb->s_dirt = 1; | 675 | sb->s_dirt = 1; |
648 | 676 | ||
649 | result += cgno * uspi->s_fpg; | 677 | result += cgno * uspi->s_fpg; |
650 | UFSD("EXIT3, result %u\n", result); | 678 | UFSD("EXIT3, result %llu\n", (unsigned long long)result); |
651 | return result; | 679 | return result; |
652 | } | 680 | } |
653 | 681 | ||
654 | static unsigned ufs_alloccg_block (struct inode * inode, | 682 | static u64 ufs_alloccg_block(struct inode *inode, |
655 | struct ufs_cg_private_info * ucpi, unsigned goal, int * err) | 683 | struct ufs_cg_private_info *ucpi, |
684 | u64 goal, int *err) | ||
656 | { | 685 | { |
657 | struct super_block * sb; | 686 | struct super_block * sb; |
658 | struct ufs_sb_private_info * uspi; | 687 | struct ufs_sb_private_info * uspi; |
659 | struct ufs_super_block_first * usb1; | 688 | struct ufs_super_block_first * usb1; |
660 | struct ufs_cylinder_group * ucg; | 689 | struct ufs_cylinder_group * ucg; |
661 | unsigned result, cylno, blkno; | 690 | u64 result, blkno; |
662 | 691 | ||
663 | UFSD("ENTER, goal %u\n", goal); | 692 | UFSD("ENTER, goal %llu\n", (unsigned long long)goal); |
664 | 693 | ||
665 | sb = inode->i_sb; | 694 | sb = inode->i_sb; |
666 | uspi = UFS_SB(sb)->s_uspi; | 695 | uspi = UFS_SB(sb)->s_uspi; |
@@ -672,7 +701,7 @@ static unsigned ufs_alloccg_block (struct inode * inode, | |||
672 | goto norot; | 701 | goto norot; |
673 | } | 702 | } |
674 | goal = ufs_blknum (goal); | 703 | goal = ufs_blknum (goal); |
675 | goal = ufs_dtogd (goal); | 704 | goal = ufs_dtogd(uspi, goal); |
676 | 705 | ||
677 | /* | 706 | /* |
678 | * If the requested block is available, use it. | 707 | * If the requested block is available, use it. |
@@ -684,8 +713,8 @@ static unsigned ufs_alloccg_block (struct inode * inode, | |||
684 | 713 | ||
685 | norot: | 714 | norot: |
686 | result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb); | 715 | result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb); |
687 | if (result == (unsigned)-1) | 716 | if (result == INVBLOCK) |
688 | return (unsigned)-1; | 717 | return INVBLOCK; |
689 | ucpi->c_rotor = result; | 718 | ucpi->c_rotor = result; |
690 | gotit: | 719 | gotit: |
691 | blkno = ufs_fragstoblks(result); | 720 | blkno = ufs_fragstoblks(result); |
@@ -694,17 +723,22 @@ gotit: | |||
694 | ufs_clusteracct (sb, ucpi, blkno, -1); | 723 | ufs_clusteracct (sb, ucpi, blkno, -1); |
695 | if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) { | 724 | if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) { |
696 | *err = -EDQUOT; | 725 | *err = -EDQUOT; |
697 | return (unsigned)-1; | 726 | return INVBLOCK; |
698 | } | 727 | } |
699 | 728 | ||
700 | fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); | 729 | fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); |
701 | uspi->cs_total.cs_nbfree--; | 730 | uspi->cs_total.cs_nbfree--; |
702 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); | 731 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1); |
703 | cylno = ufs_cbtocylno(result); | 732 | |
704 | fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(result)), 1); | 733 | if (uspi->fs_magic != UFS2_MAGIC) { |
705 | fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1); | 734 | unsigned cylno = ufs_cbtocylno((unsigned)result); |
735 | |||
736 | fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, | ||
737 | ufs_cbtorpos((unsigned)result)), 1); | ||
738 | fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1); | ||
739 | } | ||
706 | 740 | ||
707 | UFSD("EXIT, result %u\n", result); | 741 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
708 | 742 | ||
709 | return result; | 743 | return result; |
710 | } | 744 | } |
@@ -744,9 +778,9 @@ static unsigned ubh_scanc(struct ufs_sb_private_info *uspi, | |||
744 | * @goal: near which block we want find new one | 778 | * @goal: near which block we want find new one |
745 | * @count: specified size | 779 | * @count: specified size |
746 | */ | 780 | */ |
747 | static unsigned ufs_bitmap_search(struct super_block *sb, | 781 | static u64 ufs_bitmap_search(struct super_block *sb, |
748 | struct ufs_cg_private_info *ucpi, | 782 | struct ufs_cg_private_info *ucpi, |
749 | unsigned goal, unsigned count) | 783 | u64 goal, unsigned count) |
750 | { | 784 | { |
751 | /* | 785 | /* |
752 | * Bit patterns for identifying fragments in the block map | 786 | * Bit patterns for identifying fragments in the block map |
@@ -761,16 +795,18 @@ static unsigned ufs_bitmap_search(struct super_block *sb, | |||
761 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 795 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
762 | struct ufs_super_block_first *usb1; | 796 | struct ufs_super_block_first *usb1; |
763 | struct ufs_cylinder_group *ucg; | 797 | struct ufs_cylinder_group *ucg; |
764 | unsigned start, length, loc, result; | 798 | unsigned start, length, loc; |
765 | unsigned pos, want, blockmap, mask, end; | 799 | unsigned pos, want, blockmap, mask, end; |
800 | u64 result; | ||
766 | 801 | ||
767 | UFSD("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count); | 802 | UFSD("ENTER, cg %u, goal %llu, count %u\n", ucpi->c_cgx, |
803 | (unsigned long long)goal, count); | ||
768 | 804 | ||
769 | usb1 = ubh_get_usb_first (uspi); | 805 | usb1 = ubh_get_usb_first (uspi); |
770 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); | 806 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
771 | 807 | ||
772 | if (goal) | 808 | if (goal) |
773 | start = ufs_dtogd(goal) >> 3; | 809 | start = ufs_dtogd(uspi, goal) >> 3; |
774 | else | 810 | else |
775 | start = ucpi->c_frotor >> 3; | 811 | start = ucpi->c_frotor >> 3; |
776 | 812 | ||
@@ -790,7 +826,7 @@ static unsigned ufs_bitmap_search(struct super_block *sb, | |||
790 | " length %u, count %u, freeoff %u\n", | 826 | " length %u, count %u, freeoff %u\n", |
791 | ucpi->c_cgx, start, length, count, | 827 | ucpi->c_cgx, start, length, count, |
792 | ucpi->c_freeoff); | 828 | ucpi->c_freeoff); |
793 | return (unsigned)-1; | 829 | return INVBLOCK; |
794 | } | 830 | } |
795 | start = 0; | 831 | start = 0; |
796 | } | 832 | } |
@@ -808,7 +844,8 @@ static unsigned ufs_bitmap_search(struct super_block *sb, | |||
808 | want = want_arr[count]; | 844 | want = want_arr[count]; |
809 | for (pos = 0; pos <= uspi->s_fpb - count; pos++) { | 845 | for (pos = 0; pos <= uspi->s_fpb - count; pos++) { |
810 | if ((blockmap & mask) == want) { | 846 | if ((blockmap & mask) == want) { |
811 | UFSD("EXIT, result %u\n", result); | 847 | UFSD("EXIT, result %llu\n", |
848 | (unsigned long long)result); | ||
812 | return result + pos; | 849 | return result + pos; |
813 | } | 850 | } |
814 | mask <<= 1; | 851 | mask <<= 1; |
@@ -819,7 +856,7 @@ static unsigned ufs_bitmap_search(struct super_block *sb, | |||
819 | ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u\n", | 856 | ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u\n", |
820 | ucpi->c_cgx); | 857 | ucpi->c_cgx); |
821 | UFSD("EXIT (FAILED)\n"); | 858 | UFSD("EXIT (FAILED)\n"); |
822 | return (unsigned)-1; | 859 | return INVBLOCK; |
823 | } | 860 | } |
824 | 861 | ||
825 | static void ufs_clusteracct(struct super_block * sb, | 862 | static void ufs_clusteracct(struct super_block * sb, |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index dd52eecdcb0f..fb34ad03e224 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -170,7 +170,7 @@ out: | |||
170 | * @locked_page - for ufs_new_fragments() | 170 | * @locked_page - for ufs_new_fragments() |
171 | */ | 171 | */ |
172 | static struct buffer_head * | 172 | static struct buffer_head * |
173 | ufs_inode_getfrag(struct inode *inode, unsigned int fragment, | 173 | ufs_inode_getfrag(struct inode *inode, u64 fragment, |
174 | sector_t new_fragment, unsigned int required, int *err, | 174 | sector_t new_fragment, unsigned int required, int *err, |
175 | long *phys, int *new, struct page *locked_page) | 175 | long *phys, int *new, struct page *locked_page) |
176 | { | 176 | { |
@@ -178,12 +178,12 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment, | |||
178 | struct super_block *sb = inode->i_sb; | 178 | struct super_block *sb = inode->i_sb; |
179 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 179 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
180 | struct buffer_head * result; | 180 | struct buffer_head * result; |
181 | unsigned block, blockoff, lastfrag, lastblock, lastblockoff; | 181 | unsigned blockoff, lastblockoff; |
182 | unsigned tmp, goal; | 182 | u64 tmp, goal, lastfrag, block, lastblock; |
183 | __fs32 * p, * p2; | 183 | void *p, *p2; |
184 | 184 | ||
185 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, required %u, " | 185 | UFSD("ENTER, ino %lu, fragment %llu, new_fragment %llu, required %u, " |
186 | "metadata %d\n", inode->i_ino, fragment, | 186 | "metadata %d\n", inode->i_ino, (unsigned long long)fragment, |
187 | (unsigned long long)new_fragment, required, !phys); | 187 | (unsigned long long)new_fragment, required, !phys); |
188 | 188 | ||
189 | /* TODO : to be done for write support | 189 | /* TODO : to be done for write support |
@@ -193,17 +193,20 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment, | |||
193 | 193 | ||
194 | block = ufs_fragstoblks (fragment); | 194 | block = ufs_fragstoblks (fragment); |
195 | blockoff = ufs_fragnum (fragment); | 195 | blockoff = ufs_fragnum (fragment); |
196 | p = ufsi->i_u1.i_data + block; | 196 | p = ufs_get_direct_data_ptr(uspi, ufsi, block); |
197 | |||
197 | goal = 0; | 198 | goal = 0; |
198 | 199 | ||
199 | repeat: | 200 | repeat: |
200 | tmp = fs32_to_cpu(sb, *p); | 201 | tmp = ufs_data_ptr_to_cpu(sb, p); |
202 | |||
201 | lastfrag = ufsi->i_lastfrag; | 203 | lastfrag = ufsi->i_lastfrag; |
202 | if (tmp && fragment < lastfrag) { | 204 | if (tmp && fragment < lastfrag) { |
203 | if (!phys) { | 205 | if (!phys) { |
204 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 206 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
205 | if (tmp == fs32_to_cpu(sb, *p)) { | 207 | if (tmp == ufs_data_ptr_to_cpu(sb, p)) { |
206 | UFSD("EXIT, result %u\n", tmp + blockoff); | 208 | UFSD("EXIT, result %llu\n", |
209 | (unsigned long long)tmp + blockoff); | ||
207 | return result; | 210 | return result; |
208 | } | 211 | } |
209 | brelse (result); | 212 | brelse (result); |
@@ -224,10 +227,11 @@ repeat: | |||
224 | * We must reallocate last allocated block | 227 | * We must reallocate last allocated block |
225 | */ | 228 | */ |
226 | if (lastblockoff) { | 229 | if (lastblockoff) { |
227 | p2 = ufsi->i_u1.i_data + lastblock; | 230 | p2 = ufs_get_direct_data_ptr(uspi, ufsi, lastblock); |
228 | tmp = ufs_new_fragments (inode, p2, lastfrag, | 231 | tmp = ufs_new_fragments(inode, p2, lastfrag, |
229 | fs32_to_cpu(sb, *p2), uspi->s_fpb - lastblockoff, | 232 | ufs_data_ptr_to_cpu(sb, p2), |
230 | err, locked_page); | 233 | uspi->s_fpb - lastblockoff, |
234 | err, locked_page); | ||
231 | if (!tmp) { | 235 | if (!tmp) { |
232 | if (lastfrag != ufsi->i_lastfrag) | 236 | if (lastfrag != ufsi->i_lastfrag) |
233 | goto repeat; | 237 | goto repeat; |
@@ -237,27 +241,31 @@ repeat: | |||
237 | lastfrag = ufsi->i_lastfrag; | 241 | lastfrag = ufsi->i_lastfrag; |
238 | 242 | ||
239 | } | 243 | } |
240 | tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]); | 244 | tmp = ufs_data_ptr_to_cpu(sb, |
245 | ufs_get_direct_data_ptr(uspi, ufsi, | ||
246 | lastblock)); | ||
241 | if (tmp) | 247 | if (tmp) |
242 | goal = tmp + uspi->s_fpb; | 248 | goal = tmp + uspi->s_fpb; |
243 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, | 249 | tmp = ufs_new_fragments (inode, p, fragment - blockoff, |
244 | goal, required + blockoff, | 250 | goal, required + blockoff, |
245 | err, | 251 | err, |
246 | phys != NULL ? locked_page : NULL); | 252 | phys != NULL ? locked_page : NULL); |
247 | } | 253 | } else if (lastblock == block) { |
248 | /* | 254 | /* |
249 | * We will extend last allocated block | 255 | * We will extend last allocated block |
250 | */ | 256 | */ |
251 | else if (lastblock == block) { | 257 | tmp = ufs_new_fragments(inode, p, fragment - |
252 | tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), | 258 | (blockoff - lastblockoff), |
253 | fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), | 259 | ufs_data_ptr_to_cpu(sb, p), |
260 | required + (blockoff - lastblockoff), | ||
254 | err, phys != NULL ? locked_page : NULL); | 261 | err, phys != NULL ? locked_page : NULL); |
255 | } else /* (lastblock > block) */ { | 262 | } else /* (lastblock > block) */ { |
256 | /* | 263 | /* |
257 | * We will allocate new block before last allocated block | 264 | * We will allocate new block before last allocated block |
258 | */ | 265 | */ |
259 | if (block) { | 266 | if (block) { |
260 | tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[block-1]); | 267 | tmp = ufs_data_ptr_to_cpu(sb, |
268 | ufs_get_direct_data_ptr(uspi, ufsi, block - 1)); | ||
261 | if (tmp) | 269 | if (tmp) |
262 | goal = tmp + uspi->s_fpb; | 270 | goal = tmp + uspi->s_fpb; |
263 | } | 271 | } |
@@ -266,7 +274,7 @@ repeat: | |||
266 | phys != NULL ? locked_page : NULL); | 274 | phys != NULL ? locked_page : NULL); |
267 | } | 275 | } |
268 | if (!tmp) { | 276 | if (!tmp) { |
269 | if ((!blockoff && *p) || | 277 | if ((!blockoff && ufs_data_ptr_to_cpu(sb, p)) || |
270 | (blockoff && lastfrag != ufsi->i_lastfrag)) | 278 | (blockoff && lastfrag != ufsi->i_lastfrag)) |
271 | goto repeat; | 279 | goto repeat; |
272 | *err = -ENOSPC; | 280 | *err = -ENOSPC; |
@@ -286,7 +294,7 @@ repeat: | |||
286 | if (IS_SYNC(inode)) | 294 | if (IS_SYNC(inode)) |
287 | ufs_sync_inode (inode); | 295 | ufs_sync_inode (inode); |
288 | mark_inode_dirty(inode); | 296 | mark_inode_dirty(inode); |
289 | UFSD("EXIT, result %u\n", tmp + blockoff); | 297 | UFSD("EXIT, result %llu\n", (unsigned long long)tmp + blockoff); |
290 | return result; | 298 | return result; |
291 | 299 | ||
292 | /* This part : To be implemented .... | 300 | /* This part : To be implemented .... |
@@ -320,20 +328,22 @@ repeat2: | |||
320 | */ | 328 | */ |
321 | static struct buffer_head * | 329 | static struct buffer_head * |
322 | ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, | 330 | ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, |
323 | unsigned int fragment, sector_t new_fragment, int *err, | 331 | u64 fragment, sector_t new_fragment, int *err, |
324 | long *phys, int *new, struct page *locked_page) | 332 | long *phys, int *new, struct page *locked_page) |
325 | { | 333 | { |
326 | struct super_block *sb = inode->i_sb; | 334 | struct super_block *sb = inode->i_sb; |
327 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 335 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
328 | struct buffer_head * result; | 336 | struct buffer_head * result; |
329 | unsigned tmp, goal, block, blockoff; | 337 | unsigned blockoff; |
330 | __fs32 * p; | 338 | u64 tmp, goal, block; |
339 | void *p; | ||
331 | 340 | ||
332 | block = ufs_fragstoblks (fragment); | 341 | block = ufs_fragstoblks (fragment); |
333 | blockoff = ufs_fragnum (fragment); | 342 | blockoff = ufs_fragnum (fragment); |
334 | 343 | ||
335 | UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, metadata %d\n", | 344 | UFSD("ENTER, ino %lu, fragment %llu, new_fragment %llu, metadata %d\n", |
336 | inode->i_ino, fragment, (unsigned long long)new_fragment, !phys); | 345 | inode->i_ino, (unsigned long long)fragment, |
346 | (unsigned long long)new_fragment, !phys); | ||
337 | 347 | ||
338 | result = NULL; | 348 | result = NULL; |
339 | if (!bh) | 349 | if (!bh) |
@@ -344,14 +354,16 @@ ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, | |||
344 | if (!buffer_uptodate(bh)) | 354 | if (!buffer_uptodate(bh)) |
345 | goto out; | 355 | goto out; |
346 | } | 356 | } |
347 | 357 | if (uspi->fs_magic == UFS2_MAGIC) | |
348 | p = (__fs32 *) bh->b_data + block; | 358 | p = (__fs64 *)bh->b_data + block; |
359 | else | ||
360 | p = (__fs32 *)bh->b_data + block; | ||
349 | repeat: | 361 | repeat: |
350 | tmp = fs32_to_cpu(sb, *p); | 362 | tmp = ufs_data_ptr_to_cpu(sb, p); |
351 | if (tmp) { | 363 | if (tmp) { |
352 | if (!phys) { | 364 | if (!phys) { |
353 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); | 365 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
354 | if (tmp == fs32_to_cpu(sb, *p)) | 366 | if (tmp == ufs_data_ptr_to_cpu(sb, p)) |
355 | goto out; | 367 | goto out; |
356 | brelse (result); | 368 | brelse (result); |
357 | goto repeat; | 369 | goto repeat; |
@@ -361,14 +373,16 @@ repeat: | |||
361 | } | 373 | } |
362 | } | 374 | } |
363 | 375 | ||
364 | if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1]))) | 376 | if (block && (uspi->fs_magic == UFS2_MAGIC ? |
377 | (tmp = fs64_to_cpu(sb, ((__fs64 *)bh->b_data)[block-1])) : | ||
378 | (tmp = fs32_to_cpu(sb, ((__fs32 *)bh->b_data)[block-1])))) | ||
365 | goal = tmp + uspi->s_fpb; | 379 | goal = tmp + uspi->s_fpb; |
366 | else | 380 | else |
367 | goal = bh->b_blocknr + uspi->s_fpb; | 381 | goal = bh->b_blocknr + uspi->s_fpb; |
368 | tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal, | 382 | tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal, |
369 | uspi->s_fpb, err, locked_page); | 383 | uspi->s_fpb, err, locked_page); |
370 | if (!tmp) { | 384 | if (!tmp) { |
371 | if (fs32_to_cpu(sb, *p)) | 385 | if (ufs_data_ptr_to_cpu(sb, p)) |
372 | goto repeat; | 386 | goto repeat; |
373 | goto out; | 387 | goto out; |
374 | } | 388 | } |
@@ -386,7 +400,7 @@ repeat: | |||
386 | sync_dirty_buffer(bh); | 400 | sync_dirty_buffer(bh); |
387 | inode->i_ctime = CURRENT_TIME_SEC; | 401 | inode->i_ctime = CURRENT_TIME_SEC; |
388 | mark_inode_dirty(inode); | 402 | mark_inode_dirty(inode); |
389 | UFSD("result %u\n", tmp + blockoff); | 403 | UFSD("result %llu\n", (unsigned long long)tmp + blockoff); |
390 | out: | 404 | out: |
391 | brelse (bh); | 405 | brelse (bh); |
392 | UFSD("EXIT\n"); | 406 | UFSD("EXIT\n"); |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 0437b0a6fe97..77ed77932aeb 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -30,8 +30,8 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Modified to avoid infinite loop on 2006 by | 33 | * Adoptation to use page cache and UFS2 write support by |
34 | * Evgeniy Dushistov <dushistov@mail.ru> | 34 | * Evgeniy Dushistov <dushistov@mail.ru>, 2006-2007 |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
@@ -63,13 +63,13 @@ | |||
63 | #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) | 63 | #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) |
64 | 64 | ||
65 | 65 | ||
66 | static int ufs_trunc_direct (struct inode * inode) | 66 | static int ufs_trunc_direct(struct inode *inode) |
67 | { | 67 | { |
68 | struct ufs_inode_info *ufsi = UFS_I(inode); | 68 | struct ufs_inode_info *ufsi = UFS_I(inode); |
69 | struct super_block * sb; | 69 | struct super_block * sb; |
70 | struct ufs_sb_private_info * uspi; | 70 | struct ufs_sb_private_info * uspi; |
71 | __fs32 * p; | 71 | void *p; |
72 | unsigned frag1, frag2, frag3, frag4, block1, block2; | 72 | u64 frag1, frag2, frag3, frag4, block1, block2; |
73 | unsigned frag_to_free, free_count; | 73 | unsigned frag_to_free, free_count; |
74 | unsigned i, tmp; | 74 | unsigned i, tmp; |
75 | int retry; | 75 | int retry; |
@@ -91,13 +91,16 @@ static int ufs_trunc_direct (struct inode * inode) | |||
91 | if (frag2 > frag3) { | 91 | if (frag2 > frag3) { |
92 | frag2 = frag4; | 92 | frag2 = frag4; |
93 | frag3 = frag4 = 0; | 93 | frag3 = frag4 = 0; |
94 | } | 94 | } else if (frag2 < frag3) { |
95 | else if (frag2 < frag3) { | ||
96 | block1 = ufs_fragstoblks (frag2); | 95 | block1 = ufs_fragstoblks (frag2); |
97 | block2 = ufs_fragstoblks (frag3); | 96 | block2 = ufs_fragstoblks (frag3); |
98 | } | 97 | } |
99 | 98 | ||
100 | UFSD("frag1 %u, frag2 %u, block1 %u, block2 %u, frag3 %u, frag4 %u\n", frag1, frag2, block1, block2, frag3, frag4); | 99 | UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu," |
100 | " frag4 %llu\n", | ||
101 | (unsigned long long)frag1, (unsigned long long)frag2, | ||
102 | (unsigned long long)block1, (unsigned long long)block2, | ||
103 | (unsigned long long)frag3, (unsigned long long)frag4); | ||
101 | 104 | ||
102 | if (frag1 >= frag2) | 105 | if (frag1 >= frag2) |
103 | goto next1; | 106 | goto next1; |
@@ -105,8 +108,8 @@ static int ufs_trunc_direct (struct inode * inode) | |||
105 | /* | 108 | /* |
106 | * Free first free fragments | 109 | * Free first free fragments |
107 | */ | 110 | */ |
108 | p = ufsi->i_u1.i_data + ufs_fragstoblks (frag1); | 111 | p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag1)); |
109 | tmp = fs32_to_cpu(sb, *p); | 112 | tmp = ufs_data_ptr_to_cpu(sb, p); |
110 | if (!tmp ) | 113 | if (!tmp ) |
111 | ufs_panic (sb, "ufs_trunc_direct", "internal error"); | 114 | ufs_panic (sb, "ufs_trunc_direct", "internal error"); |
112 | frag2 -= frag1; | 115 | frag2 -= frag1; |
@@ -121,12 +124,11 @@ next1: | |||
121 | * Free whole blocks | 124 | * Free whole blocks |
122 | */ | 125 | */ |
123 | for (i = block1 ; i < block2; i++) { | 126 | for (i = block1 ; i < block2; i++) { |
124 | p = ufsi->i_u1.i_data + i; | 127 | p = ufs_get_direct_data_ptr(uspi, ufsi, i); |
125 | tmp = fs32_to_cpu(sb, *p); | 128 | tmp = ufs_data_ptr_to_cpu(sb, p); |
126 | if (!tmp) | 129 | if (!tmp) |
127 | continue; | 130 | continue; |
128 | 131 | ufs_data_ptr_clear(uspi, p); | |
129 | *p = 0; | ||
130 | 132 | ||
131 | if (free_count == 0) { | 133 | if (free_count == 0) { |
132 | frag_to_free = tmp; | 134 | frag_to_free = tmp; |
@@ -150,13 +152,12 @@ next1: | |||
150 | /* | 152 | /* |
151 | * Free last free fragments | 153 | * Free last free fragments |
152 | */ | 154 | */ |
153 | p = ufsi->i_u1.i_data + ufs_fragstoblks (frag3); | 155 | p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag3)); |
154 | tmp = fs32_to_cpu(sb, *p); | 156 | tmp = ufs_data_ptr_to_cpu(sb, p); |
155 | if (!tmp ) | 157 | if (!tmp ) |
156 | ufs_panic(sb, "ufs_truncate_direct", "internal error"); | 158 | ufs_panic(sb, "ufs_truncate_direct", "internal error"); |
157 | frag4 = ufs_fragnum (frag4); | 159 | frag4 = ufs_fragnum (frag4); |
158 | 160 | ufs_data_ptr_clear(uspi, p); | |
159 | *p = 0; | ||
160 | 161 | ||
161 | ufs_free_fragments (inode, tmp, frag4); | 162 | ufs_free_fragments (inode, tmp, frag4); |
162 | mark_inode_dirty(inode); | 163 | mark_inode_dirty(inode); |
@@ -167,17 +168,20 @@ next1: | |||
167 | } | 168 | } |
168 | 169 | ||
169 | 170 | ||
170 | static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | 171 | static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p) |
171 | { | 172 | { |
172 | struct super_block * sb; | 173 | struct super_block * sb; |
173 | struct ufs_sb_private_info * uspi; | 174 | struct ufs_sb_private_info * uspi; |
174 | struct ufs_buffer_head * ind_ubh; | 175 | struct ufs_buffer_head * ind_ubh; |
175 | __fs32 * ind; | 176 | void *ind; |
176 | unsigned indirect_block, i, tmp; | 177 | u64 tmp, indirect_block, i, frag_to_free; |
177 | unsigned frag_to_free, free_count; | 178 | unsigned free_count; |
178 | int retry; | 179 | int retry; |
179 | 180 | ||
180 | UFSD("ENTER\n"); | 181 | UFSD("ENTER: ino %lu, offset %llu, p: %p\n", |
182 | inode->i_ino, (unsigned long long)offset, p); | ||
183 | |||
184 | BUG_ON(!p); | ||
181 | 185 | ||
182 | sb = inode->i_sb; | 186 | sb = inode->i_sb; |
183 | uspi = UFS_SB(sb)->s_uspi; | 187 | uspi = UFS_SB(sb)->s_uspi; |
@@ -186,27 +190,27 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
186 | free_count = 0; | 190 | free_count = 0; |
187 | retry = 0; | 191 | retry = 0; |
188 | 192 | ||
189 | tmp = fs32_to_cpu(sb, *p); | 193 | tmp = ufs_data_ptr_to_cpu(sb, p); |
190 | if (!tmp) | 194 | if (!tmp) |
191 | return 0; | 195 | return 0; |
192 | ind_ubh = ubh_bread(sb, tmp, uspi->s_bsize); | 196 | ind_ubh = ubh_bread(sb, tmp, uspi->s_bsize); |
193 | if (tmp != fs32_to_cpu(sb, *p)) { | 197 | if (tmp != ufs_data_ptr_to_cpu(sb, p)) { |
194 | ubh_brelse (ind_ubh); | 198 | ubh_brelse (ind_ubh); |
195 | return 1; | 199 | return 1; |
196 | } | 200 | } |
197 | if (!ind_ubh) { | 201 | if (!ind_ubh) { |
198 | *p = 0; | 202 | ufs_data_ptr_clear(uspi, p); |
199 | return 0; | 203 | return 0; |
200 | } | 204 | } |
201 | 205 | ||
202 | indirect_block = (DIRECT_BLOCK > offset) ? (DIRECT_BLOCK - offset) : 0; | 206 | indirect_block = (DIRECT_BLOCK > offset) ? (DIRECT_BLOCK - offset) : 0; |
203 | for (i = indirect_block; i < uspi->s_apb; i++) { | 207 | for (i = indirect_block; i < uspi->s_apb; i++) { |
204 | ind = ubh_get_addr32 (ind_ubh, i); | 208 | ind = ubh_get_data_ptr(uspi, ind_ubh, i); |
205 | tmp = fs32_to_cpu(sb, *ind); | 209 | tmp = ufs_data_ptr_to_cpu(sb, ind); |
206 | if (!tmp) | 210 | if (!tmp) |
207 | continue; | 211 | continue; |
208 | 212 | ||
209 | *ind = 0; | 213 | ufs_data_ptr_clear(uspi, ind); |
210 | ubh_mark_buffer_dirty(ind_ubh); | 214 | ubh_mark_buffer_dirty(ind_ubh); |
211 | if (free_count == 0) { | 215 | if (free_count == 0) { |
212 | frag_to_free = tmp; | 216 | frag_to_free = tmp; |
@@ -226,11 +230,12 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
226 | ufs_free_blocks (inode, frag_to_free, free_count); | 230 | ufs_free_blocks (inode, frag_to_free, free_count); |
227 | } | 231 | } |
228 | for (i = 0; i < uspi->s_apb; i++) | 232 | for (i = 0; i < uspi->s_apb; i++) |
229 | if (*ubh_get_addr32(ind_ubh,i)) | 233 | if (!ufs_is_data_ptr_zero(uspi, |
234 | ubh_get_data_ptr(uspi, ind_ubh, i))) | ||
230 | break; | 235 | break; |
231 | if (i >= uspi->s_apb) { | 236 | if (i >= uspi->s_apb) { |
232 | tmp = fs32_to_cpu(sb, *p); | 237 | tmp = ufs_data_ptr_to_cpu(sb, p); |
233 | *p = 0; | 238 | ufs_data_ptr_clear(uspi, p); |
234 | 239 | ||
235 | ufs_free_blocks (inode, tmp, uspi->s_fpb); | 240 | ufs_free_blocks (inode, tmp, uspi->s_fpb); |
236 | mark_inode_dirty(inode); | 241 | mark_inode_dirty(inode); |
@@ -248,13 +253,13 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
248 | return retry; | 253 | return retry; |
249 | } | 254 | } |
250 | 255 | ||
251 | static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) | 256 | static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) |
252 | { | 257 | { |
253 | struct super_block * sb; | 258 | struct super_block * sb; |
254 | struct ufs_sb_private_info * uspi; | 259 | struct ufs_sb_private_info * uspi; |
255 | struct ufs_buffer_head * dind_bh; | 260 | struct ufs_buffer_head *dind_bh; |
256 | unsigned i, tmp, dindirect_block; | 261 | u64 i, tmp, dindirect_block; |
257 | __fs32 * dind; | 262 | void *dind; |
258 | int retry = 0; | 263 | int retry = 0; |
259 | 264 | ||
260 | UFSD("ENTER\n"); | 265 | UFSD("ENTER\n"); |
@@ -266,22 +271,22 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) | |||
266 | ? ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0; | 271 | ? ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0; |
267 | retry = 0; | 272 | retry = 0; |
268 | 273 | ||
269 | tmp = fs32_to_cpu(sb, *p); | 274 | tmp = ufs_data_ptr_to_cpu(sb, p); |
270 | if (!tmp) | 275 | if (!tmp) |
271 | return 0; | 276 | return 0; |
272 | dind_bh = ubh_bread(sb, tmp, uspi->s_bsize); | 277 | dind_bh = ubh_bread(sb, tmp, uspi->s_bsize); |
273 | if (tmp != fs32_to_cpu(sb, *p)) { | 278 | if (tmp != ufs_data_ptr_to_cpu(sb, p)) { |
274 | ubh_brelse (dind_bh); | 279 | ubh_brelse (dind_bh); |
275 | return 1; | 280 | return 1; |
276 | } | 281 | } |
277 | if (!dind_bh) { | 282 | if (!dind_bh) { |
278 | *p = 0; | 283 | ufs_data_ptr_clear(uspi, p); |
279 | return 0; | 284 | return 0; |
280 | } | 285 | } |
281 | 286 | ||
282 | for (i = dindirect_block ; i < uspi->s_apb ; i++) { | 287 | for (i = dindirect_block ; i < uspi->s_apb ; i++) { |
283 | dind = ubh_get_addr32 (dind_bh, i); | 288 | dind = ubh_get_data_ptr(uspi, dind_bh, i); |
284 | tmp = fs32_to_cpu(sb, *dind); | 289 | tmp = ufs_data_ptr_to_cpu(sb, dind); |
285 | if (!tmp) | 290 | if (!tmp) |
286 | continue; | 291 | continue; |
287 | retry |= ufs_trunc_indirect (inode, offset + (i << uspi->s_apbshift), dind); | 292 | retry |= ufs_trunc_indirect (inode, offset + (i << uspi->s_apbshift), dind); |
@@ -289,11 +294,12 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) | |||
289 | } | 294 | } |
290 | 295 | ||
291 | for (i = 0; i < uspi->s_apb; i++) | 296 | for (i = 0; i < uspi->s_apb; i++) |
292 | if (*ubh_get_addr32 (dind_bh, i)) | 297 | if (!ufs_is_data_ptr_zero(uspi, |
298 | ubh_get_data_ptr(uspi, dind_bh, i))) | ||
293 | break; | 299 | break; |
294 | if (i >= uspi->s_apb) { | 300 | if (i >= uspi->s_apb) { |
295 | tmp = fs32_to_cpu(sb, *p); | 301 | tmp = ufs_data_ptr_to_cpu(sb, p); |
296 | *p = 0; | 302 | ufs_data_ptr_clear(uspi, p); |
297 | 303 | ||
298 | ufs_free_blocks(inode, tmp, uspi->s_fpb); | 304 | ufs_free_blocks(inode, tmp, uspi->s_fpb); |
299 | mark_inode_dirty(inode); | 305 | mark_inode_dirty(inode); |
@@ -311,34 +317,33 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) | |||
311 | return retry; | 317 | return retry; |
312 | } | 318 | } |
313 | 319 | ||
314 | static int ufs_trunc_tindirect (struct inode * inode) | 320 | static int ufs_trunc_tindirect(struct inode *inode) |
315 | { | 321 | { |
322 | struct super_block *sb = inode->i_sb; | ||
323 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | ||
316 | struct ufs_inode_info *ufsi = UFS_I(inode); | 324 | struct ufs_inode_info *ufsi = UFS_I(inode); |
317 | struct super_block * sb; | ||
318 | struct ufs_sb_private_info * uspi; | ||
319 | struct ufs_buffer_head * tind_bh; | 325 | struct ufs_buffer_head * tind_bh; |
320 | unsigned tindirect_block, tmp, i; | 326 | u64 tindirect_block, tmp, i; |
321 | __fs32 * tind, * p; | 327 | void *tind, *p; |
322 | int retry; | 328 | int retry; |
323 | 329 | ||
324 | UFSD("ENTER\n"); | 330 | UFSD("ENTER\n"); |
325 | 331 | ||
326 | sb = inode->i_sb; | ||
327 | uspi = UFS_SB(sb)->s_uspi; | ||
328 | retry = 0; | 332 | retry = 0; |
329 | 333 | ||
330 | tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb)) | 334 | tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb)) |
331 | ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0; | 335 | ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0; |
332 | p = ufsi->i_u1.i_data + UFS_TIND_BLOCK; | 336 | |
333 | if (!(tmp = fs32_to_cpu(sb, *p))) | 337 | p = ufs_get_direct_data_ptr(uspi, ufsi, UFS_TIND_BLOCK); |
338 | if (!(tmp = ufs_data_ptr_to_cpu(sb, p))) | ||
334 | return 0; | 339 | return 0; |
335 | tind_bh = ubh_bread (sb, tmp, uspi->s_bsize); | 340 | tind_bh = ubh_bread (sb, tmp, uspi->s_bsize); |
336 | if (tmp != fs32_to_cpu(sb, *p)) { | 341 | if (tmp != ufs_data_ptr_to_cpu(sb, p)) { |
337 | ubh_brelse (tind_bh); | 342 | ubh_brelse (tind_bh); |
338 | return 1; | 343 | return 1; |
339 | } | 344 | } |
340 | if (!tind_bh) { | 345 | if (!tind_bh) { |
341 | *p = 0; | 346 | ufs_data_ptr_clear(uspi, p); |
342 | return 0; | 347 | return 0; |
343 | } | 348 | } |
344 | 349 | ||
@@ -349,11 +354,12 @@ static int ufs_trunc_tindirect (struct inode * inode) | |||
349 | ubh_mark_buffer_dirty(tind_bh); | 354 | ubh_mark_buffer_dirty(tind_bh); |
350 | } | 355 | } |
351 | for (i = 0; i < uspi->s_apb; i++) | 356 | for (i = 0; i < uspi->s_apb; i++) |
352 | if (*ubh_get_addr32 (tind_bh, i)) | 357 | if (!ufs_is_data_ptr_zero(uspi, |
358 | ubh_get_data_ptr(uspi, tind_bh, i))) | ||
353 | break; | 359 | break; |
354 | if (i >= uspi->s_apb) { | 360 | if (i >= uspi->s_apb) { |
355 | tmp = fs32_to_cpu(sb, *p); | 361 | tmp = ufs_data_ptr_to_cpu(sb, p); |
356 | *p = 0; | 362 | ufs_data_ptr_clear(uspi, p); |
357 | 363 | ||
358 | ufs_free_blocks(inode, tmp, uspi->s_fpb); | 364 | ufs_free_blocks(inode, tmp, uspi->s_fpb); |
359 | mark_inode_dirty(inode); | 365 | mark_inode_dirty(inode); |
@@ -375,7 +381,8 @@ static int ufs_alloc_lastblock(struct inode *inode) | |||
375 | int err = 0; | 381 | int err = 0; |
376 | struct address_space *mapping = inode->i_mapping; | 382 | struct address_space *mapping = inode->i_mapping; |
377 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; | 383 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; |
378 | unsigned lastfrag, i, end; | 384 | unsigned i, end; |
385 | sector_t lastfrag; | ||
379 | struct page *lastpage; | 386 | struct page *lastpage; |
380 | struct buffer_head *bh; | 387 | struct buffer_head *bh; |
381 | 388 | ||
@@ -430,7 +437,9 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) | |||
430 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 437 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
431 | int retry, err = 0; | 438 | int retry, err = 0; |
432 | 439 | ||
433 | UFSD("ENTER\n"); | 440 | UFSD("ENTER: ino %lu, i_size: %llu, old_i_size: %llu\n", |
441 | inode->i_ino, (unsigned long long)i_size_read(inode), | ||
442 | (unsigned long long)old_i_size); | ||
434 | 443 | ||
435 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 444 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
436 | S_ISLNK(inode->i_mode))) | 445 | S_ISLNK(inode->i_mode))) |
@@ -450,10 +459,12 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) | |||
450 | lock_kernel(); | 459 | lock_kernel(); |
451 | while (1) { | 460 | while (1) { |
452 | retry = ufs_trunc_direct(inode); | 461 | retry = ufs_trunc_direct(inode); |
453 | retry |= ufs_trunc_indirect (inode, UFS_IND_BLOCK, | 462 | retry |= ufs_trunc_indirect(inode, UFS_IND_BLOCK, |
454 | (__fs32 *) &ufsi->i_u1.i_data[UFS_IND_BLOCK]); | 463 | ufs_get_direct_data_ptr(uspi, ufsi, |
455 | retry |= ufs_trunc_dindirect (inode, UFS_IND_BLOCK + uspi->s_apb, | 464 | UFS_IND_BLOCK)); |
456 | (__fs32 *) &ufsi->i_u1.i_data[UFS_DIND_BLOCK]); | 465 | retry |= ufs_trunc_dindirect(inode, UFS_IND_BLOCK + uspi->s_apb, |
466 | ufs_get_direct_data_ptr(uspi, ufsi, | ||
467 | UFS_DIND_BLOCK)); | ||
457 | retry |= ufs_trunc_tindirect (inode); | 468 | retry |= ufs_trunc_tindirect (inode); |
458 | if (!retry) | 469 | if (!retry) |
459 | break; | 470 | break; |
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 7dd12bb1d62b..06d344839c42 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
@@ -305,8 +305,22 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi, | |||
305 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ | 305 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ |
306 | ((begin) & ((uspi->s_fsize>>2) - 1))) | 306 | ((begin) & ((uspi->s_fsize>>2) - 1))) |
307 | 307 | ||
308 | #define ubh_get_addr64(ubh,begin) \ | ||
309 | (((__fs64*)((ubh)->bh[(begin) >> (uspi->s_fshift-3)]->b_data)) + \ | ||
310 | ((begin) & ((uspi->s_fsize>>3) - 1))) | ||
311 | |||
308 | #define ubh_get_addr ubh_get_addr8 | 312 | #define ubh_get_addr ubh_get_addr8 |
309 | 313 | ||
314 | static inline void *ubh_get_data_ptr(struct ufs_sb_private_info *uspi, | ||
315 | struct ufs_buffer_head *ubh, | ||
316 | u64 blk) | ||
317 | { | ||
318 | if (uspi->fs_magic == UFS2_MAGIC) | ||
319 | return ubh_get_addr64(ubh, blk); | ||
320 | else | ||
321 | return ubh_get_addr32(ubh, blk); | ||
322 | } | ||
323 | |||
310 | #define ubh_blkmap(ubh,begin,bit) \ | 324 | #define ubh_blkmap(ubh,begin,bit) \ |
311 | ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb))) | 325 | ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb))) |
312 | 326 | ||
@@ -507,3 +521,46 @@ static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap, | |||
507 | if (fragsize > 0 && fragsize < uspi->s_fpb) | 521 | if (fragsize > 0 && fragsize < uspi->s_fpb) |
508 | fs32_add(sb, &fraglist[fragsize], cnt); | 522 | fs32_add(sb, &fraglist[fragsize], cnt); |
509 | } | 523 | } |
524 | |||
525 | static inline void *ufs_get_direct_data_ptr(struct ufs_sb_private_info *uspi, | ||
526 | struct ufs_inode_info *ufsi, | ||
527 | unsigned blk) | ||
528 | { | ||
529 | BUG_ON(blk > UFS_TIND_BLOCK); | ||
530 | return uspi->fs_magic == UFS2_MAGIC ? | ||
531 | (void *)&ufsi->i_u1.u2_i_data[blk] : | ||
532 | (void *)&ufsi->i_u1.i_data[blk]; | ||
533 | } | ||
534 | |||
535 | static inline u64 ufs_data_ptr_to_cpu(struct super_block *sb, void *p) | ||
536 | { | ||
537 | return UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC ? | ||
538 | fs64_to_cpu(sb, *(__fs64 *)p) : | ||
539 | fs32_to_cpu(sb, *(__fs32 *)p); | ||
540 | } | ||
541 | |||
542 | static inline void ufs_cpu_to_data_ptr(struct super_block *sb, void *p, u64 val) | ||
543 | { | ||
544 | if (UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC) | ||
545 | *(__fs64 *)p = cpu_to_fs64(sb, val); | ||
546 | else | ||
547 | *(__fs32 *)p = cpu_to_fs32(sb, val); | ||
548 | } | ||
549 | |||
550 | static inline void ufs_data_ptr_clear(struct ufs_sb_private_info *uspi, | ||
551 | void *p) | ||
552 | { | ||
553 | if (uspi->fs_magic == UFS2_MAGIC) | ||
554 | *(__fs64 *)p = 0; | ||
555 | else | ||
556 | *(__fs32 *)p = 0; | ||
557 | } | ||
558 | |||
559 | static inline int ufs_is_data_ptr_zero(struct ufs_sb_private_info *uspi, | ||
560 | void *p) | ||
561 | { | ||
562 | if (uspi->fs_magic == UFS2_MAGIC) | ||
563 | return *(__fs64 *)p == 0; | ||
564 | else | ||
565 | return *(__fs32 *)p == 0; | ||
566 | } | ||