[PATCH] ufs2 write: block allocation update
authorEvgeniy Dushistov <dushistov@mail.ru>
Mon, 12 Feb 2007 08:54:32 +0000 (00:54 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 12 Feb 2007 17:48:40 +0000 (09:48 -0800)
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>
fs/ufs/balloc.c
fs/ufs/inode.c
fs/ufs/truncate.c
fs/ufs/util.h
include/linux/ufs_fs.h
include/linux/ufs_fs_i.h

index 638f4c585e89a404f0bb87ee5ddea0bd2cf3fc9f..0e97a4f79c319ad7adfefca81629be2667170a42 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright (C) 1998
  * Daniel Pirkl <daniel.pirkl@email.cz>
  * Charles University, Faculty of Mathematics and Physics
+ *
+ * UFS2 write support Evgeniy Dushistov <dushistov@mail.ru>, 2007
  */
 
 #include <linux/fs.h>
 #include "swab.h"
 #include "util.h"
 
-static unsigned ufs_add_fragments (struct inode *, unsigned, unsigned, unsigned, int *);
-static unsigned ufs_alloc_fragments (struct inode *, unsigned, unsigned, unsigned, int *);
-static unsigned ufs_alloccg_block (struct inode *, struct ufs_cg_private_info *, unsigned, int *);
-static unsigned ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, unsigned, unsigned);
+#define INVBLOCK ((u64)-1L)
+
+static u64 ufs_add_fragments(struct inode *, u64, unsigned, unsigned, int *);
+static u64 ufs_alloc_fragments(struct inode *, unsigned, u64, unsigned, int *);
+static u64 ufs_alloccg_block(struct inode *, struct ufs_cg_private_info *, u64, int *);
+static u64 ufs_bitmap_search (struct super_block *, struct ufs_cg_private_info *, u64, unsigned);
 static unsigned char ufs_fragtable_8fpb[], ufs_fragtable_other[];
 static void ufs_clusteracct(struct super_block *, struct ufs_cg_private_info *, unsigned, int);
 
 /*
  * Free 'count' fragments from fragment number 'fragment'
  */
-void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count)
+void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
        struct ufs_cg_private_info * ucpi;
        struct ufs_cylinder_group * ucg;
-       unsigned cgno, bit, end_bit, bbase, blkmap, i, blkno, cylno;
+       unsigned cgno, bit, end_bit, bbase, blkmap, i;
+       u64 blkno;
        
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
        usb1 = ubh_get_usb_first(uspi);
        
-       UFSD("ENTER, fragment %u, count %u\n", fragment, count);
+       UFSD("ENTER, fragment %llu, count %u\n",
+            (unsigned long long)fragment, count);
        
        if (ufs_fragnum(fragment) + count > uspi->s_fpg)
                ufs_error (sb, "ufs_free_fragments", "internal error");
        
        lock_super(sb);
        
-       cgno = ufs_dtog(fragment);
-       bit = ufs_dtogd(fragment);
+       cgno = ufs_dtog(uspi, fragment);
+       bit = ufs_dtogd(uspi, fragment);
        if (cgno >= uspi->s_ncg) {
                ufs_panic (sb, "ufs_free_fragments", "freeing blocks are outside device");
                goto failed;
@@ -101,9 +107,13 @@ void ufs_free_fragments(struct inode *inode, unsigned fragment, unsigned count)
                fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
                uspi->cs_total.cs_nbfree++;
                fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1);
-               cylno = ufs_cbtocylno (bbase);
-               fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(bbase)), 1);
-               fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+               if (uspi->fs_magic != UFS2_MAGIC) {
+                       unsigned cylno = ufs_cbtocylno (bbase);
+
+                       fs16_add(sb, &ubh_cg_blks(ucpi, cylno,
+                                                 ufs_cbtorpos(bbase)), 1);
+                       fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+               }
        }
        
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
@@ -127,24 +137,27 @@ failed:
 /*
  * Free 'count' fragments from fragment number 'fragment' (free whole blocks)
  */
-void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count)
+void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
        struct ufs_cg_private_info * ucpi;
        struct ufs_cylinder_group * ucg;
-       unsigned overflow, cgno, bit, end_bit, blkno, i, cylno;
+       unsigned overflow, cgno, bit, end_bit, i;
+       u64 blkno;
        
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
        usb1 = ubh_get_usb_first(uspi);
 
-       UFSD("ENTER, fragment %u, count %u\n", fragment, count);
+       UFSD("ENTER, fragment %llu, count %u\n",
+            (unsigned long long)fragment, count);
        
        if ((fragment & uspi->s_fpbmask) || (count & uspi->s_fpbmask)) {
                ufs_error (sb, "ufs_free_blocks", "internal error, "
-                       "fragment %u, count %u\n", fragment, count);
+                          "fragment %llu, count %u\n",
+                          (unsigned long long)fragment, count);
                goto failed;
        }
 
@@ -152,8 +165,8 @@ void ufs_free_blocks(struct inode *inode, unsigned fragment, unsigned count)
        
 do_more:
        overflow = 0;
-       cgno = ufs_dtog (fragment);
-       bit = ufs_dtogd (fragment);
+       cgno = ufs_dtog(uspi, fragment);
+       bit = ufs_dtogd(uspi, fragment);
        if (cgno >= uspi->s_ncg) {
                ufs_panic (sb, "ufs_free_blocks", "freeing blocks are outside device");
                goto failed_unlock;
@@ -187,9 +200,14 @@ do_more:
                fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
                uspi->cs_total.cs_nbfree++;
                fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nbfree, 1);
-               cylno = ufs_cbtocylno(i);
-               fs16_add(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(i)), 1);
-               fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+
+               if (uspi->fs_magic != UFS2_MAGIC) {
+                       unsigned cylno = ufs_cbtocylno(i);
+
+                       fs16_add(sb, &ubh_cg_blks(ucpi, cylno,
+                                                 ufs_cbtorpos(i)), 1);
+                       fs32_add(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+               }
        }
 
        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,
        }
 }
 
-unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
-                          unsigned goal, unsigned count, int * err, struct page *locked_page)
+u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
+                          u64 goal, unsigned count, int *err,
+                          struct page *locked_page)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
-       unsigned cgno, oldcount, newcount, tmp, request, result;
+       unsigned cgno, oldcount, newcount;
+       u64 tmp, request, result;
        
-       UFSD("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count);
+       UFSD("ENTER, ino %lu, fragment %llu, goal %llu, count %u\n",
+            inode->i_ino, (unsigned long long)fragment,
+            (unsigned long long)goal, count);
        
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
@@ -324,11 +346,12 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
        *err = -ENOSPC;
 
        lock_super (sb);
-       
-       tmp = fs32_to_cpu(sb, *p);
+       tmp = ufs_data_ptr_to_cpu(sb, p);
+
        if (count + ufs_fragnum(fragment) > uspi->s_fpb) {
-               ufs_warning (sb, "ufs_new_fragments", "internal warning"
-                       " fragment %u, count %u", fragment, count);
+               ufs_warning(sb, "ufs_new_fragments", "internal warning"
+                           " fragment %llu, count %u",
+                           (unsigned long long)fragment, count);
                count = uspi->s_fpb - ufs_fragnum(fragment); 
        }
        oldcount = ufs_fragnum (fragment);
@@ -339,10 +362,12 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
         */
        if (oldcount) {
                if (!tmp) {
-                       ufs_error (sb, "ufs_new_fragments", "internal error, "
-                               "fragment %u, tmp %u\n", fragment, tmp);
-                       unlock_super (sb);
-                       return (unsigned)-1;
+                       ufs_error(sb, "ufs_new_fragments", "internal error, "
+                                 "fragment %llu, tmp %llu\n",
+                                 (unsigned long long)fragment,
+                                 (unsigned long long)tmp);
+                       unlock_super(sb);
+                       return INVBLOCK;
                }
                if (fragment < UFS_I(inode)->i_lastfrag) {
                        UFSD("EXIT (ALREADY ALLOCATED)\n");
@@ -372,7 +397,7 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
        if (goal == 0) 
                cgno = ufs_inotocg (inode->i_ino);
        else
-               cgno = ufs_dtog (goal);
+               cgno = ufs_dtog(uspi, goal);
         
        /*
         * allocate new fragment
@@ -380,14 +405,16 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
        if (oldcount == 0) {
                result = ufs_alloc_fragments (inode, cgno, goal, count, err);
                if (result) {
-                       *p = cpu_to_fs32(sb, result);
+                       ufs_cpu_to_data_ptr(sb, p, result);
                        *err = 0;
-                       UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
-                       ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
-                                       locked_page != NULL);
+                       UFS_I(inode)->i_lastfrag =
+                               max_t(u32, UFS_I(inode)->i_lastfrag,
+                                     fragment + count);
+                       ufs_clear_frags(inode, result + oldcount,
+                                       newcount - oldcount, locked_page != NULL);
                }
                unlock_super(sb);
-               UFSD("EXIT, result %u\n", result);
+               UFSD("EXIT, result %llu\n", (unsigned long long)result);
                return result;
        }
 
@@ -401,7 +428,7 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
                ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
                                locked_page != NULL);
                unlock_super(sb);
-               UFSD("EXIT, result %u\n", result);
+               UFSD("EXIT, result %llu\n", (unsigned long long)result);
                return result;
        }
 
@@ -433,15 +460,14 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
                                locked_page != NULL);
                ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp,
                                   result, locked_page);
-
-               *p = cpu_to_fs32(sb, result);
+               ufs_cpu_to_data_ptr(sb, p, result);
                *err = 0;
                UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
                unlock_super(sb);
                if (newcount < request)
                        ufs_free_fragments (inode, result + newcount, request - newcount);
                ufs_free_fragments (inode, tmp, oldcount);
-               UFSD("EXIT, result %u\n", result);
+               UFSD("EXIT, result %llu\n", (unsigned long long)result);
                return result;
        }
 
@@ -450,9 +476,8 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
        return 0;
 }              
 
-static unsigned
-ufs_add_fragments (struct inode * inode, unsigned fragment,
-                  unsigned oldcount, unsigned newcount, int * err)
+static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
+                            unsigned oldcount, unsigned newcount, int *err)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
@@ -461,14 +486,15 @@ ufs_add_fragments (struct inode * inode, unsigned fragment,
        struct ufs_cylinder_group * ucg;
        unsigned cgno, fragno, fragoff, count, fragsize, i;
        
-       UFSD("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount);
+       UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n",
+            (unsigned long long)fragment, oldcount, newcount);
        
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
        usb1 = ubh_get_usb_first (uspi);
        count = newcount - oldcount;
        
-       cgno = ufs_dtog(fragment);
+       cgno = ufs_dtog(uspi, fragment);
        if (fs32_to_cpu(sb, UFS_SB(sb)->fs_cs(cgno).cs_nffree) < count)
                return 0;
        if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb)
@@ -483,7 +509,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment,
                return 0;
        }
 
-       fragno = ufs_dtogd (fragment);
+       fragno = ufs_dtogd(uspi, fragment);
        fragoff = ufs_fragnum (fragno);
        for (i = oldcount; i < newcount; i++)
                if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i))
@@ -521,7 +547,7 @@ ufs_add_fragments (struct inode * inode, unsigned fragment,
        }
        sb->s_dirt = 1;
 
-       UFSD("EXIT, fragment %u\n", fragment);
+       UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment);
        
        return fragment;
 }
@@ -534,17 +560,19 @@ ufs_add_fragments (struct inode * inode, unsigned fragment,
                if (fs32_to_cpu(sb, ucg->cg_frsum[k])) \
                        goto cg_found; 
 
-static unsigned ufs_alloc_fragments (struct inode * inode, unsigned cgno,
-       unsigned goal, unsigned count, int * err)
+static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno,
+                              u64 goal, unsigned count, int *err)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
        struct ufs_cg_private_info * ucpi;
        struct ufs_cylinder_group * ucg;
-       unsigned oldcg, i, j, k, result, allocsize;
+       unsigned oldcg, i, j, k, allocsize;
+       u64 result;
        
-       UFSD("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count);
+       UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n",
+            inode->i_ino, cgno, (unsigned long long)goal, count);
 
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
@@ -593,7 +621,7 @@ cg_found:
 
        if (count == uspi->s_fpb) {
                result = ufs_alloccg_block (inode, ucpi, goal, err);
-               if (result == (unsigned)-1)
+               if (result == INVBLOCK)
                        return 0;
                goto succed;
        }
@@ -604,9 +632,9 @@ cg_found:
        
        if (allocsize == uspi->s_fpb) {
                result = ufs_alloccg_block (inode, ucpi, goal, err);
-               if (result == (unsigned)-1)
+               if (result == INVBLOCK)
                        return 0;
-               goal = ufs_dtogd (result);
+               goal = ufs_dtogd(uspi, result);
                for (i = count; i < uspi->s_fpb; i++)
                        ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i);
                i = uspi->s_fpb - count;
@@ -620,7 +648,7 @@ cg_found:
        }
 
        result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
-       if (result == (unsigned)-1)
+       if (result == INVBLOCK)
                return 0;
        if(DQUOT_ALLOC_BLOCK(inode, count)) {
                *err = -EDQUOT;
@@ -647,20 +675,21 @@ succed:
        sb->s_dirt = 1;
 
        result += cgno * uspi->s_fpg;
-       UFSD("EXIT3, result %u\n", result);
+       UFSD("EXIT3, result %llu\n", (unsigned long long)result);
        return result;
 }
 
-static unsigned ufs_alloccg_block (struct inode * inode,
-       struct ufs_cg_private_info * ucpi, unsigned goal, int * err)
+static u64 ufs_alloccg_block(struct inode *inode,
+                            struct ufs_cg_private_info *ucpi,
+                            u64 goal, int *err)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
        struct ufs_cylinder_group * ucg;
-       unsigned result, cylno, blkno;
+       u64 result, blkno;
 
-       UFSD("ENTER, goal %u\n", goal);
+       UFSD("ENTER, goal %llu\n", (unsigned long long)goal);
 
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
@@ -672,7 +701,7 @@ static unsigned ufs_alloccg_block (struct inode * inode,
                goto norot;
        }
        goal = ufs_blknum (goal);
-       goal = ufs_dtogd (goal);
+       goal = ufs_dtogd(uspi, goal);
        
        /*
         * If the requested block is available, use it.
@@ -684,8 +713,8 @@ static unsigned ufs_alloccg_block (struct inode * inode,
        
 norot: 
        result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb);
-       if (result == (unsigned)-1)
-               return (unsigned)-1;
+       if (result == INVBLOCK)
+               return INVBLOCK;
        ucpi->c_rotor = result;
 gotit:
        blkno = ufs_fragstoblks(result);
@@ -694,17 +723,22 @@ gotit:
                ufs_clusteracct (sb, ucpi, blkno, -1);
        if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) {
                *err = -EDQUOT;
-               return (unsigned)-1;
+               return INVBLOCK;
        }
 
        fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1);
        uspi->cs_total.cs_nbfree--;
        fs32_sub(sb, &UFS_SB(sb)->fs_cs(ucpi->c_cgx).cs_nbfree, 1);
-       cylno = ufs_cbtocylno(result);
-       fs16_sub(sb, &ubh_cg_blks(ucpi, cylno, ufs_cbtorpos(result)), 1);
-       fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+
+       if (uspi->fs_magic != UFS2_MAGIC) {
+               unsigned cylno = ufs_cbtocylno((unsigned)result);
+
+               fs16_sub(sb, &ubh_cg_blks(ucpi, cylno,
+                                         ufs_cbtorpos((unsigned)result)), 1);
+               fs32_sub(sb, &ubh_cg_blktot(ucpi, cylno), 1);
+       }
        
-       UFSD("EXIT, result %u\n", result);
+       UFSD("EXIT, result %llu\n", (unsigned long long)result);
 
        return result;
 }
@@ -744,9 +778,9 @@ static unsigned ubh_scanc(struct ufs_sb_private_info *uspi,
  * @goal: near which block we want find new one
  * @count: specified size
  */
-static unsigned ufs_bitmap_search(struct super_block *sb,
-                                 struct ufs_cg_private_info *ucpi,
-                                 unsigned goal, unsigned count)
+static u64 ufs_bitmap_search(struct super_block *sb,
+                            struct ufs_cg_private_info *ucpi,
+                            u64 goal, unsigned count)
 {
        /*
         * Bit patterns for identifying fragments in the block map
@@ -761,16 +795,18 @@ static unsigned ufs_bitmap_search(struct super_block *sb,
        struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        struct ufs_super_block_first *usb1;
        struct ufs_cylinder_group *ucg;
-       unsigned start, length, loc, result;
+       unsigned start, length, loc;
        unsigned pos, want, blockmap, mask, end;
+       u64 result;
 
-       UFSD("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count);
+       UFSD("ENTER, cg %u, goal %llu, count %u\n", ucpi->c_cgx,
+            (unsigned long long)goal, count);
 
        usb1 = ubh_get_usb_first (uspi);
        ucg = ubh_get_ucg(UCPI_UBH(ucpi));
 
        if (goal)
-               start = ufs_dtogd(goal) >> 3;
+               start = ufs_dtogd(uspi, goal) >> 3;
        else
                start = ucpi->c_frotor >> 3;
                
@@ -790,7 +826,7 @@ static unsigned ufs_bitmap_search(struct super_block *sb,
                                  " length %u, count %u, freeoff %u\n",
                                  ucpi->c_cgx, start, length, count,
                                  ucpi->c_freeoff);
-                       return (unsigned)-1;
+                       return INVBLOCK;
                }
                start = 0;
        }
@@ -808,7 +844,8 @@ static unsigned ufs_bitmap_search(struct super_block *sb,
                want = want_arr[count];
                for (pos = 0; pos <= uspi->s_fpb - count; pos++) {
                        if ((blockmap & mask) == want) {
-                               UFSD("EXIT, result %u\n", result);
+                               UFSD("EXIT, result %llu\n",
+                                    (unsigned long long)result);
                                return result + pos;
                        }
                        mask <<= 1;
@@ -819,7 +856,7 @@ static unsigned ufs_bitmap_search(struct super_block *sb,
        ufs_error(sb, "ufs_bitmap_search", "block not in map on cg %u\n",
                  ucpi->c_cgx);
        UFSD("EXIT (FAILED)\n");
-       return (unsigned)-1;
+       return INVBLOCK;
 }
 
 static void ufs_clusteracct(struct super_block * sb,
index dd52eecdcb0f5a474bd78d013169347852ebf75f..fb34ad03e22404af08871ea66267c7df1542e636 100644 (file)
@@ -170,7 +170,7 @@ out:
  * @locked_page - for ufs_new_fragments()
  */
 static struct buffer_head *
-ufs_inode_getfrag(struct inode *inode, unsigned int fragment,
+ufs_inode_getfrag(struct inode *inode, u64 fragment,
                  sector_t new_fragment, unsigned int required, int *err,
                  long *phys, int *new, struct page *locked_page)
 {
@@ -178,12 +178,12 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment,
        struct super_block *sb = inode->i_sb;
        struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        struct buffer_head * result;
-       unsigned block, blockoff, lastfrag, lastblock, lastblockoff;
-       unsigned tmp, goal;
-       __fs32 * p, * p2;
+       unsigned blockoff, lastblockoff;
+       u64 tmp, goal, lastfrag, block, lastblock;
+       void *p, *p2;
 
-       UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, required %u, "
-            "metadata %d\n", inode->i_ino, fragment,
+       UFSD("ENTER, ino %lu, fragment %llu, new_fragment %llu, required %u, "
+            "metadata %d\n", inode->i_ino, (unsigned long long)fragment,
             (unsigned long long)new_fragment, required, !phys);
 
         /* TODO : to be done for write support
@@ -193,17 +193,20 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment,
 
        block = ufs_fragstoblks (fragment);
        blockoff = ufs_fragnum (fragment);
-       p = ufsi->i_u1.i_data + block;
+       p = ufs_get_direct_data_ptr(uspi, ufsi, block);
+
        goal = 0;
 
 repeat:
-       tmp = fs32_to_cpu(sb, *p);
+       tmp = ufs_data_ptr_to_cpu(sb, p);
+
        lastfrag = ufsi->i_lastfrag;
        if (tmp && fragment < lastfrag) {
                if (!phys) {
                        result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff);
-                       if (tmp == fs32_to_cpu(sb, *p)) {
-                               UFSD("EXIT, result %u\n", tmp + blockoff);
+                       if (tmp == ufs_data_ptr_to_cpu(sb, p)) {
+                               UFSD("EXIT, result %llu\n",
+                                    (unsigned long long)tmp + blockoff);
                                return result;
                        }
                        brelse (result);
@@ -224,10 +227,11 @@ repeat:
                 * We must reallocate last allocated block
                 */
                if (lastblockoff) {
-                       p2 = ufsi->i_u1.i_data + lastblock;
-                       tmp = ufs_new_fragments (inode, p2, lastfrag, 
-                                                fs32_to_cpu(sb, *p2), uspi->s_fpb - lastblockoff,
-                                                err, locked_page);
+                       p2 = ufs_get_direct_data_ptr(uspi, ufsi, lastblock);
+                       tmp = ufs_new_fragments(inode, p2, lastfrag,
+                                               ufs_data_ptr_to_cpu(sb, p2),
+                                               uspi->s_fpb - lastblockoff,
+                                               err, locked_page);
                        if (!tmp) {
                                if (lastfrag != ufsi->i_lastfrag)
                                        goto repeat;
@@ -237,27 +241,31 @@ repeat:
                        lastfrag = ufsi->i_lastfrag;
                        
                }
-               tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]);
+               tmp = ufs_data_ptr_to_cpu(sb,
+                                        ufs_get_direct_data_ptr(uspi, ufsi,
+                                                                lastblock));
                if (tmp)
                        goal = tmp + uspi->s_fpb;
                tmp = ufs_new_fragments (inode, p, fragment - blockoff, 
                                         goal, required + blockoff,
                                         err,
                                         phys != NULL ? locked_page : NULL);
-       }
+       } else if (lastblock == block) {
        /*
         * We will extend last allocated block
         */
-       else if (lastblock == block) {
-               tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff),
-                                       fs32_to_cpu(sb, *p), required +  (blockoff - lastblockoff),
+               tmp = ufs_new_fragments(inode, p, fragment -
+                                       (blockoff - lastblockoff),
+                                       ufs_data_ptr_to_cpu(sb, p),
+                                       required +  (blockoff - lastblockoff),
                                        err, phys != NULL ? locked_page : NULL);
        } else /* (lastblock > block) */ {
        /*
         * We will allocate new block before last allocated block
         */
                if (block) {
-                       tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[block-1]);
+                       tmp = ufs_data_ptr_to_cpu(sb,
+                                                ufs_get_direct_data_ptr(uspi, ufsi, block - 1));
                        if (tmp)
                                goal = tmp + uspi->s_fpb;
                }
@@ -266,7 +274,7 @@ repeat:
                                        phys != NULL ? locked_page : NULL);
        }
        if (!tmp) {
-               if ((!blockoff && *p) || 
+               if ((!blockoff && ufs_data_ptr_to_cpu(sb, p)) ||
                    (blockoff && lastfrag != ufsi->i_lastfrag))
                        goto repeat;
                *err = -ENOSPC;
@@ -286,7 +294,7 @@ repeat:
        if (IS_SYNC(inode))
                ufs_sync_inode (inode);
        mark_inode_dirty(inode);
-       UFSD("EXIT, result %u\n", tmp + blockoff);
+       UFSD("EXIT, result %llu\n", (unsigned long long)tmp + blockoff);
        return result;
 
      /* This part : To be implemented ....
@@ -320,20 +328,22 @@ repeat2:
  */
 static struct buffer_head *
 ufs_inode_getblock(struct inode *inode, struct buffer_head *bh,
-                 unsigned int fragment, sector_t new_fragment, int *err,
+                 u64 fragment, sector_t new_fragment, int *err,
                  long *phys, int *new, struct page *locked_page)
 {
        struct super_block *sb = inode->i_sb;
        struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        struct buffer_head * result;
-       unsigned tmp, goal, block, blockoff;
-       __fs32 * p;
+       unsigned blockoff;
+       u64 tmp, goal, block;
+       void *p;
 
        block = ufs_fragstoblks (fragment);
        blockoff = ufs_fragnum (fragment);
 
-       UFSD("ENTER, ino %lu, fragment %u, new_fragment %llu, metadata %d\n",
-            inode->i_ino, fragment, (unsigned long long)new_fragment, !phys);
+       UFSD("ENTER, ino %lu, fragment %llu, new_fragment %llu, metadata %d\n",
+            inode->i_ino, (unsigned long long)fragment,
+            (unsigned long long)new_fragment, !phys);
 
        result = NULL;
        if (!bh)
@@ -344,14 +354,16 @@ ufs_inode_getblock(struct inode *inode, struct buffer_head *bh,
                if (!buffer_uptodate(bh))
                        goto out;
        }
-
-       p = (__fs32 *) bh->b_data + block;
+       if (uspi->fs_magic == UFS2_MAGIC)
+               p = (__fs64 *)bh->b_data + block;
+       else
+               p = (__fs32 *)bh->b_data + block;
 repeat:
-       tmp = fs32_to_cpu(sb, *p);
+       tmp = ufs_data_ptr_to_cpu(sb, p);
        if (tmp) {
                if (!phys) {
                        result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff);
-                       if (tmp == fs32_to_cpu(sb, *p))
+                       if (tmp == ufs_data_ptr_to_cpu(sb, p))
                                goto out;
                        brelse (result);
                        goto repeat;
@@ -361,14 +373,16 @@ repeat:
                }
        }
 
-       if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1])))
+       if (block && (uspi->fs_magic == UFS2_MAGIC ?
+                     (tmp = fs64_to_cpu(sb, ((__fs64 *)bh->b_data)[block-1])) :
+                     (tmp = fs32_to_cpu(sb, ((__fs32 *)bh->b_data)[block-1]))))
                goal = tmp + uspi->s_fpb;
        else
                goal = bh->b_blocknr + uspi->s_fpb;
        tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), goal,
                                uspi->s_fpb, err, locked_page);
        if (!tmp) {
-               if (fs32_to_cpu(sb, *p))
+               if (ufs_data_ptr_to_cpu(sb, p))
                        goto repeat;
                goto out;
        }               
