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 panic("sysv_free_inode: unable to read inode block");
69 return;
70 }
71 raw_inode = (struct sysv_inode *) bh_data + ((ino-1) & sb->sv_inodes_per_block_1);
72 lock_super(sb);
73 if (*sb->sv_sb_fic_count < sb->sv_fic_size)
74 sb->sv_sb_fic_inodes[(*sb->sv_sb_fic_count)++] = ino;
75 (*sb->sv_sb_total_free_inodes)++;
76 sb->sv_bh->b_dirt = 1;
77 sb->s_dirt = 1;
78 memset(raw_inode, 0, sizeof(struct sysv_inode));
79 bh->b_dirt = 1;
80 unlock_super(sb);
81 brelse(bh);
82 clear_inode(inode);
83 }
84
85 struct inode * sysv_new_inode(const struct inode * dir)
86 {
87 struct inode * inode;
88 struct super_block * sb;
89 struct buffer_head * bh;
90 char * bh_data;
91 struct sysv_inode * raw_inode;
92 int i,j,ino,block;
93
94 if (!dir || !(inode = get_empty_inode()))
95 return NULL;
96 sb = dir->i_sb;
97 inode->i_sb = sb;
98 inode->i_flags = inode->i_sb->s_flags;
99 lock_super(sb);
100 if ((*sb->sv_sb_fic_count == 0)
101 || (sb->sv_sb_fic_inodes[(*sb->sv_sb_fic_count)-1] == 0)
102 ) {
103
104
105
106
107
108
109
110 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) {
111 if (!(bh = sysv_bread(sb, sb->s_dev, block, &bh_data))) {
112 printk("sysv_new_inode: unable to read inode table\n");
113 break;
114
115 }
116 raw_inode = (struct sysv_inode *) bh_data + j;
117 for (; j < sb->sv_inodes_per_block && i < sb->sv_fic_size; ino++, j++, raw_inode++) {
118 if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0)
119 sb->sv_sb_fic_inodes[i++] = ino;
120 }
121 brelse(bh);
122 }
123 if (i == 0) {
124 iput(inode);
125 unlock_super(sb);
126 return NULL;
127 }
128 *sb->sv_sb_fic_count = i;
129 }
130
131 ino = sb->sv_sb_fic_inodes[--(*sb->sv_sb_fic_count)];
132 sb->sv_bh->b_dirt = 1;
133 sb->s_dirt = 1;
134 inode->i_count = 1;
135 inode->i_nlink = 1;
136 inode->i_dev = sb->s_dev;
137 inode->i_uid = current->euid;
138 inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->egid;
139 inode->i_dirt = 1;
140 inode->i_ino = ino;
141 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
142 inode->i_op = NULL;
143 inode->i_blocks = inode->i_blksize = 0;
144 inode->u.sysv_i.i_lock = 0; inode->u.sysv_i.i_wait = NULL;
145 insert_inode_hash(inode);
146
147 inode->i_mode = 0;
148 inode->i_size = 0;
149 sysv_write_inode(inode);
150
151 inode->i_dirt = 1;
152
153 (*sb->sv_sb_total_free_inodes)--;
154 sb->sv_bh->b_dirt = 1;
155 sb->s_dirt = 1;
156 unlock_super(sb);
157 return inode;
158 }
159
160 unsigned long sysv_count_free_inodes(struct super_block * sb)
161 {
162 #if 1
163 struct buffer_head * bh;
164 char * bh_data;
165 struct sysv_inode * raw_inode;
166 int j,block,count;
167
168
169 count = 0;
170 lock_super(sb);
171
172
173
174
175
176
177 for (block = sb->sv_firstinodezone, j = SYSV_ROOT_INO ; block < sb->sv_firstdatazone ; block++, j = 0) {
178 if (!(bh = sysv_bread(sb, sb->s_dev, block, &bh_data))) {
179 printk("sysv_count_free_inodes: unable to read inode table\n");
180 break;
181
182 }
183 raw_inode = (struct sysv_inode *) bh_data + j;
184 for (; j < sb->sv_inodes_per_block ; j++, raw_inode++)
185 if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0)
186 count++;
187 brelse(bh);
188 }
189 if (count != *sb->sv_sb_total_free_inodes) {
190 printk("sysv_count_free_inodes: free inode count was %d, correcting to %d\n",(short)(*sb->sv_sb_total_free_inodes),count);
191 if (!(sb->s_flags & MS_RDONLY)) {
192 *sb->sv_sb_total_free_inodes = count;
193 sb->sv_bh->b_dirt = 1;
194 sb->s_dirt = 1;
195 }
196 }
197 unlock_super(sb);
198 return count;
199 #else
200 return *sb->sv_sb_total_free_inodes;
201 #endif
202 }
203