diff options
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r-- | fs/bfs/inode.c | 116 |
1 files changed, 39 insertions, 77 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index f22a7d3dc362..c4daf0f5fc02 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -31,7 +31,6 @@ MODULE_LICENSE("GPL"); | |||
31 | #define dprintf(x...) | 31 | #define dprintf(x...) |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | static void bfs_write_super(struct super_block *s); | ||
35 | void dump_imap(const char *prefix, struct super_block *s); | 34 | void dump_imap(const char *prefix, struct super_block *s); |
36 | 35 | ||
37 | struct inode *bfs_iget(struct super_block *sb, unsigned long ino) | 36 | struct inode *bfs_iget(struct super_block *sb, unsigned long ino) |
@@ -99,6 +98,24 @@ error: | |||
99 | return ERR_PTR(-EIO); | 98 | return ERR_PTR(-EIO); |
100 | } | 99 | } |
101 | 100 | ||
101 | static struct bfs_inode *find_inode(struct super_block *sb, u16 ino, struct buffer_head **p) | ||
102 | { | ||
103 | if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(sb)->si_lasti)) { | ||
104 | printf("Bad inode number %s:%08x\n", sb->s_id, ino); | ||
105 | return ERR_PTR(-EIO); | ||
106 | } | ||
107 | |||
108 | ino -= BFS_ROOT_INO; | ||
109 | |||
110 | *p = sb_bread(sb, 1 + ino / BFS_INODES_PER_BLOCK); | ||
111 | if (!*p) { | ||
112 | printf("Unable to read inode %s:%08x\n", sb->s_id, ino); | ||
113 | return ERR_PTR(-EIO); | ||
114 | } | ||
115 | |||
116 | return (struct bfs_inode *)(*p)->b_data + ino % BFS_INODES_PER_BLOCK; | ||
117 | } | ||
118 | |||
102 | static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) | 119 | static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
103 | { | 120 | { |
104 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); | 121 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); |
@@ -106,28 +123,15 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
106 | unsigned long i_sblock; | 123 | unsigned long i_sblock; |
107 | struct bfs_inode *di; | 124 | struct bfs_inode *di; |
108 | struct buffer_head *bh; | 125 | struct buffer_head *bh; |
109 | int block, off; | ||
110 | int err = 0; | 126 | int err = 0; |
111 | 127 | ||
112 | dprintf("ino=%08x\n", ino); | 128 | dprintf("ino=%08x\n", ino); |
113 | 129 | ||
114 | if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) { | 130 | di = find_inode(inode->i_sb, ino, &bh); |
115 | printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino); | 131 | if (IS_ERR(di)) |
116 | return -EIO; | 132 | return PTR_ERR(di); |
117 | } | ||
118 | 133 | ||
119 | mutex_lock(&info->bfs_lock); | 134 | mutex_lock(&info->bfs_lock); |
120 | block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; | ||
121 | bh = sb_bread(inode->i_sb, block); | ||
122 | if (!bh) { | ||
123 | printf("Unable to read inode %s:%08x\n", | ||
124 | inode->i_sb->s_id, ino); | ||
125 | mutex_unlock(&info->bfs_lock); | ||
126 | return -EIO; | ||
127 | } | ||
128 | |||
129 | off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; | ||
130 | di = (struct bfs_inode *)bh->b_data + off; | ||
131 | 135 | ||
132 | if (ino == BFS_ROOT_INO) | 136 | if (ino == BFS_ROOT_INO) |
133 | di->i_vtype = cpu_to_le32(BFS_VDIR); | 137 | di->i_vtype = cpu_to_le32(BFS_VDIR); |
@@ -158,12 +162,11 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
158 | return err; | 162 | return err; |
159 | } | 163 | } |
160 | 164 | ||
161 | static void bfs_delete_inode(struct inode *inode) | 165 | static void bfs_evict_inode(struct inode *inode) |
162 | { | 166 | { |
163 | unsigned long ino = inode->i_ino; | 167 | unsigned long ino = inode->i_ino; |
164 | struct bfs_inode *di; | 168 | struct bfs_inode *di; |
165 | struct buffer_head *bh; | 169 | struct buffer_head *bh; |
166 | int block, off; | ||
167 | struct super_block *s = inode->i_sb; | 170 | struct super_block *s = inode->i_sb; |
168 | struct bfs_sb_info *info = BFS_SB(s); | 171 | struct bfs_sb_info *info = BFS_SB(s); |
169 | struct bfs_inode_info *bi = BFS_I(inode); | 172 | struct bfs_inode_info *bi = BFS_I(inode); |
@@ -171,28 +174,19 @@ static void bfs_delete_inode(struct inode *inode) | |||
171 | dprintf("ino=%08lx\n", ino); | 174 | dprintf("ino=%08lx\n", ino); |
172 | 175 | ||
173 | truncate_inode_pages(&inode->i_data, 0); | 176 | truncate_inode_pages(&inode->i_data, 0); |
177 | invalidate_inode_buffers(inode); | ||
178 | end_writeback(inode); | ||
174 | 179 | ||
175 | if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) { | 180 | if (inode->i_nlink) |
176 | printf("invalid ino=%08lx\n", ino); | ||
177 | return; | 181 | return; |
178 | } | ||
179 | |||
180 | inode->i_size = 0; | ||
181 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | ||
182 | mutex_lock(&info->bfs_lock); | ||
183 | mark_inode_dirty(inode); | ||
184 | 182 | ||
185 | block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; | 183 | di = find_inode(s, inode->i_ino, &bh); |
186 | bh = sb_bread(s, block); | 184 | if (IS_ERR(di)) |
187 | if (!bh) { | ||
188 | printf("Unable to read inode %s:%08lx\n", | ||
189 | inode->i_sb->s_id, ino); | ||
190 | mutex_unlock(&info->bfs_lock); | ||
191 | return; | 185 | return; |
192 | } | 186 | |
193 | off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; | 187 | mutex_lock(&info->bfs_lock); |
194 | di = (struct bfs_inode *)bh->b_data + off; | 188 | /* clear on-disk inode */ |
195 | memset((void *)di, 0, sizeof(struct bfs_inode)); | 189 | memset(di, 0, sizeof(struct bfs_inode)); |
196 | mark_buffer_dirty(bh); | 190 | mark_buffer_dirty(bh); |
197 | brelse(bh); | 191 | brelse(bh); |
198 | 192 | ||
@@ -209,32 +203,9 @@ static void bfs_delete_inode(struct inode *inode) | |||
209 | * "last block of the last file" even if there is no | 203 | * "last block of the last file" even if there is no |
210 | * real file there, saves us 1 gap. | 204 | * real file there, saves us 1 gap. |
211 | */ | 205 | */ |
212 | if (info->si_lf_eblk == bi->i_eblock) { | 206 | if (info->si_lf_eblk == bi->i_eblock) |
213 | info->si_lf_eblk = bi->i_sblock - 1; | 207 | info->si_lf_eblk = bi->i_sblock - 1; |
214 | mark_buffer_dirty(info->si_sbh); | ||
215 | } | ||
216 | mutex_unlock(&info->bfs_lock); | 208 | mutex_unlock(&info->bfs_lock); |
217 | clear_inode(inode); | ||
218 | } | ||
219 | |||
220 | static int bfs_sync_fs(struct super_block *sb, int wait) | ||
221 | { | ||
222 | struct bfs_sb_info *info = BFS_SB(sb); | ||
223 | |||
224 | mutex_lock(&info->bfs_lock); | ||
225 | mark_buffer_dirty(info->si_sbh); | ||
226 | sb->s_dirt = 0; | ||
227 | mutex_unlock(&info->bfs_lock); | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static void bfs_write_super(struct super_block *sb) | ||
233 | { | ||
234 | if (!(sb->s_flags & MS_RDONLY)) | ||
235 | bfs_sync_fs(sb, 1); | ||
236 | else | ||
237 | sb->s_dirt = 0; | ||
238 | } | 209 | } |
239 | 210 | ||
240 | static void bfs_put_super(struct super_block *s) | 211 | static void bfs_put_super(struct super_block *s) |
@@ -246,10 +217,6 @@ static void bfs_put_super(struct super_block *s) | |||
246 | 217 | ||
247 | lock_kernel(); | 218 | lock_kernel(); |
248 | 219 | ||
249 | if (s->s_dirt) | ||
250 | bfs_write_super(s); | ||
251 | |||
252 | brelse(info->si_sbh); | ||
253 | mutex_destroy(&info->bfs_lock); | 220 | mutex_destroy(&info->bfs_lock); |
254 | kfree(info->si_imap); | 221 | kfree(info->si_imap); |
255 | kfree(info); | 222 | kfree(info); |
@@ -319,10 +286,8 @@ static const struct super_operations bfs_sops = { | |||
319 | .alloc_inode = bfs_alloc_inode, | 286 | .alloc_inode = bfs_alloc_inode, |
320 | .destroy_inode = bfs_destroy_inode, | 287 | .destroy_inode = bfs_destroy_inode, |
321 | .write_inode = bfs_write_inode, | 288 | .write_inode = bfs_write_inode, |
322 | .delete_inode = bfs_delete_inode, | 289 | .evict_inode = bfs_evict_inode, |
323 | .put_super = bfs_put_super, | 290 | .put_super = bfs_put_super, |
324 | .write_super = bfs_write_super, | ||
325 | .sync_fs = bfs_sync_fs, | ||
326 | .statfs = bfs_statfs, | 291 | .statfs = bfs_statfs, |
327 | }; | 292 | }; |
328 | 293 | ||
@@ -349,7 +314,7 @@ void dump_imap(const char *prefix, struct super_block *s) | |||
349 | 314 | ||
350 | static int bfs_fill_super(struct super_block *s, void *data, int silent) | 315 | static int bfs_fill_super(struct super_block *s, void *data, int silent) |
351 | { | 316 | { |
352 | struct buffer_head *bh; | 317 | struct buffer_head *bh, *sbh; |
353 | struct bfs_super_block *bfs_sb; | 318 | struct bfs_super_block *bfs_sb; |
354 | struct inode *inode; | 319 | struct inode *inode; |
355 | unsigned i, imap_len; | 320 | unsigned i, imap_len; |
@@ -365,10 +330,10 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
365 | 330 | ||
366 | sb_set_blocksize(s, BFS_BSIZE); | 331 | sb_set_blocksize(s, BFS_BSIZE); |
367 | 332 | ||
368 | info->si_sbh = sb_bread(s, 0); | 333 | sbh = sb_bread(s, 0); |
369 | if (!info->si_sbh) | 334 | if (!sbh) |
370 | goto out; | 335 | goto out; |
371 | bfs_sb = (struct bfs_super_block *)info->si_sbh->b_data; | 336 | bfs_sb = (struct bfs_super_block *)sbh->b_data; |
372 | if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) { | 337 | if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) { |
373 | if (!silent) | 338 | if (!silent) |
374 | printf("No BFS filesystem on %s (magic=%08x)\n", | 339 | printf("No BFS filesystem on %s (magic=%08x)\n", |
@@ -472,10 +437,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) | |||
472 | info->si_lf_eblk = eblock; | 437 | info->si_lf_eblk = eblock; |
473 | } | 438 | } |
474 | brelse(bh); | 439 | brelse(bh); |
475 | if (!(s->s_flags & MS_RDONLY)) { | 440 | brelse(sbh); |
476 | mark_buffer_dirty(info->si_sbh); | ||
477 | s->s_dirt = 1; | ||
478 | } | ||
479 | dump_imap("read_super", s); | 441 | dump_imap("read_super", s); |
480 | return 0; | 442 | return 0; |
481 | 443 | ||
@@ -485,7 +447,7 @@ out3: | |||
485 | out2: | 447 | out2: |
486 | kfree(info->si_imap); | 448 | kfree(info->si_imap); |
487 | out1: | 449 | out1: |
488 | brelse(info->si_sbh); | 450 | brelse(sbh); |
489 | out: | 451 | out: |
490 | mutex_destroy(&info->bfs_lock); | 452 | mutex_destroy(&info->bfs_lock); |
491 | kfree(info); | 453 | kfree(info); |