@@ -386,7 +400,7 @@ repeat:
                sync_dirty_buffer(bh);
        inode->i_ctime = CURRENT_TIME_SEC;
        mark_inode_dirty(inode);
-       UFSD("result %u\n", tmp + blockoff);
+       UFSD("result %llu\n", (unsigned long long)tmp + blockoff);
 out:
        brelse (bh);
        UFSD("EXIT\n");
index 0437b0a6fe97f5ea9c5096f1a43ed4f554c4b475..77ed77932aebc086533fc0f1898f711e12347ae4 100644 (file)
@@ -30,8 +30,8 @@
  */
 
 /*
- * Modified to avoid infinite loop on 2006 by
- * Evgeniy Dushistov <dushistov@mail.ru>
+ * Adoptation to use page cache and UFS2 write support by
+ * Evgeniy Dushistov <dushistov@mail.ru>, 2006-2007
  */
 
 #include <linux/errno.h>
 #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
 
 
-static int ufs_trunc_direct (struct inode * inode)
+static int ufs_trunc_direct(struct inode *inode)
 {
        struct ufs_inode_info *ufsi = UFS_I(inode);
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
-       __fs32 * p;
-       unsigned frag1, frag2, frag3, frag4, block1, block2;
+       void *p;
+       u64 frag1, frag2, frag3, frag4, block1, block2;
        unsigned frag_to_free, free_count;
        unsigned i, tmp;
        int retry;
@@ -91,13 +91,16 @@ static int ufs_trunc_direct (struct inode * inode)
        if (frag2 > frag3) {
                frag2 = frag4;
                frag3 = frag4 = 0;
-       }
-       else if (frag2 < frag3) {
+       } else if (frag2 < frag3) {
                block1 = ufs_fragstoblks (frag2);
                block2 = ufs_fragstoblks (frag3);
        }
 
-       UFSD("frag1 %u, frag2 %u, block1 %u, block2 %u, frag3 %u, frag4 %u\n", frag1, frag2, block1, block2, frag3, frag4);
+       UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu,"
+            " frag4 %llu\n",
+            (unsigned long long)frag1, (unsigned long long)frag2,
+            (unsigned long long)block1, (unsigned long long)block2,
+            (unsigned long long)frag3, (unsigned long long)frag4);
 
        if (frag1 >= frag2)
                goto next1;             
