aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r--fs/bfs/inode.c116
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
34static void bfs_write_super(struct super_block *s);
35void dump_imap(const char *prefix, struct super_block *s); 34void dump_imap(const char *prefix, struct super_block *s);
36 35
37struct inode *bfs_iget(struct super_block *sb, unsigned long ino) 36struct 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
101static 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
102static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) 119static 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
161static void bfs_delete_inode(struct inode *inode) 165static 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
220static 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
232static 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
240static void bfs_put_super(struct super_block *s) 211static 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
350static int bfs_fill_super(struct super_block *s, void *data, int silent) 315static 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:
485out2: 447out2:
486 kfree(info->si_imap); 448 kfree(info->si_imap);
487out1: 449out1:
488 brelse(info->si_sbh); 450 brelse(sbh);
489out: 451out:
490 mutex_destroy(&info->bfs_lock); 452 mutex_destroy(&info->bfs_lock);
491 kfree(info); 453 kfree(info);