fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / affs / super.c
index ad83ec3..3de93e7 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/genhd.h>
-#include <linux/amigaffs.h>
-#include <linux/major.h>
-#include <linux/blkdev.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
-#include <linux/vfs.h>
+#include <linux/statfs.h>
 #include <linux/parser.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/magic.h>
+#include "affs.h"
 
 extern struct timezone sys_tz;
 
-static int affs_statfs(struct super_block *sb, struct kstatfs *buf);
+static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int affs_remount (struct super_block *sb, int *flags, char *data);
 
 static void
@@ -44,17 +29,15 @@ affs_put_super(struct super_block *sb)
        pr_debug("AFFS: put_super()\n");
 
        if (!(sb->s_flags & MS_RDONLY)) {
-               AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = be32_to_cpu(1);
+               AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1);
                secs_to_datestamp(get_seconds(),
                                  &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
                affs_fix_checksum(sb, sbi->s_root_bh);
                mark_buffer_dirty(sbi->s_root_bh);
        }
 
-       affs_brelse(sbi->s_bmap_bh);
-       if (sbi->s_prefix)
-               kfree(sbi->s_prefix);
-       kfree(sbi->s_bitmap);
+       kfree(sbi->s_prefix);
+       affs_free_bitmap(sb);
        affs_brelse(sbi->s_root_bh);
        kfree(sbi);
        sb->s_fs_info = NULL;
@@ -71,7 +54,7 @@ affs_write_super(struct super_block *sb)
                //      if (sbi->s_bitmap[i].bm_bh) {
                //              if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) {
                //                      clean = 0;
-               AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = be32_to_cpu(clean);
+               AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(clean);
                secs_to_datestamp(get_seconds(),
                                  &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
                affs_fix_checksum(sb, sbi->s_root_bh);
@@ -83,12 +66,12 @@ affs_write_super(struct super_block *sb)
        pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean);
 }
 
-static kmem_cache_t * affs_inode_cachep;
+static struct kmem_cache * affs_inode_cachep;
 
 static struct inode *affs_alloc_inode(struct super_block *sb)
 {
        struct affs_inode_info *ei;
-       ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, SLAB_KERNEL);
+       ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
        ei->vfs_inode.i_version = 1;