@@ -105,8 +108,8 @@ static int ufs_trunc_direct (struct inode * inode)
        /*
         * Free first free fragments
         */
-       p = ufsi->i_u1.i_data + ufs_fragstoblks (frag1);
-       tmp = fs32_to_cpu(sb, *p);
+       p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag1));
+       tmp = ufs_data_ptr_to_cpu(sb, p);
        if (!tmp )
                ufs_panic (sb, "ufs_trunc_direct", "internal error");
        frag2 -= frag1;
@@ -121,12 +124,11 @@ next1:
         * Free whole blocks
         */
        for (i = block1 ; i < block2; i++) {
-               p = ufsi->i_u1.i_data + i;
-               tmp = fs32_to_cpu(sb, *p);
+               p = ufs_get_direct_data_ptr(uspi, ufsi, i);
+               tmp = ufs_data_ptr_to_cpu(sb, p);
                if (!tmp)
                        continue;
-
-               *p = 0;
+               ufs_data_ptr_clear(uspi, p);
 
                if (free_count == 0) {
                        frag_to_free = tmp;
@@ -150,13 +152,12 @@ next1:
        /*
         * Free last free fragments
         */
-       p = ufsi->i_u1.i_data + ufs_fragstoblks (frag3);
-       tmp = fs32_to_cpu(sb, *p);
+       p = ufs_get_direct_data_ptr(uspi, ufsi, ufs_fragstoblks(frag3));
+       tmp = ufs_data_ptr_to_cpu(sb, p);
        if (!tmp )
                ufs_panic(sb, "ufs_truncate_direct", "internal error");
        frag4 = ufs_fragnum (frag4);
-
-       *p = 0;
+       ufs_data_ptr_clear(uspi, p);
 
        ufs_free_fragments (inode, tmp, frag4);
        mark_inode_dirty(inode);
@@ -167,17 +168,20 @@ next1:
 }
 
 
-static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
+static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_buffer_head * ind_ubh;
-       __fs32 * ind;
-       unsigned indirect_block, i, tmp;
-       unsigned frag_to_free, free_count;
+       void *ind;
+       u64 tmp, indirect_block, i, frag_to_free;
+       unsigned free_count;
        int retry;
 
-       UFSD("ENTER\n");
+       UFSD("ENTER: ino %lu, offset %llu, p: %p\n",
+            inode->i_ino, (unsigned long long)offset, p);
+
+       BUG_ON(!p);
                
        sb = inode->i_sb;
        uspi = UFS_SB(sb)->s_uspi;
@@ -186,27 +190,27 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
        free_count = 0;
        retry = 0;
        
-       tmp = fs32_to_cpu(sb, *p);
+       tmp = ufs_data_ptr_to_cpu(sb, p);
        if (!tmp)
                return 0;
        ind_ubh = ubh_bread(sb, tmp, uspi->s_bsize);
-       if (tmp != fs32_to_cpu(sb, *p)) {
+       if (tmp != ufs_data_ptr_to_cpu(sb, p)) {
                ubh_brelse (ind_ubh);
                return 1;
        }
        if (!ind_ubh) {
-               *p = 0;
+               ufs_data_ptr_clear(uspi, p);
                return 0;
        }
 
        indirect_block = (DIRECT_BLOCK > offset) ? (DIRECT_BLOCK - offset) : 0;
        for (i = indirect_block; i < uspi->s_apb; i++) {
-               ind = ubh_get_addr32 (ind_ubh, i);
-               tmp = fs32_to_cpu(sb, *ind);
+               ind = ubh_get_data_ptr(uspi, ind_ubh, i);
+               tmp = ufs_data_ptr_to_cpu(sb, ind);
                if (!tmp)
                        continue;
 
-               *ind = 0;
+               ufs_data_ptr_clear(uspi, ind);
                ubh_mark_buffer_dirty(ind_ubh);
                if (free_count == 0) {
                        frag_to_free = tmp;
@@ -226,11 +230,12 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
                ufs_free_blocks (inode, frag_to_free, free_count);
        }
        for (i = 0; i < uspi->s_apb; i++)
-               if (*ubh_get_addr32(ind_ubh,i))
+               if (!ufs_is_data_ptr_zero(uspi,
+                                         ubh_get_data_ptr(uspi, ind_ubh, i)))
                        break;
        if (i >= uspi->s_apb) {
-               tmp = fs32_to_cpu(sb, *p);
-               *p = 0;
+               tmp = ufs_data_ptr_to_cpu(sb, p);
+               ufs_data_ptr_clear(uspi, p);
 
                ufs_free_blocks (inode, tmp, uspi->s_fpb);
                mark_inode_dirty(inode);
@@ -248,13 +253,13 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p)
        return retry;
 }
 
-static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p)
+static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
 {
        struct super_block * sb;
        struct ufs_sb_private_info * uspi;
-       struct ufs_buffer_head * dind_bh;
-       unsigned i, tmp, dindirect_block;
-       __fs32 * dind;
+       struct ufs_buffer_head *dind_bh;
+       u64 i, tmp, dindirect_block;
+       void *dind;
        int retry = 0;
        
        UFSD("ENTER\n");
@@ -266,22 +271,22 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p)
                ? ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0;
        retry = 0;
        
-       tmp = fs32_to_cpu(sb, *p);
+       tmp = ufs_data_ptr_to_cpu(sb, p);
        if (!tmp)
                return 0;
        dind_bh = ubh_bread(sb, tmp, uspi->s_bsize);
-       if (tmp != fs32_to_cpu(sb, *p)) {
+       if (tmp != ufs_data_ptr_to_cpu(sb, p)) {
                ubh_brelse (dind_bh);
                return 1;
        }
        if (!dind_bh) {
-               *p = 0;
+               ufs_data_ptr_clear(uspi, p);
                return 0;
        }
 
        for (i = dindirect_block ; i < uspi->s_apb ; i++) {
-               dind = ubh_get_addr32 (dind_bh, i);
-               tmp = fs32_to_cpu(sb, *dind);
+               dind = ubh_get_data_ptr(uspi, dind_bh, i);
+               tmp = ufs_data_ptr_to_cpu(sb, dind);
                if (!tmp)
                        continue;
                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)
        }
 
        for (i = 0; i < uspi->s_apb; i++)
-               if (*ubh_get_addr32 (dind_bh, i))
+               if (!ufs_is_data_ptr_zero(uspi,
+                                         ubh_get_data_ptr(uspi, dind_bh, i)))
                        break;
        if (i >= uspi->s_apb) {
-               tmp = fs32_to_cpu(sb, *p);
-               *p = 0;
+               tmp = ufs_data_ptr_to_cpu(sb, p);
+               ufs_data_ptr_clear(uspi, p);
 
                ufs_free_blocks(inode, tmp, uspi->s_fpb);
                mark_inode_dirty(inode);
@@ -311,34 +317,33 @@ static int ufs_trunc_dindirect (struct inode *inode, unsigned offset, __fs32 *p)
        return retry;
 }
 
-static int ufs_trunc_tindirect (struct inode * inode)
+static int ufs_trunc_tindirect(struct inode *inode)
 {
+       struct super_block *sb = inode->i_sb;
+       struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        struct ufs_inode_info *ufsi = UFS_I(inode);
-       struct super_block * sb;
-       struct ufs_sb_private_info * uspi;
        struct ufs_buffer_head * tind_bh;
-       unsigned tindirect_block, tmp, i;
-       __fs32 * tind, * p;
+       u64 tindirect_block, tmp, i;
+       void *tind, *p;
        int retry;
        
        UFSD("ENTER\n");
 
-       sb = inode->i_sb;
-       uspi = UFS_SB(sb)->s_uspi;
        retry = 0;
        
        tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb))
                ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0;
