|
|
1.1 root 1: /* bitmap.c contains the code that handles the inode and block bitmaps */
2: #include <string.h>
3:
4: #include <linux/sched.h>
5: #include <linux/kernel.h>
6:
7: #define clear_block(addr) \
8: __asm__("cld\n\t" \
9: "rep\n\t" \
10: "stosl" \
11: ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
12:
13: #define set_bit(nr,addr) ({\
14: register int res __asm__("ax"); \
15: __asm__("btsl %2,%3\n\tsetb %%al":"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
16: res;})
17:
18: #define clear_bit(nr,addr) ({\
19: register int res __asm__("ax"); \
20: __asm__("btrl %2,%3\n\tsetnb %%al":"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
21: res;})
22:
23: #define find_first_zero(addr) ({ \
24: int __res; \
25: __asm__("cld\n" \
26: "1:\tlodsl\n\t" \
27: "notl %%eax\n\t" \
28: "bsfl %%eax,%%edx\n\t" \
29: "je 2f\n\t" \
30: "addl %%edx,%%ecx\n\t" \
31: "jmp 3f\n" \
32: "2:\taddl $32,%%ecx\n\t" \
33: "cmpl $8192,%%ecx\n\t" \
34: "jl 1b\n" \
35: "3:" \
36: :"=c" (__res):"c" (0),"S" (addr):"ax","dx","si"); \
37: __res;})
38:
39: void free_block(int dev, int block)
40: {
41: struct super_block * sb;
42: struct buffer_head * bh;
43:
44: if (!(sb = get_super(dev)))
45: panic("trying to free block on nonexistent device");
46: if (block < sb->s_firstdatazone || block >= sb->s_nzones)
47: panic("trying to free block not in datazone");
48: bh = get_hash_table(dev,block);
49: if (bh) {
50: if (bh->b_count != 1) {
51: printk("trying to free block (%04x:%d), count=%d\n",
52: dev,block,bh->b_count);
53: return;
54: }
55: bh->b_dirt=0;
56: bh->b_uptodate=0;
57: brelse(bh);
58: }
59: block -= sb->s_firstdatazone - 1 ;
60: if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) {
61: printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1);
62: panic("free_block: bit already cleared");
63: }
64: sb->s_zmap[block/8192]->b_dirt = 1;
65: }
66:
67: int new_block(int dev)
68: {
69: struct buffer_head * bh;
70: struct super_block * sb;
71: int i,j;
72:
73: if (!(sb = get_super(dev)))
74: panic("trying to get new block from nonexistant device");
75: j = 8192;
76: for (i=0 ; i<8 ; i++)
77: if (bh=sb->s_zmap[i])
78: if ((j=find_first_zero(bh->b_data))<8192)
79: break;
80: if (i>=8 || !bh || j>=8192)
81: return 0;
82: if (set_bit(j,bh->b_data))
83: panic("new_block: bit already set");
84: bh->b_dirt = 1;
85: j += i*8192 + sb->s_firstdatazone-1;
86: if (j >= sb->s_nzones)
87: return 0;
88: if (!(bh=getblk(dev,j)))
89: panic("new_block: cannot get block");
90: if (bh->b_count != 1)
91: panic("new block: count is != 1");
92: clear_block(bh->b_data);
93: bh->b_uptodate = 1;
94: bh->b_dirt = 1;
95: brelse(bh);
96: return j;
97: }
98:
99: void free_inode(struct m_inode * inode)
100: {
101: struct super_block * sb;
102: struct buffer_head * bh;
103:
104: if (!inode)
105: return;
106: if (!inode->i_dev) {
107: memset(inode,0,sizeof(*inode));
108: return;
109: }
110: if (inode->i_count>1) {
111: printk("trying to free inode with count=%d\n",inode->i_count);
112: panic("free_inode");
113: }
114: if (inode->i_nlinks)
115: panic("trying to free inode with links");
116: if (!(sb = get_super(inode->i_dev)))
117: panic("trying to free inode on nonexistent device");
118: if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)
119: panic("trying to free inode 0 or nonexistant inode");
120: if (!(bh=sb->s_imap[inode->i_num>>13]))
121: panic("nonexistent imap in superblock");
122: if (clear_bit(inode->i_num&8191,bh->b_data))
123: panic("free_inode: bit already cleared");
124: bh->b_dirt = 1;
125: memset(inode,0,sizeof(*inode));
126: }
127:
128: struct m_inode * new_inode(int dev)
129: {
130: struct m_inode * inode;
131: struct super_block * sb;
132: struct buffer_head * bh;
133: int i,j;
134:
135: if (!(inode=get_empty_inode()))
136: return NULL;
137: if (!(sb = get_super(dev)))
138: panic("new_inode with unknown device");
139: j = 8192;
140: for (i=0 ; i<8 ; i++)
141: if (bh=sb->s_imap[i])
142: if ((j=find_first_zero(bh->b_data))<8192)
143: break;
144: if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {
145: iput(inode);
146: return NULL;
147: }
148: if (set_bit(j,bh->b_data))
149: panic("new_inode: bit already set");
150: bh->b_dirt = 1;
151: inode->i_count=1;
152: inode->i_nlinks=1;
153: inode->i_dev=dev;
154: inode->i_dirt=1;
155: inode->i_num = j + i*8192;
156: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
157: return inode;
158: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.