This source file includes following definitions.
- sysv_free_inode
- sysv_new_inode
- sysv_count_free_inodes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <linux/sched.h>
23 #include <linux/kernel.h>
24 #include <linux/fs.h>
25 #include <linux/sysv_fs.h>
26 #include <linux/stat.h>
27 #include <linux/string.h>
28 #include <linux/locks.h>
29
30
31
32
33
34
35
36 void sysv_free_inode(struct inode * inode)
37 {
38 struct super_block * sb;
39 unsigned int ino;
40 struct buffer_head * bh;
41 char * bh_data;
42 struct sysv_inode * raw_inode;
43
44 if (!inode)
45 return;
46 if (!inode->i_dev) {
47 printk("sysv_free_inode: inode has no device\n");
48 return;
49 }
50 if (inode->i_count != 1) {
51 printk("sysv_free_inode: inode has count=%d\n", inode->i_count);
52 return;
53 }
54 if (inode->i_nlink) {
55 printk("sysv_free_inode: inode has nlink=%d\n", inode->i_nlink);
56 return;
57 }
58 if (!(sb = inode->i_sb)) {
59 printk("sysv_free_inode: inode on nonexistent device\n");
60 return;
61 }
62 ino = inode->i_ino;
63 if (ino <= SYSV_ROOT_INO || ino > sb->sv_ninodes) {
64 printk("sysv_free_inode: inode 0,1,2 or nonexistent inode\n");
65 return;
66 }
67 if (!(bh = sysv_bread(sb, inode->i_dev, sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits), &bh_data))) {
68 printk("sysv_free_inode: unable to read inode block on device %d/%d\n",MAJOR(inode->i_dev),MINOR(inode->i_dev));
69 clear_inode(inode);
70 return;
71 }
72 raw_inode = (struct sysv_inode *) bh_data + ((ino-1) & sb->sv_inodes_per_block_1);
73 lock_super(sb);
74 if (*sb->sv_sb_fic_count < sb->sv_fic_size)
75 sb->sv_sb_fic_inodes[(*sb->sv_sb_fic_count)++] = ino;
76 (*sb->sv_sb_total_free_inodes)++;
77 mark_buffer_dirty(sb->sv_bh, 1);
78 sb->s_dirt = 1;
79 memset(raw_inode, 0, sizeof(struct sysv_inode));
80 mark_buffer_dirty(bh, 1);
81 unlock_super(sb);
82 brelse(bh);
83 clear_inode(inode);
84 }
85
86 struct inode * sysv_new_inode(const struct inode * dir)
87 {
88 struct inode * inode;
89 struct super_block * sb;
90 struct buffer_head * bh;
91 char * bh_data;
92 struct sysv_inode * raw_inode;
93 int i,j,ino,block;
94
95 if (!dir || !(inode = get_empty_inode()))
96 return NULL;
97 sb = dir->i_sb;
98 inode->i_sb = sb;
99 inode->i_flags = inode->i_sb->s_flags;
100 lock_super(sb);
101 if ((*sb->sv_sb_fic_count == 0)
102 || (sb->sv_sb_fic_inodes[(*sb->sv_sb_fic_count)-1] == 0)
103 ) {
104
105
106
107
108
109
110
111 for (i = 0, ino = SYSV_ROOT_INO+1, block = sb->sv_firstinodezone, j = SYSV_ROOT_INO ; i < sb->sv_fic_size && block < sb->sv_firstdatazone ; block++, j = 0) {
112 if (!(bh = sysv_bread(sb, sb->s_dev, block, &bh_data))) {
113 printk("sysv_new_inode: unable to read inode table\n");
114 break;
115
116 }
117 raw_inode = (struct sysv_inode *) bh_data + j;
118 for (; j < sb->sv_inodes_per_block && i < sb->sv_fic_size; ino++, j++, raw_inode++) {
119 if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0)
120 sb->sv_sb_fic_inodes[i++] = ino;
121 }
122 brelse(bh);
123 }
124 if (i == 0) {
125 iput(inode);
126 unlock_super(sb);
127 return NULL;
128 }
129 *sb->sv_sb_fic_count = i;
130 }
131
132 ino = sb->sv_sb_fic_inodes[--(*sb->sv_sb_fic_count)];
133 mark_buffer_dirty(sb->sv_bh, 1);
134 sb->s_dirt = 1;
135 inode->i_count = 1;
136 inode->i_nlink = 1;
137 inode->i_dev = sb->s_dev;
138 inode->i_uid = current->fsuid;
139 inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
140 inode->i_dirt = 1;
141 inode->i_ino = ino;
142 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
143 inode->i_op = NULL;
144 inode->i_blocks = inode->i_blksize = 0;
145 inode->u.sysv_i.i_lock = 0; inode->u.sysv_i.i_wait = NULL;
146 insert_inode_hash(inode);
147
148 inode->i_mode = 0;
149 inode->i_size = 0;
150 sysv_write_inode(inode);
151
152 inode->i_dirt = 1;
153
154 (*sb->sv_sb_total_free_inodes)--;
155 mark_buffer_dirty(sb->sv_bh, 1);
156 sb->s_dirt = 1;
157 unlock_super(sb);
158 return inode;
159 }
160
161 unsigned long sysv_count_free_inodes(struct super_block * sb)
162 {
163 #if 1
164 struct buffer_head * bh;
165 char * bh_data;
166 struct sysv_inode * raw_inode;
167 int j,block,count;
168
169
170 count = 0;
171 lock_super(sb);
172
173
174
175
176
177
178 for (block = sb->sv_firstinodezone, j = SYSV_ROOT_INO ; block < sb->sv_firstdatazone ; block++, j = 0) {
179 if (!(bh = sysv_bread(sb, sb->s_dev, block, &bh_data))) {
180 printk("sysv_count_free_inodes: unable to read inode table\n");
181 break;
182
183 }
184 raw_inode = (struct sysv_inode *) bh_data + j;
185 for (; j < sb->sv_inodes_per_block ; j++, raw_inode++)
186 if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0)
187 count++;
188 brelse(bh);
189 }
190 if (count != *sb->sv_sb_total_free_inodes) {
191 printk("sysv_count_free_inodes: free inode count was %d, correcting to %d\n",(short)(*sb->sv_sb_total_free_inodes),count);
192 if (!(sb->s_flags & MS_RDONLY)) {
193 *sb->sv_sb_total_free_inodes = count;
194 mark_buffer_dirty(sb->sv_bh, 1);
195 sb->s_dirt = 1;
196 }
197 }
198 unlock_super(sb);
199 return count;
200 #else
201 return *sb->sv_sb_total_free_inodes;
202 #endif
203 }
204