-       p = ufsi->i_u1.i_data + UFS_TIND_BLOCK;
-       if (!(tmp = fs32_to_cpu(sb, *p)))
+
+       p = ufs_get_direct_data_ptr(uspi, ufsi, UFS_TIND_BLOCK);
+       if (!(tmp = ufs_data_ptr_to_cpu(sb, p)))
                return 0;
        tind_bh = ubh_bread (sb, tmp, uspi->s_bsize);
-       if (tmp != fs32_to_cpu(sb, *p)) {
+       if (tmp != ufs_data_ptr_to_cpu(sb, p)) {
                ubh_brelse (tind_bh);
                return 1;
        }
        if (!tind_bh) {
-               *p = 0;
+               ufs_data_ptr_clear(uspi, p);
                return 0;
        }
 
@@ -349,11 +354,12 @@ static int ufs_trunc_tindirect (struct inode * inode)
                ubh_mark_buffer_dirty(tind_bh);
        }
        for (i = 0; i < uspi->s_apb; i++)
-               if (*ubh_get_addr32 (tind_bh, i))
+               if (!ufs_is_data_ptr_zero(uspi,
+                                         ubh_get_data_ptr(uspi, tind_bh, i)))
                        break;
        if (i >= uspi->s_apb) {
-               tmp = fs32_to_cpu(sb, *p);
-               *p = 0;
+               tmp = ufs_data_ptr_to_cpu(sb, p);
+               ufs_data_ptr_clear(uspi, p);
 
                ufs_free_blocks(inode, tmp, uspi->s_fpb);
                mark_inode_dirty(inode);
@@ -375,7 +381,8 @@ static int ufs_alloc_lastblock(struct inode *inode)
        int err = 0;
        struct address_space *mapping = inode->i_mapping;
        struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
-       unsigned lastfrag, i, end;
+       unsigned i, end;
+       sector_t lastfrag;
        struct page *lastpage;
        struct buffer_head *bh;
 
@@ -430,7 +437,9 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size)
        struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
        int retry, err = 0;
        
