.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * fs/bfs/inode.c |
---|
3 | 4 | * BFS superblock and inode operations. |
---|
4 | | - * Copyright (C) 1999-2006 Tigran Aivazian <aivazian.tigran@gmail.com> |
---|
| 5 | + * Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com> |
---|
5 | 6 | * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. |
---|
6 | | - * |
---|
7 | | - * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005. |
---|
| 7 | + * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005. |
---|
8 | 8 | */ |
---|
9 | 9 | |
---|
10 | 10 | #include <linux/module.h> |
---|
.. | .. |
---|
22 | 22 | MODULE_AUTHOR("Tigran Aivazian <aivazian.tigran@gmail.com>"); |
---|
23 | 23 | MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux"); |
---|
24 | 24 | MODULE_LICENSE("GPL"); |
---|
| 25 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
---|
25 | 26 | |
---|
26 | 27 | #undef DEBUG |
---|
27 | 28 | |
---|
.. | .. |
---|
118 | 119 | { |
---|
119 | 120 | struct bfs_sb_info *info = BFS_SB(inode->i_sb); |
---|
120 | 121 | unsigned int ino = (u16)inode->i_ino; |
---|
121 | | - unsigned long i_sblock; |
---|
| 122 | + unsigned long i_sblock; |
---|
122 | 123 | struct bfs_inode *di; |
---|
123 | 124 | struct buffer_head *bh; |
---|
124 | 125 | int err = 0; |
---|
125 | 126 | |
---|
126 | | - dprintf("ino=%08x\n", ino); |
---|
| 127 | + dprintf("ino=%08x\n", ino); |
---|
127 | 128 | |
---|
128 | 129 | di = find_inode(inode->i_sb, ino, &bh); |
---|
129 | 130 | if (IS_ERR(di)) |
---|
.. | .. |
---|
144 | 145 | di->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
---|
145 | 146 | di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); |
---|
146 | 147 | di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); |
---|
147 | | - i_sblock = BFS_I(inode)->i_sblock; |
---|
| 148 | + i_sblock = BFS_I(inode)->i_sblock; |
---|
148 | 149 | di->i_sblock = cpu_to_le32(i_sblock); |
---|
149 | 150 | di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock); |
---|
150 | 151 | di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1); |
---|
.. | .. |
---|
188 | 189 | mark_buffer_dirty(bh); |
---|
189 | 190 | brelse(bh); |
---|
190 | 191 | |
---|
191 | | - if (bi->i_dsk_ino) { |
---|
| 192 | + if (bi->i_dsk_ino) { |
---|
192 | 193 | if (bi->i_sblock) |
---|
193 | 194 | info->si_freeb += bi->i_eblock + 1 - bi->i_sblock; |
---|
194 | 195 | info->si_freei++; |
---|
195 | 196 | clear_bit(ino, info->si_imap); |
---|
196 | | - bfs_dump_imap("delete_inode", s); |
---|
197 | | - } |
---|
| 197 | + bfs_dump_imap("evict_inode", s); |
---|
| 198 | + } |
---|
198 | 199 | |
---|
199 | 200 | /* |
---|
200 | 201 | * If this was the last file, make the previous block |
---|
.. | .. |
---|
214 | 215 | return; |
---|
215 | 216 | |
---|
216 | 217 | mutex_destroy(&info->bfs_lock); |
---|
217 | | - kfree(info->si_imap); |
---|
218 | 218 | kfree(info); |
---|
219 | 219 | s->s_fs_info = NULL; |
---|
220 | 220 | } |
---|
.. | .. |
---|
230 | 230 | buf->f_bfree = buf->f_bavail = info->si_freeb; |
---|
231 | 231 | buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO; |
---|
232 | 232 | buf->f_ffree = info->si_freei; |
---|
233 | | - buf->f_fsid.val[0] = (u32)id; |
---|
234 | | - buf->f_fsid.val[1] = (u32)(id >> 32); |
---|
| 233 | + buf->f_fsid = u64_to_fsid(id); |
---|
235 | 234 | buf->f_namelen = BFS_NAMELEN; |
---|
236 | 235 | return 0; |
---|
237 | 236 | } |
---|
.. | .. |
---|
247 | 246 | return &bi->vfs_inode; |
---|
248 | 247 | } |
---|
249 | 248 | |
---|
250 | | -static void bfs_i_callback(struct rcu_head *head) |
---|
| 249 | +static void bfs_free_inode(struct inode *inode) |
---|
251 | 250 | { |
---|
252 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
---|
253 | 251 | kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); |
---|
254 | | -} |
---|
255 | | - |
---|
256 | | -static void bfs_destroy_inode(struct inode *inode) |
---|
257 | | -{ |
---|
258 | | - call_rcu(&inode->i_rcu, bfs_i_callback); |
---|
259 | 252 | } |
---|
260 | 253 | |
---|
261 | 254 | static void init_once(void *foo) |
---|
.. | .. |
---|
289 | 282 | |
---|
290 | 283 | static const struct super_operations bfs_sops = { |
---|
291 | 284 | .alloc_inode = bfs_alloc_inode, |
---|
292 | | - .destroy_inode = bfs_destroy_inode, |
---|
| 285 | + .free_inode = bfs_free_inode, |
---|
293 | 286 | .write_inode = bfs_write_inode, |
---|
294 | 287 | .evict_inode = bfs_evict_inode, |
---|
295 | 288 | .put_super = bfs_put_super, |
---|
.. | .. |
---|
311 | 304 | else |
---|
312 | 305 | strcat(tmpbuf, "0"); |
---|
313 | 306 | } |
---|
314 | | - printf("BFS-fs: %s: lasti=%08lx <%s>\n", |
---|
315 | | - prefix, BFS_SB(s)->si_lasti, tmpbuf); |
---|
| 307 | + printf("%s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf); |
---|
316 | 308 | free_page((unsigned long)tmpbuf); |
---|
317 | 309 | #endif |
---|
318 | 310 | } |
---|
.. | .. |
---|
322 | 314 | struct buffer_head *bh, *sbh; |
---|
323 | 315 | struct bfs_super_block *bfs_sb; |
---|
324 | 316 | struct inode *inode; |
---|
325 | | - unsigned i, imap_len; |
---|
| 317 | + unsigned i; |
---|
326 | 318 | struct bfs_sb_info *info; |
---|
327 | 319 | int ret = -EINVAL; |
---|
328 | 320 | unsigned long i_sblock, i_eblock, i_eoff, s_size; |
---|
.. | .. |
---|
332 | 324 | return -ENOMEM; |
---|
333 | 325 | mutex_init(&info->bfs_lock); |
---|
334 | 326 | s->s_fs_info = info; |
---|
| 327 | + s->s_time_min = 0; |
---|
| 328 | + s->s_time_max = U32_MAX; |
---|
335 | 329 | |
---|
336 | 330 | sb_set_blocksize(s, BFS_BSIZE); |
---|
337 | 331 | |
---|
.. | .. |
---|
341 | 335 | bfs_sb = (struct bfs_super_block *)sbh->b_data; |
---|
342 | 336 | if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) { |
---|
343 | 337 | if (!silent) |
---|
344 | | - printf("No BFS filesystem on %s (magic=%08x)\n", |
---|
345 | | - s->s_id, le32_to_cpu(bfs_sb->s_magic)); |
---|
| 338 | + printf("No BFS filesystem on %s (magic=%08x)\n", s->s_id, le32_to_cpu(bfs_sb->s_magic)); |
---|
346 | 339 | goto out1; |
---|
347 | 340 | } |
---|
348 | 341 | if (BFS_UNCLEAN(bfs_sb, s) && !silent) |
---|
.. | .. |
---|
351 | 344 | s->s_magic = BFS_MAGIC; |
---|
352 | 345 | |
---|
353 | 346 | if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end) || |
---|
354 | | - le32_to_cpu(bfs_sb->s_start) < BFS_BSIZE) { |
---|
355 | | - printf("Superblock is corrupted\n"); |
---|
| 347 | + le32_to_cpu(bfs_sb->s_start) < sizeof(struct bfs_super_block) + sizeof(struct bfs_dirent)) { |
---|
| 348 | + printf("Superblock is corrupted on %s\n", s->s_id); |
---|
356 | 349 | goto out1; |
---|
357 | 350 | } |
---|
358 | 351 | |
---|
359 | | - info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / |
---|
360 | | - sizeof(struct bfs_inode) |
---|
361 | | - + BFS_ROOT_INO - 1; |
---|
362 | | - imap_len = (info->si_lasti / 8) + 1; |
---|
363 | | - info->si_imap = kzalloc(imap_len, GFP_KERNEL | __GFP_NOWARN); |
---|
364 | | - if (!info->si_imap) { |
---|
365 | | - printf("Cannot allocate %u bytes\n", imap_len); |
---|
| 352 | + info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / sizeof(struct bfs_inode) + BFS_ROOT_INO - 1; |
---|
| 353 | + if (info->si_lasti == BFS_MAX_LASTI) |
---|
| 354 | + printf("NOTE: filesystem %s was created with 512 inodes, the real maximum is 511, mounting anyway\n", s->s_id); |
---|
| 355 | + else if (info->si_lasti > BFS_MAX_LASTI) { |
---|
| 356 | + printf("Impossible last inode number %lu > %d on %s\n", info->si_lasti, BFS_MAX_LASTI, s->s_id); |
---|
366 | 357 | goto out1; |
---|
367 | 358 | } |
---|
368 | 359 | for (i = 0; i < BFS_ROOT_INO; i++) |
---|
.. | .. |
---|
372 | 363 | inode = bfs_iget(s, BFS_ROOT_INO); |
---|
373 | 364 | if (IS_ERR(inode)) { |
---|
374 | 365 | ret = PTR_ERR(inode); |
---|
375 | | - goto out2; |
---|
| 366 | + goto out1; |
---|
376 | 367 | } |
---|
377 | 368 | s->s_root = d_make_root(inode); |
---|
378 | 369 | if (!s->s_root) { |
---|
379 | 370 | ret = -ENOMEM; |
---|
380 | | - goto out2; |
---|
| 371 | + goto out1; |
---|
381 | 372 | } |
---|
382 | 373 | |
---|
383 | 374 | info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS; |
---|
384 | | - info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 |
---|
385 | | - - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS; |
---|
| 375 | + info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS; |
---|
386 | 376 | info->si_freei = 0; |
---|
387 | 377 | info->si_lf_eblk = 0; |
---|
388 | 378 | |
---|
389 | 379 | /* can we read the last block? */ |
---|
390 | 380 | bh = sb_bread(s, info->si_blocks - 1); |
---|
391 | 381 | if (!bh) { |
---|
392 | | - printf("Last block not available: %lu\n", info->si_blocks - 1); |
---|
| 382 | + printf("Last block not available on %s: %lu\n", s->s_id, info->si_blocks - 1); |
---|
393 | 383 | ret = -EIO; |
---|
394 | | - goto out3; |
---|
| 384 | + goto out2; |
---|
395 | 385 | } |
---|
396 | 386 | brelse(bh); |
---|
397 | 387 | |
---|
.. | .. |
---|
425 | 415 | (i_eoff != le32_to_cpu(-1) && i_eoff > s_size) || |
---|
426 | 416 | i_sblock * BFS_BSIZE > i_eoff) { |
---|
427 | 417 | |
---|
428 | | - printf("Inode 0x%08x corrupted\n", i); |
---|
| 418 | + printf("Inode 0x%08x corrupted on %s\n", i, s->s_id); |
---|
429 | 419 | |
---|
430 | 420 | brelse(bh); |
---|
431 | 421 | ret = -EIO; |
---|
432 | | - goto out3; |
---|
| 422 | + goto out2; |
---|
433 | 423 | } |
---|
434 | 424 | |
---|
435 | 425 | if (!di->i_ino) { |
---|
.. | .. |
---|
445 | 435 | } |
---|
446 | 436 | brelse(bh); |
---|
447 | 437 | brelse(sbh); |
---|
448 | | - bfs_dump_imap("read_super", s); |
---|
| 438 | + bfs_dump_imap("fill_super", s); |
---|
449 | 439 | return 0; |
---|
450 | 440 | |
---|
451 | | -out3: |
---|
| 441 | +out2: |
---|
452 | 442 | dput(s->s_root); |
---|
453 | 443 | s->s_root = NULL; |
---|
454 | | -out2: |
---|
455 | | - kfree(info->si_imap); |
---|
456 | 444 | out1: |
---|
457 | 445 | brelse(sbh); |
---|
458 | 446 | out: |
---|
.. | .. |
---|
482 | 470 | int err = init_inodecache(); |
---|
483 | 471 | if (err) |
---|
484 | 472 | goto out1; |
---|
485 | | - err = register_filesystem(&bfs_fs_type); |
---|
| 473 | + err = register_filesystem(&bfs_fs_type); |
---|
486 | 474 | if (err) |
---|
487 | 475 | goto out; |
---|
488 | 476 | return 0; |
---|