config GFS2_FS
        tristate "GFS2 file system support"
-       depends on EXPERIMENTAL
+       depends on EXPERIMENTAL && (64BIT || LSF)
        select FS_POSIX_ACL
        select CRC32
        help
 
 
        if (ip->i_di.di_size) {
                *(__be64 *)(di + 1) = cpu_to_be64(block);
-               ip->i_di.di_blocks++;
-               gfs2_set_inode_blocks(&ip->i_inode);
-               di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
+               gfs2_add_inode_blocks(&ip->i_inode, 1);
+               di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
        }
 
        ip->i_height = 1;
        gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
        *(__be64 *)(di + 1) = cpu_to_be64(bn);
        ip->i_height += new_height;
-       ip->i_di.di_blocks += new_height;
-       gfs2_set_inode_blocks(&ip->i_inode);
+       gfs2_add_inode_blocks(&ip->i_inode, new_height);
        di->di_height = cpu_to_be16(ip->i_height);
-       di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
+       di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
        brelse(dibh);
        return error;
 }
        gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[height], 1);
 
        *ptr = cpu_to_be64(*block);
-       ip->i_di.di_blocks++;
-       gfs2_set_inode_blocks(&ip->i_inode);
+       gfs2_add_inode_blocks(&ip->i_inode, 1);
 
        *new = 1;
        return 0;
                }
 
                *p = 0;
-               if (!ip->i_di.di_blocks)
-                       gfs2_consist_inode(ip);
-               ip->i_di.di_blocks--;
-               gfs2_set_inode_blocks(&ip->i_inode);
+               gfs2_add_inode_blocks(&ip->i_inode, -1);
        }
        if (bstart) {
                if (metadata)
 
                *lp = cpu_to_be64(bn);
 
        dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2;
-       dip->i_di.di_blocks++;
-       gfs2_set_inode_blocks(&dip->i_inode);
+       gfs2_add_inode_blocks(&dip->i_inode, 1);
        dip->i_di.di_flags |= GFS2_DIF_EXHASH;
 
        for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
        error = gfs2_meta_inode_buffer(dip, &dibh);
        if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
                gfs2_trans_add_bh(dip->i_gl, dibh, 1);
-               dip->i_di.di_blocks++;
-               gfs2_set_inode_blocks(&dip->i_inode);
+               gfs2_add_inode_blocks(&dip->i_inode, 1);
                gfs2_dinode_out(dip, dibh->b_data);
                brelse(dibh);
        }
        if (error)
                return error;
        gfs2_trans_add_bh(ip->i_gl, bh, 1);
-       ip->i_di.di_blocks++;
-       gfs2_set_inode_blocks(&ip->i_inode);
+       gfs2_add_inode_blocks(&ip->i_inode, 1);
        gfs2_dinode_out(ip, bh->b_data);
        brelse(bh);
        return 0;
                brelse(bh);
 
                gfs2_free_meta(dip, blk, 1);
-
-               if (!dip->i_di.di_blocks)
-                       gfs2_consist_inode(dip);
-               dip->i_di.di_blocks--;
-               gfs2_set_inode_blocks(&dip->i_inode);
+               gfs2_add_inode_blocks(&dip->i_inode, -1);
        }
 
        error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size);
 
                }
 
                *dataptrs = 0;
-               if (!ip->i_di.di_blocks)
-                       gfs2_consist_inode(ip);
-               ip->i_di.di_blocks--;
-               gfs2_set_inode_blocks(&ip->i_inode);
+               gfs2_add_inode_blocks(&ip->i_inode, -1);
        }
        if (bstart)
                gfs2_free_meta(ip, bstart, blen);
        ea->ea_flags = GFS2_EAFLAG_LAST;
        ea->ea_num_ptrs = 0;
 
-       ip->i_di.di_blocks++;
-       gfs2_set_inode_blocks(&ip->i_inode);
+       gfs2_add_inode_blocks(&ip->i_inode, 1);
 
        return 0;
 }
                        gfs2_trans_add_bh(ip->i_gl, bh, 1);
                        gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);
 
-                       ip->i_di.di_blocks++;
-                       gfs2_set_inode_blocks(&ip->i_inode);
+                       gfs2_add_inode_blocks(&ip->i_inode, 1);
 
                        copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
                                                           data_len;
                *eablk = cpu_to_be64(ip->i_di.di_eattr);
                ip->i_di.di_eattr = blk;
                ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT;
