vserver 1.9.5.x5
[linux-2.6.git] / fs / affs / bitmap.c
index 095ef77..b0b9536 100644 (file)
@@ -7,21 +7,13 @@
  *  block allocation, deallocation, calculation of free space.
  */
 
-#include <linux/time.h>
-#include <linux/affs_fs.h>
-#include <linux/stat.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/bitops.h>
-#include <linux/amigaffs.h>
-#include <linux/buffer_head.h>
+#include "affs.h"
 
 /* This is, of course, shamelessly stolen from fs/minix */
 
 static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
 
-u32
+static u32
 affs_count_free_bits(u32 blocksize, const void *data)
 {
        const u32 *map;
@@ -72,7 +64,7 @@ affs_free_block(struct super_block *sb, u32 block)
        struct affs_bm_info *bm;
        struct buffer_head *bh;
        u32 blk, bmap, bit, mask, tmp;
-       u32 *data;
+       __be32 *data;
 
        pr_debug("AFFS: free_block(%u)\n", block);
 
@@ -97,7 +89,7 @@ affs_free_block(struct super_block *sb, u32 block)
        }
 
        mask = 1 << (bit & 31);
-       data = (u32 *)bh->b_data + bit / 32 + 1;
+       data = (__be32 *)bh->b_data + bit / 32 + 1;
 
        /* mark block free */
        tmp = be32_to_cpu(*data);
@@ -106,8 +98,8 @@ affs_free_block(struct super_block *sb, u32 block)
        *data = cpu_to_be32(tmp | mask);
 
        /* fix checksum */
-       tmp = be32_to_cpu(*(u32 *)bh->b_data);
-       *(u32 *)bh->b_data = cpu_to_be32(tmp - mask);
+       tmp = be32_to_cpu(*(__be32 *)bh->b_data);
+       *(__be32 *)bh->b_data = cpu_to_be32(tmp - mask);
 
        mark_buffer_dirty(bh);
        sb->s_dirt = 1;
@@ -149,7 +141,7 @@ affs_alloc_block(struct inode *inode, u32 goal)
        struct affs_sb_info *sbi;
        struct affs_bm_info *bm;
        struct buffer_head *bh;
-       u32 *data, *enddata;
+       __be32 *data, *enddata;
        u32 blk, bmap, bit, mask, mask2, tmp;
        int i;
 
@@ -211,8 +203,8 @@ find_bmap_bit:
 
        /* find an unused block in this bitmap block */
        bit = blk % sbi->s_bmap_bits;
-       data = (u32 *)bh->b_data + bit / 32 + 1;
-       enddata = (u32 *)((u8 *)bh->b_data + sb->s_blocksize);
+       data = (__be32 *)bh->b_data + bit / 32 + 1;
+       enddata = (__be32 *)((u8 *)bh->b_data + sb->s_blocksize);
        mask = ~0UL << (bit & 31);
        blk &= ~31UL;
 
@@ -228,8 +220,8 @@ find_bmap_bit:
                         * if scan didn't start at 0, try next bmap
                         */
                        goto find_bmap;
-       } while (!(tmp = *data));
-       tmp = be32_to_cpu(tmp);
+       } while (!*data);
+       tmp = be32_to_cpu(*data);
        mask = ~0;
 
 find_bit:
@@ -251,8 +243,8 @@ find_bit:
        *data = cpu_to_be32(tmp & ~mask);
 
        /* fix checksum */
-       tmp = be32_to_cpu(*(u32 *)bh->b_data);
-       *(u32 *)bh->b_data = cpu_to_be32(tmp + mask);
+       tmp = be32_to_cpu(*(__be32 *)bh->b_data);
+       *(__be32 *)bh->b_data = cpu_to_be32(tmp + mask);
 
        mark_buffer_dirty(bh);
        sb->s_dirt = 1;
@@ -272,23 +264,22 @@ err_full:
        return 0;
 }
 
