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