aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
authorEvgeniy Dushistov <dushistov@mail.ru>2007-02-12 03:54:32 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 12:48:40 -0500
commit54fb996ac15c4014fa4d6b0ec8e42da134204897 (patch)
treeee7a98270cabefc996a13691a7c9d63141a8d3a9 /fs/ufs
parent3313e29267414e4e3bf0d3de1caf9cb439b64aaf (diff)
[PATCH] ufs2 write: block allocation update
Patch adds ability to work with 64bit metadata, this made by replacing work with 32bit pointers by inline functions. Signed-off-by: Evgeniy Dushistov <dushistov@mail.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ufs')
-rw-r--r--fs/ufs/balloc.c197
-rw-r--r--fs/ufs/inode.c82
-rw-r--r--fs/ufs/truncate.c139
-rw-r--r--fs/ufs/util.h57
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
24static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *); 26#define INVBLOCK ((u64)-1L)
25static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *); 27
26static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *); 28static u64 ufs_add_fragments(struct inode *, u64, unsigned, unsigned, int *);
27static unsigned ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, unsigned, unsigned); 29static u64 ufs_alloc_fragments(struct inode *, unsigned, u64, unsigned, int *);
30static u64 ufs_alloccg_block(struct inode *, struct ufs_cg_private_info *, u64, int *);
31static u64 ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, u64, unsigned);
28static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[]; 32static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[];
29static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int); 33static 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 */
34void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count) 38void 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 */
130void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count) 140void 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
153do_more: 166do_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
311unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, 329u64 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
453static unsigned 479static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
454ufs_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
537static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno, 563static 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
654static unsigned ufs_alloccg_block (struct inode * inode, 682static 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
685norot: 714norot:
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;
690gotit: 719gotit:
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 */
747static unsigned ufs_bitmap_search(struct super_block *sb, 781static 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
825static void ufs_clusteracct(struct super_block * sb, 862static 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 */
172static struct buffer_head * 172static struct buffer_head *
173ufs_inode_getfrag(struct inode *inode, unsigned int fragment, 173ufs_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
199repeat: 200repeat:
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 */
321static struct buffer_head * 329static struct buffer_head *
322ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, 330ufs_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;
349repeat: 361repeat:
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);
390out: 404out:
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
66static int ufs_trunc_direct (struct inode * inode) 66static 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
170static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) 171static 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
251static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p) 256static 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
314static int ufs_trunc_tindirect (struct inode * inode) 320static 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
314static 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
525static 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
535static 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
542static 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
550static 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
559static 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}