-       UFSD("ENTER\n");
+       UFSD("ENTER: ino %lu, i_size: %llu, old_i_size: %llu\n",
+            inode->i_ino, (unsigned long long)i_size_read(inode),
+            (unsigned long long)old_i_size);
 
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
              S_ISLNK(inode->i_mode)))
@@ -450,10 +459,12 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size)
        lock_kernel();
        while (1) {
                retry = ufs_trunc_direct(inode);
-               retry |= ufs_trunc_indirect (inode, UFS_IND_BLOCK,
-                       (__fs32 *) &ufsi->i_u1.i_data[UFS_IND_BLOCK]);
-               retry |= ufs_trunc_dindirect (inode, UFS_IND_BLOCK + uspi->s_apb,
-                       (__fs32 *) &ufsi->i_u1.i_data[UFS_DIND_BLOCK]);
+               retry |= ufs_trunc_indirect(inode, UFS_IND_BLOCK,
+                                           ufs_get_direct_data_ptr(uspi, ufsi,
+                                                                   UFS_IND_BLOCK));
+               retry |= ufs_trunc_dindirect(inode, UFS_IND_BLOCK + uspi->s_apb,
+                                            ufs_get_direct_data_ptr(uspi, ufsi,
+                                                                    UFS_DIND_BLOCK));
                retry |= ufs_trunc_tindirect (inode);
                if (!retry)
                        break;
index 7dd12bb1d62bdf9a9f2223e0d5840097831d4960..06d344839c42477f85141a9b6a6a3d95c4a33ca7 100644 (file)
@@ -305,8 +305,22 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi,
        (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \
        ((begin) & ((uspi->s_fsize>>2) - 1)))
 
+#define ubh_get_addr64(ubh,begin) \
+       (((__fs64*)((ubh)->bh[(begin) >> (uspi->s_fshift-3)]->b_data)) + \
+       ((begin) & ((uspi->s_fsize>>3) - 1)))
+
 #define ubh_get_addr ubh_get_addr8
 
+static inline void *ubh_get_data_ptr(struct ufs_sb_private_info *uspi,
+                                    struct ufs_buffer_head *ubh,
+                                    u64 blk)
+{
+       if (uspi->fs_magic == UFS2_MAGIC)
+               return ubh_get_addr64(ubh, blk);
+       else
+               return ubh_get_addr32(ubh, blk);
+}
+
 #define ubh_blkmap(ubh,begin,bit) \
        ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb)))
 
