0001
0002 #include <linux/kernel.h>
0003 #include <linux/fs.h>
0004 #include <linux/buffer_head.h>
0005 #include <asm/div64.h>
0006 #include "omfs.h"
0007
0008 unsigned long omfs_count_free(struct super_block *sb)
0009 {
0010 unsigned int i;
0011 unsigned long sum = 0;
0012 struct omfs_sb_info *sbi = OMFS_SB(sb);
0013 int nbits = sb->s_blocksize * 8;
0014
0015 for (i = 0; i < sbi->s_imap_size; i++)
0016 sum += nbits - bitmap_weight(sbi->s_imap[i], nbits);
0017
0018 return sum;
0019 }
0020
0021
0022
0023
0024
0025
0026 static int count_run(unsigned long **addr, int nbits,
0027 int addrlen, int bit, int max)
0028 {
0029 int count = 0;
0030 int x;
0031
0032 for (; addrlen > 0; addrlen--, addr++) {
0033 x = find_next_bit(*addr, nbits, bit);
0034 count += x - bit;
0035
0036 if (x < nbits || count > max)
0037 return min(count, max);
0038
0039 bit = 0;
0040 }
0041 return min(count, max);
0042 }
0043
0044
0045
0046
0047
0048 static int set_run(struct super_block *sb, int map,
0049 int nbits, int bit, int count, int set)
0050 {
0051 int i;
0052 int err;
0053 struct buffer_head *bh;
0054 struct omfs_sb_info *sbi = OMFS_SB(sb);
0055
0056 err = -ENOMEM;
0057 bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
0058 if (!bh)
0059 goto out;
0060
0061 for (i = 0; i < count; i++, bit++) {
0062 if (bit >= nbits) {
0063 bit = 0;
0064 map++;
0065
0066 mark_buffer_dirty(bh);
0067 brelse(bh);
0068 bh = sb_bread(sb,
0069 clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
0070 if (!bh)
0071 goto out;
0072 }
0073 if (set) {
0074 set_bit(bit, sbi->s_imap[map]);
0075 set_bit(bit, (unsigned long *)bh->b_data);
0076 } else {
0077 clear_bit(bit, sbi->s_imap[map]);
0078 clear_bit(bit, (unsigned long *)bh->b_data);
0079 }
0080 }
0081 mark_buffer_dirty(bh);
0082 brelse(bh);
0083 err = 0;
0084 out:
0085 return err;
0086 }
0087
0088
0089
0090
0091 int omfs_allocate_block(struct super_block *sb, u64 block)
0092 {
0093 struct buffer_head *bh;
0094 struct omfs_sb_info *sbi = OMFS_SB(sb);
0095 int bits_per_entry = 8 * sb->s_blocksize;
0096 unsigned int map, bit;
0097 int ret = 0;
0098 u64 tmp;
0099
0100 tmp = block;
0101 bit = do_div(tmp, bits_per_entry);
0102 map = tmp;
0103
0104 mutex_lock(&sbi->s_bitmap_lock);
0105 if (map >= sbi->s_imap_size || test_and_set_bit(bit, sbi->s_imap[map]))
0106 goto out;
0107
0108 if (sbi->s_bitmap_ino > 0) {
0109 bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map);
0110 if (!bh)
0111 goto out;
0112
0113 set_bit(bit, (unsigned long *)bh->b_data);
0114 mark_buffer_dirty(bh);
0115 brelse(bh);
0116 }
0117 ret = 1;
0118 out:
0119 mutex_unlock(&sbi->s_bitmap_lock);
0120 return ret;
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130 int omfs_allocate_range(struct super_block *sb,
0131 int min_request,
0132 int max_request,
0133 u64 *return_block,
0134 int *return_size)
0135 {
0136 struct omfs_sb_info *sbi = OMFS_SB(sb);
0137 int bits_per_entry = 8 * sb->s_blocksize;
0138 int ret = 0;
0139 int i, run, bit;
0140
0141 mutex_lock(&sbi->s_bitmap_lock);
0142 for (i = 0; i < sbi->s_imap_size; i++) {
0143 bit = 0;
0144 while (bit < bits_per_entry) {
0145 bit = find_next_zero_bit(sbi->s_imap[i], bits_per_entry,
0146 bit);
0147
0148 if (bit == bits_per_entry)
0149 break;
0150
0151 run = count_run(&sbi->s_imap[i], bits_per_entry,
0152 sbi->s_imap_size-i, bit, max_request);
0153
0154 if (run >= min_request)
0155 goto found;
0156 bit += run;
0157 }
0158 }
0159 ret = -ENOSPC;
0160 goto out;
0161
0162 found:
0163 *return_block = (u64) i * bits_per_entry + bit;
0164 *return_size = run;
0165 ret = set_run(sb, i, bits_per_entry, bit, run, 1);
0166
0167 out:
0168 mutex_unlock(&sbi->s_bitmap_lock);
0169 return ret;
0170 }
0171
0172
0173
0174
0175 int omfs_clear_range(struct super_block *sb, u64 block, int count)
0176 {
0177 struct omfs_sb_info *sbi = OMFS_SB(sb);
0178 int bits_per_entry = 8 * sb->s_blocksize;
0179 u64 tmp;
0180 unsigned int map, bit;
0181 int ret;
0182
0183 tmp = block;
0184 bit = do_div(tmp, bits_per_entry);
0185 map = tmp;
0186
0187 if (map >= sbi->s_imap_size)
0188 return 0;
0189
0190 mutex_lock(&sbi->s_bitmap_lock);
0191 ret = set_run(sb, map, bits_per_entry, bit, count, 0);
0192 mutex_unlock(&sbi->s_bitmap_lock);
0193 return ret;
0194 }