-int
-affs_init_bitmap(struct super_block *sb)
+int affs_init_bitmap(struct super_block *sb, int *flags)
 {
        struct affs_bm_info *bm;
        struct buffer_head *bmap_bh = NULL, *bh = NULL;
-       u32 *bmap_blk;
+       __be32 *bmap_blk;
        u32 size, blk, end, offset, mask;
        int i, res = 0;
        struct affs_sb_info *sbi = AFFS_SB(sb);
 
-       if (sb->s_flags & MS_RDONLY)
+       if (*flags & MS_RDONLY)
                return 0;
 
        if (!AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag) {
                printk(KERN_NOTICE "AFFS: Bitmap invalid - mounting %s read only\n",
                        sb->s_id);
-               sb->s_flags |= MS_RDONLY;
+               *flags |= MS_RDONLY;
                return 0;
        }
 
@@ -301,11 +292,11 @@ affs_init_bitmap(struct super_block *sb)
        bm = sbi->s_bitmap = kmalloc(size, GFP_KERNEL);
        if (!sbi->s_bitmap) {
                printk(KERN_ERR "AFFS: Bitmap allocation failed\n");
-               return 1;
+               return -ENOMEM;
        }
        memset(sbi->s_bitmap, 0, size);
 
-       bmap_blk = (u32 *)sbi->s_root_bh->b_data;
+       bmap_blk = (__be32 *)sbi->s_root_bh->b_data;
        blk = sb->s_blocksize / 4 - 49;
        end = blk + 25;
 
@@ -316,13 +307,13 @@ affs_init_bitmap(struct super_block *sb)
                bh = affs_bread(sb, bm->bm_key);
                if (!bh) {
                        printk(KERN_ERR "AFFS: Cannot read bitmap\n");
-                       res = 1;
+                       res = -EIO;
                        goto out;
                }
                if (affs_checksum_block(sb, bh)) {
                        printk(KERN_WARNING "AFFS: Bitmap %u invalid - mounting %s read only.\n",
                               bm->bm_key, sb->s_id);
-                       sb->s_flags |= MS_RDONLY;
+                       *flags |= MS_RDONLY;
                        goto out;
                }
                pr_debug("AFFS: read bitmap block %d: %d\n", blk, bm->bm_key);
@@ -338,10 +329,10 @@ affs_init_bitmap(struct super_block *sb)
                bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk]));
                if (!bmap_bh) {
                        printk(KERN_ERR "AFFS: Cannot read bitmap extension\n");
-                       res = 1;
+                       res = -EIO;
                        goto out;
                }
-               bmap_blk = (u32 *)bmap_bh->b_data;
+               bmap_blk = (__be32 *)bmap_bh->b_data;
                blk = 0;
                end = sb->s_blocksize / 4 - 1;
        }
@@ -355,23 +346,23 @@ affs_init_bitmap(struct super_block *sb)
                u32 old, new;
 
                /* Mark unused bits in the last word as allocated */
-               old = be32_to_cpu(((u32 *)bh->b_data)[offset]);
+               old = be32_to_cpu(((__be32 *)bh->b_data)[offset]);
                new = old & mask;
                //if (old != new) {
-                       ((u32 *)bh->b_data)[offset] = cpu_to_be32(new);
+                       ((__be32 *)bh->b_data)[offset] = cpu_to_be32(new);
                        /* fix checksum */
                        //new -= old;
-                       //old = be32_to_cpu(*(u32 *)bh->b_data);
-                       //*(u32 *)bh->b_data = cpu_to_be32(old - new);
+                       //old = be32_to_cpu(*(__be32 *)bh->b_data);
+                       //*(__be32 *)bh->b_data = cpu_to_be32(old - new);
                        //mark_buffer_dirty(bh);
                //}
                /* correct offset for the bitmap count below */
                //offset++;
        }
        while (++offset < sb->s_blocksize / 4)
-               ((u32 *)bh->b_data)[offset] = 0;
-       ((u32 *)bh->b_data)[0] = 0;
-       ((u32 *)bh->b_data)[0] = cpu_to_be32(-affs_checksum_block(sb, bh));
+               ((__be32 *)bh->b_data)[offset] = 0;
+       ((__be32 *)bh->b_data)[0] = 0;
+       ((__be32 *)bh->b_data)[0] = cpu_to_be32(-affs_checksum_block(sb, bh));
        mark_buffer_dirty(bh);
 
        /* recalculate bitmap count for last block */
@@ -383,3 +374,17 @@ out:
        affs_brelse(bmap_bh);
        return res;
 }
+
+void affs_free_bitmap(struct super_block *sb)
+{
+       struct affs_sb_info *sbi = AFFS_SB(sb);
+
+       if (!sbi->s_bitmap)
+               return;
+
+       affs_brelse(sbi->s_bmap_bh);
+       sbi->s_bmap_bh = NULL;
+       sbi->s_last_bmap = ~0;
+       kfree(sbi->s_bitmap);
+       sbi->s_bitmap = NULL;
+}