[PATCH] VFS: Permit filesystem to perform statfs with a known root dentry
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / ufs / super.c
index e9a42c711a9e386df42f329855e4683600eda25d..fe5ab2aa289936f062ce2c5fe43a8f6ed220315e 100644 (file)
@@ -221,7 +221,7 @@ void ufs_error (struct super_block * sb, const char * function,
        va_list args;
 
        uspi = UFS_SB(sb)->s_uspi;
-       usb1 = ubh_get_usb_first(USPI_UBH);
+       usb1 = ubh_get_usb_first(uspi);
        
        if (!(sb->s_flags & MS_RDONLY)) {
                usb1->fs_clean = UFS_FSBAD;
@@ -253,7 +253,7 @@ void ufs_panic (struct super_block * sb, const char * function,
        va_list args;
        
        uspi = UFS_SB(sb)->s_uspi;
-       usb1 = ubh_get_usb_first(USPI_UBH);
+       usb1 = ubh_get_usb_first(uspi);
        
        if (!(sb->s_flags & MS_RDONLY)) {
                usb1->fs_clean = UFS_FSBAD;
@@ -388,7 +388,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
 /*
  * Read on-disk structures associated with cylinder groups
  */
-static int ufs_read_cylinder_structures (struct super_block *sb) {
+static int ufs_read_cylinder_structures (struct super_block *sb)
+{
        struct ufs_sb_info * sbi = UFS_SB(sb);
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block *usb;
@@ -415,26 +416,23 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
        base = space = kmalloc(size, GFP_KERNEL);
        if (!base)
                goto failed; 
+       sbi->s_csp = (struct ufs_csum *)space;
        for (i = 0; i < blks; i += uspi->s_fpb) {
                size = uspi->s_bsize;
                if (i + uspi->s_fpb > blks)
                        size = (blks - i) * uspi->s_fsize;
 
-               if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
+               if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) 
                        ubh = ubh_bread(sb,
                                fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_csaddr) + i, size);
-                       if (!ubh)
-                               goto failed;
-                       ubh_ubhcpymem (space, ubh, size);
-                       sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space;
-               }
-               else {
+               else 
                        ubh = ubh_bread(sb, uspi->s_csaddr + i, size);
-                       if (!ubh)
-                               goto failed;
-                       ubh_ubhcpymem(space, ubh, size);
-                       sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space;
-               }
+               
+               if (!ubh)
+                       goto failed;
+
+               ubh_ubhcpymem (space, ubh, size);
+
                space += size;
                ubh_brelse (ubh);
                ubh = NULL;
@@ -489,7 +487,8 @@ failed:
  * Put on-disk structures associated with cylinder groups and 
  * write them back to disk
  */
-static void ufs_put_cylinder_structures (struct super_block *sb) {
+static void ufs_put_cylinder_structures (struct super_block *sb)
+{
        struct ufs_sb_info * sbi = UFS_SB(sb);
        struct ufs_sb_private_info * uspi;
        struct ufs_buffer_head * ubh;
@@ -502,7 +501,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) {
 
        size = uspi->s_cssize;
        blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
-       base = space = (char*) sbi->s_csp[0];
+       base = space = (char*) sbi->s_csp;
        for (i = 0; i < blks; i += uspi->s_fpb) {
                size = uspi->s_bsize;
                if (i + uspi->s_fpb > blks)
@@ -539,6 +538,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
        struct inode *inode;
        unsigned block_size, super_block_size;
        unsigned flags;
+       unsigned super_block_offset;
 
        uspi = NULL;
        ubh = NULL;
@@ -575,7 +575,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
                if (!silent)
                        printk("You didn't specify the type of your ufs filesystem\n\n"
                        "mount -t ufs -o ufstype="
-                       "sun|sunx86|44bsd|ufs2|5xbsd|old|hp|nextstep|netxstep-cd|openstep ...\n\n"
+                       "sun|sunx86|44bsd|ufs2|5xbsd|old|hp|nextstep|nextstep-cd|openstep ...\n\n"
                        ">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "
                        "default is ufstype=old\n");
                ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);
@@ -586,10 +586,11 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
        if (!uspi)
                goto failed;
 
+       super_block_offset=UFS_SBLOCK;
+
        /* Keep 2Gig file limit. Some UFS variants need to override 
           this but as I don't know which I'll let those in the know loosen
           the rules */
-          
        switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {
        case UFS_MOUNT_UFSTYPE_44BSD:
                UFSD(("ufstype=44bsd\n"))
@@ -601,7 +602,8 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
                flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
                break;
        case UFS_MOUNT_UFSTYPE_UFS2:
-               UFSD(("ufstype=ufs2\n"))
+               UFSD(("ufstype=ufs2\n"));
+               super_block_offset=SBLOCK_UFS2;
                uspi->s_fsize = block_size = 512;
                uspi->s_fmask = ~(512 - 1);
                uspi->s_fshift = 9;
@@ -725,19 +727,16 @@ again:
        /*
         * read ufs super block from device
         */
-       if ( (flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
-               ubh = ubh_bread_uspi(uspi, sb, uspi->s_sbbase + SBLOCK_UFS2/block_size, super_block_size);
-       }
-       else {
-               ubh = ubh_bread_uspi(uspi, sb, uspi->s_sbbase + UFS_SBLOCK/block_size, super_block_size);
-       }
+
+       ubh = ubh_bread_uspi(uspi, sb, uspi->s_sbbase + super_block_offset/block_size, super_block_size);
+       
        if (!ubh) 
             goto failed;
 
        
-       usb1 = ubh_get_usb_first(USPI_UBH);
-       usb2 = ubh_get_usb_second(USPI_UBH);
-       usb3 = ubh_get_usb_third(USPI_UBH);
+       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 ;
 
@@ -1006,8 +1005,8 @@ static void ufs_write_super (struct super_block *sb) {
        UFSD(("ENTER\n"))
        flags = UFS_SB(sb)->s_flags;
        uspi = UFS_SB(sb)->s_uspi;
-       usb1 = ubh_get_usb_first(USPI_UBH);
-       usb3 = ubh_get_usb_third(USPI_UBH);
+       usb1 = ubh_get_usb_first(uspi);
+       usb3 = ubh_get_usb_third(uspi);
 
        if (!(sb->s_flags & MS_RDONLY)) {
                usb1->fs_time = cpu_to_fs32(sb, get_seconds());
@@ -1049,8 +1048,8 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
        
        uspi = UFS_SB(sb)->s_uspi;
        flags = UFS_SB(sb)->s_flags;
-       usb1 = ubh_get_usb_first(USPI_UBH);
-       usb3 = ubh_get_usb_third(USPI_UBH);
+       usb1 = ubh_get_usb_first(uspi);
+       usb3 = ubh_get_usb_third(uspi);
        
        /*
         * Allow the "check" option to be passed as a remount option.
@@ -1114,8 +1113,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
        return 0;
 }
 
-static int ufs_statfs (struct super_block *sb, struct kstatfs *buf)
+static int ufs_statfs (struct dentry *dentry, struct kstatfs *buf)
 {
+       struct super_block *sb = dentry->d_sb;
        struct ufs_sb_private_info * uspi;
        struct ufs_super_block_first * usb1;
        struct ufs_super_block * usb;
@@ -1124,7 +1124,7 @@ static int ufs_statfs (struct super_block *sb, struct kstatfs *buf)
        lock_kernel();
 
        uspi = UFS_SB(sb)->s_uspi;
-       usb1 = ubh_get_usb_first (USPI_UBH);
+       usb1 = ubh_get_usb_first (uspi);
        usb  = (struct ufs_super_block *)
                ((struct ufs_buffer_head *)uspi)->bh[0]->b_data ;
        
@@ -1185,7 +1185,8 @@ static int init_inodecache(void)
 {
        ufs_inode_cachep = kmem_cache_create("ufs_inode_cache",
                                             sizeof(struct ufs_inode_info),
-                                            0, SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (ufs_inode_cachep == NULL)
                return -ENOMEM;
@@ -1311,10 +1312,10 @@ out:
 
 #endif
 
-static struct super_block *ufs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int ufs_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt);
 }
 
 static struct file_system_type ufs_fs_type = {