This source file includes following definitions.
- free_block
- new_block
- free_inode
- new_inode
1
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 }