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); |