@@ -100,7 +83,7 @@ static void affs_destroy_inode(struct inode *inode)
        kmem_cache_free(affs_inode_cachep, AFFS_I(inode));
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
 {
        struct affs_inode_info *ei = (struct affs_inode_info *) foo;
 
@@ -116,7 +99,8 @@ static int init_inodecache(void)
 {
        affs_inode_cachep = kmem_cache_create("affs_inode_cache",
                                             sizeof(struct affs_inode_info),
-                                            0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
                                             init_once, NULL);
        if (affs_inode_cachep == NULL)
                return -ENOMEM;
@@ -125,8 +109,7 @@ static int init_inodecache(void)
 
 static void destroy_inodecache(void)
 {
-       if (kmem_cache_destroy(affs_inode_cachep))
-               printk(KERN_INFO "affs_inode_cache: not all structures were freed\n");
+       kmem_cache_destroy(affs_inode_cachep);
 }
 
 static struct super_operations affs_sops = {
@@ -215,10 +198,9 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
                        *mount_opts |= SF_MUFS;
                        break;
                case Opt_prefix:
-                       if (*prefix) {          /* Free any previous prefix */
-                               kfree(*prefix);
-                               *prefix = NULL;
-                       }
+                       /* Free any previous prefix */
+                       kfree(*prefix);
+                       *prefix = NULL;
                        *prefix = match_strdup(&args[0]);
                        if (!*prefix)
                                return 0;
@@ -288,6 +270,8 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
        gid_t                    gid;
        int                      reserved;
        unsigned long            mount_flags;
+       int                      tmp_flags;     /* fix remount prototype... */
+       u8                       sig[4];
 
        pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");
 
@@ -295,11 +279,10 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_op                = &affs_sops;
        sb->s_flags |= MS_NODIRATIME;
 
-       sbi = kmalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
+       sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
        if (!sbi)
                return -ENOMEM;
        sb->s_fs_info = sbi;
-       memset(sbi, 0, sizeof(*sbi));
        init_MUTEX(&sbi->s_bmlock);
 
        if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
@@ -387,8 +370,9 @@ got_root:
                printk(KERN_ERR "AFFS: Cannot read boot block\n");
                goto out_error;
        }
-       chksum = be32_to_cpu(*(u32 *)boot_bh->b_data);
+       memcpy(sig, boot_bh->b_data, 4);
        brelse(boot_bh);
+       chksum = be32_to_cpu(*(__be32 *)sig);
 
        /* Dircache filesystems are compatible with non-dircache ones
         * when reading. As long as they aren't supported, writing is
@@ -399,7 +383,6 @@ got_root:
                printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",
                        sb->s_id);
                sb->s_flags |= MS_RDONLY;
-               sbi->s_flags |= SF_READONLY;
        }
        switch (chksum) {
                case MUFS_FS:
@@ -438,11 +421,11 @@ got_root:
        }
 
        if (mount_flags & SF_VERBOSE) {
-               chksum = cpu_to_be32(chksum);
-               printk(KERN_NOTICE "AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",
-                       AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0],
+               u8 len = AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0];
+               printk(KERN_NOTICE "AFFS: Mounting volume \"%.*s\": Type=%.3s\\%c, Blocksize=%d\n",
+                       len > 31 ? 31 : len,
                        AFFS_ROOT_TAIL(sb, root_bh)->disk_name + 1,
-                       (char *)&chksum,((char *)&chksum)[3] + '0',blocksize);
+                       sig, sig[3] + '0', blocksize);
        }
 
        sb->s_flags |= MS_NODEV | MS_NOSUID;
@@ -455,8 +438,10 @@ got_root:
        sbi->s_root_bh = root_bh;
        /* N.B. after this point s_root_bh must be released */
 
-       if (affs_init_bitmap(sb))
+       tmp_flags = sb->s_flags;
+       if (affs_init_bitmap(sb, &tmp_flags))
                goto out_error;
+       sb->s_flags = tmp_flags;
 
        /* set up enough so that it can read an inode */
 
@@ -477,11 +462,9 @@ got_root:
 out_error:
        if (root_inode)
                iput(root_inode);
-       if (sbi->s_bitmap)
-               kfree(sbi->s_bitmap);
+       kfree(sbi->s_bitmap);
        affs_brelse(root_bh);
-       if (sbi->s_prefix)
-               kfree(sbi->s_prefix);
+       kfree(sbi->s_prefix);
        kfree(sbi);
        sb->s_fs_info = NULL;
        return -EINVAL;
@@ -498,7 +481,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
        int                      reserved;
        int                      root_block;
        unsigned long            mount_flags;
-       unsigned long            read_only = sbi->s_flags & SF_READONLY;
+       int                      res = 0;
 
        pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
 
@@ -507,7 +490,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
        if (!parse_options(data,&uid,&gid,&mode,&reserved,&root_block,
            &blocksize,&sbi->s_prefix,sbi->s_volume,&mount_flags))
                return -EINVAL;
-       sbi->s_flags = mount_flags | read_only;
+       sbi->s_flags = mount_flags;
        sbi->s_mode  = mode;
        sbi->s_uid   = uid;
        sbi->s_gid   = gid;
@@ -518,19 +501,17 @@ affs_remount(struct super_block *sb, int *flags, char *data)
                sb->s_dirt = 1;
                while (sb->s_dirt)
                        affs_write_super(sb);
-               sb->s_flags |= MS_RDONLY;
-       } else if (!(sbi->s_flags & SF_READONLY)) {
-               sb->s_flags &= ~MS_RDONLY;
-       } else {
-               affs_warning(sb,"remount","Cannot remount fs read/write because of errors");
-               return -EINVAL;
-       }
-       return 0;
+               affs_free_bitmap(sb);
+       } else
+               res = affs_init_bitmap(sb, flags);
+
+       return res;
 }
 
 static int
-affs_statfs(struct super_block *sb, struct kstatfs *buf)
+affs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
+       struct super_block *sb = dentry->d_sb;
        int              free;
 
        pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",AFFS_SB(sb)->s_partition_size,
@@ -545,10 +526,11 @@ affs_statfs(struct super_block *sb, struct kstatfs *buf)
        return 0;
 }
 
-static struct super_block *affs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int affs_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, affs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super,
+                          mnt);
 }
 
 static struct file_system_type affs_fs_type = {