@@ -507,3 +521,46 @@ static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap,
        if (fragsize > 0 && fragsize < uspi->s_fpb)
                fs32_add(sb, &fraglist[fragsize], cnt);
 }
+
+static inline void *ufs_get_direct_data_ptr(struct ufs_sb_private_info *uspi,
+                                           struct ufs_inode_info *ufsi,
+                                           unsigned blk)
+{
+       BUG_ON(blk > UFS_TIND_BLOCK);
+       return uspi->fs_magic == UFS2_MAGIC ?
+               (void *)&ufsi->i_u1.u2_i_data[blk] :
+               (void *)&ufsi->i_u1.i_data[blk];
+}
+
+static inline u64 ufs_data_ptr_to_cpu(struct super_block *sb, void *p)
+{
+       return UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC ?
+               fs64_to_cpu(sb, *(__fs64 *)p) :
+               fs32_to_cpu(sb, *(__fs32 *)p);
+}
+
+static inline void ufs_cpu_to_data_ptr(struct super_block *sb, void *p, u64 val)
+{
+       if (UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC)
+               *(__fs64 *)p = cpu_to_fs64(sb, val);
+       else
+               *(__fs32 *)p = cpu_to_fs32(sb, val);
+}
+
+static inline void ufs_data_ptr_clear(struct ufs_sb_private_info *uspi,
+                                     void *p)
+{
+       if (uspi->fs_magic == UFS2_MAGIC)
+               *(__fs64 *)p = 0;
+       else
+               *(__fs32 *)p = 0;
+}
+
+static inline int ufs_is_data_ptr_zero(struct ufs_sb_private_info *uspi,
+                                      void *p)
+{
+       if (uspi->fs_magic == UFS2_MAGIC)
+               return *(__fs64 *)p == 0;
+       else
+               return *(__fs32 *)p == 0;
+}
index 24ce39820560b122898d10d48451fab5a7079269..44c45449065cd10c8664d8d7e990fb1a41c40ced 100644 (file)
@@ -40,6 +40,7 @@ typedef __u64 __fs64;
 typedef __u32 __fs32;
 typedef __u16 __fs16;
 #else