-               ip->i_di.di_blocks++;
-               gfs2_set_inode_blocks(&ip->i_inode);
+               gfs2_add_inode_blocks(&ip->i_inode, 1);
 
                eablk++;
        }
                }
 
                *eablk = 0;
-               if (!ip->i_di.di_blocks)
-                       gfs2_consist_inode(ip);
-               ip->i_di.di_blocks--;
-               gfs2_set_inode_blocks(&ip->i_inode);
+               gfs2_add_inode_blocks(&ip->i_inode, -1);
        }
        if (bstart)
                gfs2_free_meta(ip, bstart, blen);
        gfs2_free_meta(ip, ip->i_di.di_eattr, 1);
 
        ip->i_di.di_eattr = 0;
-       if (!ip->i_di.di_blocks)
-               gfs2_consist_inode(ip);
-       ip->i_di.di_blocks--;
-       gfs2_set_inode_blocks(&ip->i_inode);
+       gfs2_add_inode_blocks(&ip->i_inode, -1);
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (!error) {
 
 
 struct gfs2_dinode_host {
        u64 di_size;            /* number of bytes in file */
-       u64 di_blocks;          /* number of blocks in file */
        u64 di_generation;      /* generation number for NFS */
        u32 di_flags;           /* GFS2_DIF_... */
        /* These only apply to directories  */
 
        ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink);
        di->di_size = be64_to_cpu(str->di_size);
        i_size_write(&ip->i_inode, di->di_size);
-       di->di_blocks = be64_to_cpu(str->di_blocks);
-       gfs2_set_inode_blocks(&ip->i_inode);
+       gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
        ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
        ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
        ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
        struct gfs2_rgrpd *rgd;
        int error;
 
-       if (ip->i_di.di_blocks != 1) {
+       if (gfs2_get_inode_blocks(&ip->i_inode) != 1) {
                if (gfs2_consist_inode(ip))
                        gfs2_dinode_print(ip);
                return -EIO;
        str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
        str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
        str->di_size = cpu_to_be64(di->di_size);
-       str->di_blocks = cpu_to_be64(di->di_blocks);
+       str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
        str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
        str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
        str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
        printk(KERN_INFO "  no_addr = %llu\n",
               (unsigned long long)ip->i_no_addr);
        printk(KERN_INFO "  di_size = %llu\n", (unsigned long long)di->di_size);
-       printk(KERN_INFO "  di_blocks = %llu\n",
-              (unsigned long long)di->di_blocks);
+       printk(KERN_INFO "  blocks = %llu\n",
+              (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode));
        printk(KERN_INFO "  i_goal = %llu\n",
               (unsigned long long)ip->i_goal);
        printk(KERN_INFO "  di_flags = 0x%.8X\n", di->di_flags);
 
 #ifndef __INODE_DOT_H__
 #define __INODE_DOT_H__
 
+#include "util.h"
+
 static inline int gfs2_is_stuffed(const struct gfs2_inode *ip)
 {
        return !ip->i_height;
        return S_ISDIR(ip->i_inode.i_mode);
 }
 
-static inline void gfs2_set_inode_blocks(struct inode *inode)
+static inline void gfs2_set_inode_blocks(struct inode *inode, u64 blocks)
+{
+       inode->i_blocks = blocks <<
+               (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
+}
+
+static inline u64 gfs2_get_inode_blocks(const struct inode *inode)
 {
-       struct gfs2_inode *ip = GFS2_I(inode);
-       inode->i_blocks = ip->i_di.di_blocks <<
+       return inode->i_blocks >>
                (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
 }
 
+static inline void gfs2_add_inode_blocks(struct inode *inode, s64 change)
+{
+       gfs2_assert(GFS2_SB(inode), (change >= 0 || inode->i_blocks > -change));
+       change *= (GFS2_SB(inode)->sd_sb.sb_bsize/GFS2_BASIC_BLOCK);
+       inode->i_blocks += change;
+}
+
 static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr,
                                  u64 no_formal_ino)
 {
 
        brelse(dibh);
 
        if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
-               gfs2_quota_change(ip, -ip->i_di.di_blocks, ouid, ogid);
-               gfs2_quota_change(ip, ip->i_di.di_blocks, nuid, ngid);
+               u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
+               gfs2_quota_change(ip, -blocks, ouid, ogid);
+               gfs2_quota_change(ip, blocks, nuid, ngid);
        }
 
 out_end_trans: