fs32_add(sb, &ucg->cg_cs.cs_nffree, count);
-       fs32_add(sb, &usb1->fs_cstotal.cs_nffree, count);
+       uspi->cs_total.cs_nffree += count;
        fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
        blkmap = ubh_blkmap (UCPI_UBH(ucpi), ucpi->c_freeoff, bbase);
        ufs_fragacct(sb, blkmap, ucg->cg_frsum, 1);
        blkno = ufs_fragstoblks (bbase);
        if (ubh_isblockset(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno)) {
                fs32_sub(sb, &ucg->cg_cs.cs_nffree, uspi->s_fpb);
-               fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, uspi->s_fpb);
+               uspi->cs_total.cs_nffree -= uspi->s_fpb;
                fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, uspi->s_fpb);
                if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
                        ufs_clusteracct (sb, ucpi, blkno, 1);
                fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
-               fs32_add(sb, &usb1->fs_cstotal.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);
                DQUOT_FREE_BLOCK(inode, uspi->s_fpb);
 
                fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
-               fs32_add(sb, &usb1->fs_cstotal.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);
        /*
         * There is not enough space for user on the device
         */
-       if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(usb1, UFS_MINFREE) <= 0) {
+       if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) {
                unlock_super (sb);
                UFSD("EXIT (FAILED)\n");
                return 0;
        switch (fs32_to_cpu(sb, usb1->fs_optim)) {
            case UFS_OPTSPACE:
                request = newcount;
-               if (uspi->s_minfree < 5 || fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree) 
-                   > uspi->s_dsize * uspi->s_minfree / (2 * 100) )
+               if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree
+                   > uspi->s_dsize * uspi->s_minfree / (2 * 100))
                        break;
                usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
                break;
        
            case UFS_OPTTIME:
                request = uspi->s_fpb;
-               if (fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree) < uspi->s_dsize *
+               if (uspi->cs_total.cs_nffree < uspi->s_dsize *
                    (uspi->s_minfree - 2) / 100)
                        break;
                usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
 
        fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);
        fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
-       fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, count);
+       uspi->cs_total.cs_nffree -= count;
        
        ubh_mark_buffer_dirty (USPI_UBH(uspi));
        ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
                DQUOT_FREE_BLOCK(inode, i);
 
                fs32_add(sb, &ucg->cg_cs.cs_nffree, i);
-               fs32_add(sb, &usb1->fs_cstotal.cs_nffree, i);
+               uspi->cs_total.cs_nffree += i;
                fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i);
                fs32_add(sb, &ucg->cg_frsum[i], 1);
                goto succed;
                ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i);
        
        fs32_sub(sb, &ucg->cg_cs.cs_nffree, count);
-       fs32_sub(sb, &usb1->fs_cstotal.cs_nffree, count);
+       uspi->cs_total.cs_nffree -= count;
        fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count);
        fs32_sub(sb, &ucg->cg_frsum[allocsize], 1);
 
        }
 
        fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1);
-       fs32_sub(sb, &usb1->fs_cstotal.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);
 
 }
 
 /*
- * Read on-disk structures associated with cylinder groups
+ * Diffrent types of UFS hold fs_cstotal in different
+ * places, and use diffrent data structure for it.
+ * To make things simplier we just copy fs_cstotal to ufs_sb_private_info
  */
-static int ufs_read_cylinder_structures (struct super_block *sb)
+static void ufs_setup_cstotal(struct super_block *sb)
 {
        struct ufs_sb_info *sbi = UFS_SB(sb);
        struct ufs_sb_private_info *uspi = sbi->s_uspi;
+       struct ufs_super_block_first *usb1;
+       struct ufs_super_block_second *usb2;
        struct ufs_super_block_third *usb3;
+       unsigned mtype = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;
+
+       UFSD("ENTER, mtype=%u\n", mtype);
+       usb1 = ubh_get_usb_first(uspi);
+       usb2 = ubh_get_usb_second(uspi);
+       usb3 = ubh_get_usb_third(uspi);
+
+       if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
+            (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
+           mtype == UFS_MOUNT_UFSTYPE_UFS2) {
+               /*we have statistic in different place, then usual*/
+               uspi->cs_total.cs_ndir = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir);
+               uspi->cs_total.cs_nbfree = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree);
+               uspi->cs_total.cs_nifree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree);
+               uspi->cs_total.cs_nffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree);
+       } else {
+               uspi->cs_total.cs_ndir = fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir);
+               uspi->cs_total.cs_nbfree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree);
+               uspi->cs_total.cs_nifree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
+               uspi->cs_total.cs_nffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
+       }
+       UFSD("EXIT\n");
+}
+
+/*
+ * Read on-disk structures associated with cylinder groups
+ */
+static int ufs_read_cylinder_structures(struct super_block *sb)
+{
+       struct ufs_sb_info *sbi = UFS_SB(sb);
+       struct ufs_sb_private_info *uspi = sbi->s_uspi;
+       unsigned flags = sbi->s_flags;
        struct ufs_buffer_head * ubh;
        unsigned char * base, * space;
        unsigned size, blks, i;
-       unsigned flags = 0;
-       
+       struct ufs_super_block_third *usb3;
+
        UFSD("ENTER\n");
-       
-       usb3 = ubh_get_usb_third(uspi);
 
-        flags = UFS_SB(sb)->s_flags;
-       
+       usb3 = ubh_get_usb_third(uspi);
        /*
         * Read cs structures from (usually) first data block
         * on the device. 
 }
 
 /*
- * Put on-disk structures associated with cylinder groups and 
- * write them back to disk
+ * Sync our internal copy of fs_cstotal with disk
  */
-static void ufs_put_cylinder_structures (struct super_block *sb)
+static void ufs_put_cstotal(struct super_block *sb)
 {
-       struct ufs_sb_info * sbi = UFS_SB(sb);
-       struct ufs_sb_private_info * uspi;
+       unsigned mtype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
+       struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+       struct ufs_super_block_first *usb1;
+       struct ufs_super_block_second *usb2;
+       struct ufs_super_block_third *usb3;
+
+       UFSD("ENTER\n");
+       usb1 = ubh_get_usb_first(uspi);
+       usb2 = ubh_get_usb_second(uspi);
+       usb3 = ubh_get_usb_third(uspi);
+
+       if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&
+            (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||
+           mtype == UFS_MOUNT_UFSTYPE_UFS2) {
+               /*we have statistic in different place, then usual*/
+               usb2->fs_un.fs_u2.cs_ndir =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_ndir);
+               usb2->fs_un.fs_u2.cs_nbfree =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_nbfree);
+               usb3->fs_un1.fs_u2.cs_nifree =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_nifree);
+               usb3->fs_un1.fs_u2.cs_nffree =
+                       cpu_to_fs64(sb, uspi->cs_total.cs_nffree);
+       } else {
+               usb1->fs_cstotal.cs_ndir =
+                       cpu_to_fs32(sb, uspi->cs_total.cs_ndir);
+               usb1->fs_cstotal.cs_nbfree =
+                       cpu_to_fs32(sb, uspi->cs_total.cs_nbfree);
+               usb1->fs_cstotal.cs_nifree =
+                       cpu_to_fs32(sb, uspi->cs_total.cs_nifree);
+               usb1->fs_cstotal.cs_nffree =
+                       cpu_to_fs32(sb, uspi->cs_total.cs_nffree);
+       }
+       ubh_mark_buffer_dirty(USPI_UBH(uspi));
+       UFSD("EXIT\n");
+}
+
+/**
+ * ufs_put_super_internal() - put on-disk intrenal structures
+ * @sb: pointer to super_block structure
+ * Put on-disk structures associated with cylinder groups
+ * and write them back to disk, also update cs_total on disk
+ */
+static void ufs_put_super_internal(struct super_block *sb)
+{
+       struct ufs_sb_info *sbi = UFS_SB(sb);
+       struct ufs_sb_private_info *uspi = sbi->s_uspi;
        struct ufs_buffer_head * ubh;
        unsigned char * base, * space;
        unsigned blks, size, i;
+
        
        UFSD("ENTER\n");
-       
-       uspi = sbi->s_uspi;
-
+       ufs_put_cstotal(sb);
        size = uspi->s_cssize;
        blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
        base = space = (char*) sbi->s_csp;
        struct ufs_super_block_first * usb1;
        struct ufs_super_block_second * usb2;
        struct ufs_super_block_third * usb3;
-       struct ufs_super_block *usb;
        struct ufs_buffer_head * ubh;   
        struct inode *inode;
        unsigned block_size, super_block_size;
        usb1 = ubh_get_usb_first(uspi);
        usb2 = ubh_get_usb_second(uspi);
        usb3 = ubh_get_usb_third(uspi);
-       usb  = (struct ufs_super_block *)
-               ((struct ufs_buffer_head *)uspi)->bh[0]->b_data ;
 
        /*
         * Check ufs magic number
                        sb->s_flags |= MS_RDONLY;
                        break;
                }
-       }
-       else {
+       } else {
                printk("ufs_read_super: fs needs fsck\n");
                sb->s_flags |= MS_RDONLY;
        }
        if (!sb->s_root)
                goto dalloc_failed;
 
-
+       ufs_setup_cstotal(sb);
        /*
         * Read cylinder group structures
         */
                  || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
                        ufs_set_fs_state(sb, usb1, usb3,
                                        UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
-               ubh_mark_buffer_dirty (USPI_UBH(uspi));
+               ufs_put_cstotal(sb);
        }
        sb->s_dirt = 0;
        UFSD("EXIT\n");
        UFSD("ENTER\n");
 
        if (!(sb->s_flags & MS_RDONLY))
-               ufs_put_cylinder_structures (sb);
+               ufs_put_super_internal(sb);
        
        ubh_brelse_uspi (sbi->s_uspi);
        kfree (sbi->s_uspi);
                return -EINVAL;
        if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
                new_mount_opt |= ufstype;
-       }
-       else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
+       } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
                printk("ufstype can't be changed during remount\n");
                return -EINVAL;
        }
         * fs was mouted as rw, remounting ro
         */
        if (*mount_flags & MS_RDONLY) {
-               ufs_put_cylinder_structures(sb);
+               ufs_put_super_internal(sb);
                usb1->fs_time = cpu_to_fs32(sb, get_seconds());
                if ((flags & UFS_ST_MASK) == UFS_ST_SUN
                  || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 
                ubh_mark_buffer_dirty (USPI_UBH(uspi));
                sb->s_dirt = 0;
                sb->s_flags |= MS_RDONLY;
-       }
+       } else {
        /*
         * fs was mounted as ro, remounting rw
         */
-       else {
 #ifndef CONFIG_UFS_FS_WRITE
                printk("ufs was compiled with read-only support, "
                "can't be mounted as read-write\n");
                        printk("this ufstype is read-only supported\n");
                        return -EINVAL;
                }
-               if (!ufs_read_cylinder_structures (sb)) {
+               if (!ufs_read_cylinder_structures(sb)) {
                        printk("failed during remounting\n");
                        return -EPERM;
                }
        if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
                buf->f_type = UFS2_MAGIC;
                buf->f_blocks = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize);
-               buf->f_bfree = ufs_blkstofrags(
-                       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree)) +
-                       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree);
-               buf->f_ffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree);
        } else {
                buf->f_type = UFS_MAGIC;
                buf->f_blocks = uspi->s_dsize;
-               buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) +
-                       fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
-               buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
        }
+       buf->f_bfree = ufs_blkstofrags(uspi->cs_total.cs_nbfree) +
+               uspi->cs_total.cs_nffree;
+       buf->f_ffree = uspi->cs_total.cs_nifree;
        buf->f_bsize = sb->s_blocksize;
        buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree))
                ? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;