+#include <asm/div64.h>
 typedef __u64 __bitwise __fs64;
 typedef __u32 __bitwise __fs32;
 typedef __u16 __bitwise __fs16;
@@ -266,13 +267,6 @@ typedef __u16 __bitwise __fs16;
 #define        ufs_inotofsba(x)        (((u64)ufs_cgimin(ufs_inotocg(x))) + ufs_inotocgoff(x) / uspi->s_inopf)
 #define        ufs_inotofsbo(x)        ((x) % uspi->s_inopf)
 
-/*
- * Give cylinder group number for a file system block.
- * Give cylinder group block number for a file system block.
- */
-#define        ufs_dtog(d)     ((d) / uspi->s_fpg)
-#define        ufs_dtogd(d)    ((d) % uspi->s_fpg)
-
 /*
  * Compute the cylinder and rotational position of a cyl block addr.
  */
@@ -723,6 +717,7 @@ struct ufs_cg_private_info {
        __u32   c_nclusterblks; /* number of clusters this cg */
 };     
 
+
 struct ufs_sb_private_info {
        struct ufs_buffer_head s_ubh; /* buffer containing super block */
        struct ufs_csum_core cs_total;
@@ -952,10 +947,10 @@ struct ufs_super_block_third {
 #ifdef __KERNEL__
 
 /* balloc.c */
-extern void ufs_free_fragments (struct inode *, unsigned, unsigned);
-extern void ufs_free_blocks (struct inode *, unsigned, unsigned);
-extern unsigned ufs_new_fragments(struct inode *, __fs32 *, unsigned, unsigned,
-                                 unsigned, int *, struct page *);
+extern void ufs_free_fragments (struct inode *, u64, unsigned);
+extern void ufs_free_blocks (struct inode *, u64, unsigned);
+extern u64 ufs_new_fragments(struct inode *, void *, u64, u64,
+                            unsigned, int *, struct page *);
 
 /* cylinder.c */
 extern struct ufs_cg_private_info * ufs_load_cylinder (struct super_block *, unsigned);
@@ -1016,6 +1011,22 @@ static inline struct ufs_inode_info *UFS_I(struct inode *inode)
        return container_of(inode, struct ufs_inode_info, vfs_inode);
 }
 
+/*
+ * Give cylinder group number for a file system block.
+ * Give cylinder group block number for a file system block.
+ */
+/* #define     ufs_dtog(d)     ((d) / uspi->s_fpg) */
+static inline u64 ufs_dtog(struct ufs_sb_private_info * uspi, u64 b)
+{
+       do_div(b, uspi->s_fpg);
+       return b;
+}
+/* #define     ufs_dtogd(d)    ((d) % uspi->s_fpg) */
+static inline u32 ufs_dtogd(struct ufs_sb_private_info * uspi, u64 b)
+{
+       return do_div(b, uspi->s_fpg);
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* __LINUX_UFS_FS_H */
index fef77d52b029371f458b4c15156e2c13a46871e0..6496caa82f9ef12ac11316e7a95e71d2565925d7 100644 (file)
@@ -25,7 +25,7 @@ struct ufs_inode_info {
        __u32   i_unused2;
        __u32   i_oeftflag;
        __u16   i_osync;
-       __u32   i_lastfrag;
+       __u64   i_lastfrag;
        __u32   i_dir_start_lookup;
        struct inode vfs_inode;
 };