diff options
Diffstat (limited to 'fs/befs/linuxvfs.c')
-rw-r--r-- | fs/befs/linuxvfs.c | 134 |
1 files changed, 85 insertions, 49 deletions
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 647a276eba56..19407165f4aa 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/parser.h> | 18 | #include <linux/parser.h> |
19 | #include <linux/namei.h> | 19 | #include <linux/namei.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/exportfs.h> | ||
21 | 22 | ||
22 | #include "befs.h" | 23 | #include "befs.h" |
23 | #include "btree.h" | 24 | #include "btree.h" |
@@ -37,7 +38,8 @@ static int befs_readdir(struct file *, struct dir_context *); | |||
37 | static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int); | 38 | static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int); |
38 | static int befs_readpage(struct file *file, struct page *page); | 39 | static int befs_readpage(struct file *file, struct page *page); |
39 | static sector_t befs_bmap(struct address_space *mapping, sector_t block); | 40 | static sector_t befs_bmap(struct address_space *mapping, sector_t block); |
40 | static struct dentry *befs_lookup(struct inode *, struct dentry *, unsigned int); | 41 | static struct dentry *befs_lookup(struct inode *, struct dentry *, |
42 | unsigned int); | ||
41 | static struct inode *befs_iget(struct super_block *, unsigned long); | 43 | static struct inode *befs_iget(struct super_block *, unsigned long); |
42 | static struct inode *befs_alloc_inode(struct super_block *sb); | 44 | static struct inode *befs_alloc_inode(struct super_block *sb); |
43 | static void befs_destroy_inode(struct inode *inode); | 45 | static void befs_destroy_inode(struct inode *inode); |
@@ -51,6 +53,10 @@ static void befs_put_super(struct super_block *); | |||
51 | static int befs_remount(struct super_block *, int *, char *); | 53 | static int befs_remount(struct super_block *, int *, char *); |
52 | static int befs_statfs(struct dentry *, struct kstatfs *); | 54 | static int befs_statfs(struct dentry *, struct kstatfs *); |
53 | static int parse_options(char *, struct befs_mount_options *); | 55 | static int parse_options(char *, struct befs_mount_options *); |
56 | static struct dentry *befs_fh_to_dentry(struct super_block *sb, | ||
57 | struct fid *fid, int fh_len, int fh_type); | ||
58 | static struct dentry *befs_fh_to_parent(struct super_block *sb, | ||
59 | struct fid *fid, int fh_len, int fh_type); | ||
54 | 60 | ||
55 | static const struct super_operations befs_sops = { | 61 | static const struct super_operations befs_sops = { |
56 | .alloc_inode = befs_alloc_inode, /* allocate a new inode */ | 62 | .alloc_inode = befs_alloc_inode, /* allocate a new inode */ |
@@ -83,9 +89,14 @@ static const struct address_space_operations befs_symlink_aops = { | |||
83 | .readpage = befs_symlink_readpage, | 89 | .readpage = befs_symlink_readpage, |
84 | }; | 90 | }; |
85 | 91 | ||
86 | /* | 92 | static const struct export_operations befs_export_operations = { |
93 | .fh_to_dentry = befs_fh_to_dentry, | ||
94 | .fh_to_parent = befs_fh_to_parent, | ||
95 | }; | ||
96 | |||
97 | /* | ||
87 | * Called by generic_file_read() to read a page of data | 98 | * Called by generic_file_read() to read a page of data |
88 | * | 99 | * |
89 | * In turn, simply calls a generic block read function and | 100 | * In turn, simply calls a generic block read function and |
90 | * passes it the address of befs_get_block, for mapping file | 101 | * passes it the address of befs_get_block, for mapping file |
91 | * positions to disk blocks. | 102 | * positions to disk blocks. |
@@ -102,15 +113,13 @@ befs_bmap(struct address_space *mapping, sector_t block) | |||
102 | return generic_block_bmap(mapping, block, befs_get_block); | 113 | return generic_block_bmap(mapping, block, befs_get_block); |
103 | } | 114 | } |
104 | 115 | ||
105 | /* | 116 | /* |
106 | * Generic function to map a file position (block) to a | 117 | * Generic function to map a file position (block) to a |
107 | * disk offset (passed back in bh_result). | 118 | * disk offset (passed back in bh_result). |
108 | * | 119 | * |
109 | * Used by many higher level functions. | 120 | * Used by many higher level functions. |
110 | * | 121 | * |
111 | * Calls befs_fblock2brun() in datastream.c to do the real work. | 122 | * Calls befs_fblock2brun() in datastream.c to do the real work. |
112 | * | ||
113 | * -WD 10-26-01 | ||
114 | */ | 123 | */ |
115 | 124 | ||
116 | static int | 125 | static int |
@@ -269,15 +278,15 @@ befs_alloc_inode(struct super_block *sb) | |||
269 | struct befs_inode_info *bi; | 278 | struct befs_inode_info *bi; |
270 | 279 | ||
271 | bi = kmem_cache_alloc(befs_inode_cachep, GFP_KERNEL); | 280 | bi = kmem_cache_alloc(befs_inode_cachep, GFP_KERNEL); |
272 | if (!bi) | 281 | if (!bi) |
273 | return NULL; | 282 | return NULL; |
274 | return &bi->vfs_inode; | 283 | return &bi->vfs_inode; |
275 | } | 284 | } |
276 | 285 | ||
277 | static void befs_i_callback(struct rcu_head *head) | 286 | static void befs_i_callback(struct rcu_head *head) |
278 | { | 287 | { |
279 | struct inode *inode = container_of(head, struct inode, i_rcu); | 288 | struct inode *inode = container_of(head, struct inode, i_rcu); |
280 | kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); | 289 | kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); |
281 | } | 290 | } |
282 | 291 | ||
283 | static void befs_destroy_inode(struct inode *inode) | 292 | static void befs_destroy_inode(struct inode *inode) |
@@ -287,7 +296,7 @@ static void befs_destroy_inode(struct inode *inode) | |||
287 | 296 | ||
288 | static void init_once(void *foo) | 297 | static void init_once(void *foo) |
289 | { | 298 | { |
290 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; | 299 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; |
291 | 300 | ||
292 | inode_init_once(&bi->vfs_inode); | 301 | inode_init_once(&bi->vfs_inode); |
293 | } | 302 | } |
@@ -338,7 +347,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
338 | /* | 347 | /* |
339 | * set uid and gid. But since current BeOS is single user OS, so | 348 | * set uid and gid. But since current BeOS is single user OS, so |
340 | * you can change by "uid" or "gid" options. | 349 | * you can change by "uid" or "gid" options. |
341 | */ | 350 | */ |
342 | 351 | ||
343 | inode->i_uid = befs_sb->mount_opts.use_uid ? | 352 | inode->i_uid = befs_sb->mount_opts.use_uid ? |
344 | befs_sb->mount_opts.uid : | 353 | befs_sb->mount_opts.uid : |
@@ -353,14 +362,14 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
353 | * BEFS's time is 64 bits, but current VFS is 32 bits... | 362 | * BEFS's time is 64 bits, but current VFS is 32 bits... |
354 | * BEFS don't have access time. Nor inode change time. VFS | 363 | * BEFS don't have access time. Nor inode change time. VFS |
355 | * doesn't have creation time. | 364 | * doesn't have creation time. |
356 | * Also, the lower 16 bits of the last_modified_time and | 365 | * Also, the lower 16 bits of the last_modified_time and |
357 | * create_time are just a counter to help ensure uniqueness | 366 | * create_time are just a counter to help ensure uniqueness |
358 | * for indexing purposes. (PFD, page 54) | 367 | * for indexing purposes. (PFD, page 54) |
359 | */ | 368 | */ |
360 | 369 | ||
361 | inode->i_mtime.tv_sec = | 370 | inode->i_mtime.tv_sec = |
362 | fs64_to_cpu(sb, raw_inode->last_modified_time) >> 16; | 371 | fs64_to_cpu(sb, raw_inode->last_modified_time) >> 16; |
363 | inode->i_mtime.tv_nsec = 0; /* lower 16 bits are not a time */ | 372 | inode->i_mtime.tv_nsec = 0; /* lower 16 bits are not a time */ |
364 | inode->i_ctime = inode->i_mtime; | 373 | inode->i_ctime = inode->i_mtime; |
365 | inode->i_atime = inode->i_mtime; | 374 | inode->i_atime = inode->i_mtime; |
366 | 375 | ||
@@ -414,10 +423,10 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
414 | unlock_new_inode(inode); | 423 | unlock_new_inode(inode); |
415 | return inode; | 424 | return inode; |
416 | 425 | ||
417 | unacquire_bh: | 426 | unacquire_bh: |
418 | brelse(bh); | 427 | brelse(bh); |
419 | 428 | ||
420 | unacquire_none: | 429 | unacquire_none: |
421 | iget_failed(inode); | 430 | iget_failed(inode); |
422 | befs_debug(sb, "<--- %s - Bad inode", __func__); | 431 | befs_debug(sb, "<--- %s - Bad inode", __func__); |
423 | return ERR_PTR(-EIO); | 432 | return ERR_PTR(-EIO); |
@@ -442,7 +451,7 @@ befs_init_inodecache(void) | |||
442 | } | 451 | } |
443 | 452 | ||
444 | /* Called at fs teardown. | 453 | /* Called at fs teardown. |
445 | * | 454 | * |
446 | * Taken from NFS implementation by Al Viro. | 455 | * Taken from NFS implementation by Al Viro. |
447 | */ | 456 | */ |
448 | static void | 457 | static void |
@@ -491,13 +500,10 @@ fail: | |||
491 | } | 500 | } |
492 | 501 | ||
493 | /* | 502 | /* |
494 | * UTF-8 to NLS charset convert routine | 503 | * UTF-8 to NLS charset convert routine |
495 | * | ||
496 | * | 504 | * |
497 | * Changed 8/10/01 by Will Dyson. Now use uni2char() / char2uni() rather than | 505 | * Uses uni2char() / char2uni() rather than the nls tables directly |
498 | * the nls tables directly | ||
499 | */ | 506 | */ |
500 | |||
501 | static int | 507 | static int |
502 | befs_utf2nls(struct super_block *sb, const char *in, | 508 | befs_utf2nls(struct super_block *sb, const char *in, |
503 | int in_len, char **out, int *out_len) | 509 | int in_len, char **out, int *out_len) |
@@ -521,9 +527,8 @@ befs_utf2nls(struct super_block *sb, const char *in, | |||
521 | } | 527 | } |
522 | 528 | ||
523 | *out = result = kmalloc(maxlen, GFP_NOFS); | 529 | *out = result = kmalloc(maxlen, GFP_NOFS); |
524 | if (!*out) { | 530 | if (!*out) |
525 | return -ENOMEM; | 531 | return -ENOMEM; |
526 | } | ||
527 | 532 | ||
528 | for (i = o = 0; i < in_len; i += utflen, o += unilen) { | 533 | for (i = o = 0; i < in_len; i += utflen, o += unilen) { |
529 | 534 | ||
@@ -546,7 +551,7 @@ befs_utf2nls(struct super_block *sb, const char *in, | |||
546 | 551 | ||
547 | return o; | 552 | return o; |
548 | 553 | ||
549 | conv_err: | 554 | conv_err: |
550 | befs_error(sb, "Name using character set %s contains a character that " | 555 | befs_error(sb, "Name using character set %s contains a character that " |
551 | "cannot be converted to unicode.", nls->charset); | 556 | "cannot be converted to unicode.", nls->charset); |
552 | befs_debug(sb, "<--- %s", __func__); | 557 | befs_debug(sb, "<--- %s", __func__); |
@@ -561,18 +566,18 @@ befs_utf2nls(struct super_block *sb, const char *in, | |||
561 | * @in_len: Length of input string in bytes | 566 | * @in_len: Length of input string in bytes |
562 | * @out: The output string in UTF-8 format | 567 | * @out: The output string in UTF-8 format |
563 | * @out_len: Length of the output buffer | 568 | * @out_len: Length of the output buffer |
564 | * | 569 | * |
565 | * Converts input string @in, which is in the format of the loaded NLS map, | 570 | * Converts input string @in, which is in the format of the loaded NLS map, |
566 | * into a utf8 string. | 571 | * into a utf8 string. |
567 | * | 572 | * |
568 | * The destination string @out is allocated by this function and the caller is | 573 | * The destination string @out is allocated by this function and the caller is |
569 | * responsible for freeing it with kfree() | 574 | * responsible for freeing it with kfree() |
570 | * | 575 | * |
571 | * On return, *@out_len is the length of @out in bytes. | 576 | * On return, *@out_len is the length of @out in bytes. |
572 | * | 577 | * |
573 | * On success, the return value is the number of utf8 characters written to | 578 | * On success, the return value is the number of utf8 characters written to |
574 | * the output buffer @out. | 579 | * the output buffer @out. |
575 | * | 580 | * |
576 | * On Failure, a negative number coresponding to the error code is returned. | 581 | * On Failure, a negative number coresponding to the error code is returned. |
577 | */ | 582 | */ |
578 | 583 | ||
@@ -585,9 +590,11 @@ befs_nls2utf(struct super_block *sb, const char *in, | |||
585 | wchar_t uni; | 590 | wchar_t uni; |
586 | int unilen, utflen; | 591 | int unilen, utflen; |
587 | char *result; | 592 | char *result; |
588 | /* There're nls characters that will translate to 3-chars-wide UTF-8 | 593 | /* |
589 | * characters, a additional byte is needed to save the final \0 | 594 | * There are nls characters that will translate to 3-chars-wide UTF-8 |
590 | * in special cases */ | 595 | * characters, an additional byte is needed to save the final \0 |
596 | * in special cases | ||
597 | */ | ||
591 | int maxlen = (3 * in_len) + 1; | 598 | int maxlen = (3 * in_len) + 1; |
592 | 599 | ||
593 | befs_debug(sb, "---> %s\n", __func__); | 600 | befs_debug(sb, "---> %s\n", __func__); |
@@ -624,14 +631,41 @@ befs_nls2utf(struct super_block *sb, const char *in, | |||
624 | 631 | ||
625 | return i; | 632 | return i; |
626 | 633 | ||
627 | conv_err: | 634 | conv_err: |
628 | befs_error(sb, "Name using charecter set %s contains a charecter that " | 635 | befs_error(sb, "Name using character set %s contains a character that " |
629 | "cannot be converted to unicode.", nls->charset); | 636 | "cannot be converted to unicode.", nls->charset); |
630 | befs_debug(sb, "<--- %s", __func__); | 637 | befs_debug(sb, "<--- %s", __func__); |
631 | kfree(result); | 638 | kfree(result); |
632 | return -EILSEQ; | 639 | return -EILSEQ; |
633 | } | 640 | } |
634 | 641 | ||
642 | static struct inode *befs_nfs_get_inode(struct super_block *sb, uint64_t ino, | ||
643 | uint32_t generation) | ||
644 | { | ||
645 | /* No need to handle i_generation */ | ||
646 | return befs_iget(sb, ino); | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Map a NFS file handle to a corresponding dentry | ||
651 | */ | ||
652 | static struct dentry *befs_fh_to_dentry(struct super_block *sb, | ||
653 | struct fid *fid, int fh_len, int fh_type) | ||
654 | { | ||
655 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, | ||
656 | befs_nfs_get_inode); | ||
657 | } | ||
658 | |||
659 | /* | ||
660 | * Find the parent for a file specified by NFS handle | ||
661 | */ | ||
662 | static struct dentry *befs_fh_to_parent(struct super_block *sb, | ||
663 | struct fid *fid, int fh_len, int fh_type) | ||
664 | { | ||
665 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, | ||
666 | befs_nfs_get_inode); | ||
667 | } | ||
668 | |||
635 | enum { | 669 | enum { |
636 | Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err, | 670 | Opt_uid, Opt_gid, Opt_charset, Opt_debug, Opt_err, |
637 | }; | 671 | }; |
@@ -666,6 +700,7 @@ parse_options(char *options, struct befs_mount_options *opts) | |||
666 | 700 | ||
667 | while ((p = strsep(&options, ",")) != NULL) { | 701 | while ((p = strsep(&options, ",")) != NULL) { |
668 | int token; | 702 | int token; |
703 | |||
669 | if (!*p) | 704 | if (!*p) |
670 | continue; | 705 | continue; |
671 | 706 | ||
@@ -721,7 +756,7 @@ parse_options(char *options, struct befs_mount_options *opts) | |||
721 | } | 756 | } |
722 | 757 | ||
723 | /* This function has the responsibiltiy of getting the | 758 | /* This function has the responsibiltiy of getting the |
724 | * filesystem ready for unmounting. | 759 | * filesystem ready for unmounting. |
725 | * Basically, we free everything that we allocated in | 760 | * Basically, we free everything that we allocated in |
726 | * befs_read_inode | 761 | * befs_read_inode |
727 | */ | 762 | */ |
@@ -782,8 +817,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
782 | * Linux 2.4.10 and later refuse to read blocks smaller than | 817 | * Linux 2.4.10 and later refuse to read blocks smaller than |
783 | * the logical block size for the device. But we also need to read at | 818 | * the logical block size for the device. But we also need to read at |
784 | * least 1k to get the second 512 bytes of the volume. | 819 | * least 1k to get the second 512 bytes of the volume. |
785 | * -WD 10-26-01 | 820 | */ |
786 | */ | ||
787 | blocksize = sb_min_blocksize(sb, 1024); | 821 | blocksize = sb_min_blocksize(sb, 1024); |
788 | if (!blocksize) { | 822 | if (!blocksize) { |
789 | if (!silent) | 823 | if (!silent) |
@@ -791,7 +825,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
791 | goto unacquire_priv_sbp; | 825 | goto unacquire_priv_sbp; |
792 | } | 826 | } |
793 | 827 | ||
794 | if (!(bh = sb_bread(sb, sb_block))) { | 828 | bh = sb_bread(sb, sb_block); |
829 | if (!bh) { | ||
795 | if (!silent) | 830 | if (!silent) |
796 | befs_error(sb, "unable to read superblock"); | 831 | befs_error(sb, "unable to read superblock"); |
797 | goto unacquire_priv_sbp; | 832 | goto unacquire_priv_sbp; |
@@ -816,7 +851,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
816 | 851 | ||
817 | brelse(bh); | 852 | brelse(bh); |
818 | 853 | ||
819 | if( befs_sb->num_blocks > ~((sector_t)0) ) { | 854 | if (befs_sb->num_blocks > ~((sector_t)0)) { |
820 | if (!silent) | 855 | if (!silent) |
821 | befs_error(sb, "blocks count: %llu is larger than the host can use", | 856 | befs_error(sb, "blocks count: %llu is larger than the host can use", |
822 | befs_sb->num_blocks); | 857 | befs_sb->num_blocks); |
@@ -831,6 +866,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
831 | /* Set real blocksize of fs */ | 866 | /* Set real blocksize of fs */ |
832 | sb_set_blocksize(sb, (ulong) befs_sb->block_size); | 867 | sb_set_blocksize(sb, (ulong) befs_sb->block_size); |
833 | sb->s_op = &befs_sops; | 868 | sb->s_op = &befs_sops; |
869 | sb->s_export_op = &befs_export_operations; | ||
834 | root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); | 870 | root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); |
835 | if (IS_ERR(root)) { | 871 | if (IS_ERR(root)) { |
836 | ret = PTR_ERR(root); | 872 | ret = PTR_ERR(root); |
@@ -861,16 +897,16 @@ befs_fill_super(struct super_block *sb, void *data, int silent) | |||
861 | } | 897 | } |
862 | 898 | ||
863 | return 0; | 899 | return 0; |
864 | /*****************/ | 900 | |
865 | unacquire_bh: | 901 | unacquire_bh: |
866 | brelse(bh); | 902 | brelse(bh); |
867 | 903 | ||
868 | unacquire_priv_sbp: | 904 | unacquire_priv_sbp: |
869 | kfree(befs_sb->mount_opts.iocharset); | 905 | kfree(befs_sb->mount_opts.iocharset); |
870 | kfree(sb->s_fs_info); | 906 | kfree(sb->s_fs_info); |
871 | sb->s_fs_info = NULL; | 907 | sb->s_fs_info = NULL; |
872 | 908 | ||
873 | unacquire_none: | 909 | unacquire_none: |
874 | return ret; | 910 | return ret; |
875 | } | 911 | } |
876 | 912 | ||
@@ -919,7 +955,7 @@ static struct file_system_type befs_fs_type = { | |||
919 | .name = "befs", | 955 | .name = "befs", |
920 | .mount = befs_mount, | 956 | .mount = befs_mount, |
921 | .kill_sb = kill_block_super, | 957 | .kill_sb = kill_block_super, |
922 | .fs_flags = FS_REQUIRES_DEV, | 958 | .fs_flags = FS_REQUIRES_DEV, |
923 | }; | 959 | }; |
924 | MODULE_ALIAS_FS("befs"); | 960 | MODULE_ALIAS_FS("befs"); |
925 | 961 | ||
@@ -956,9 +992,9 @@ exit_befs_fs(void) | |||
956 | } | 992 | } |
957 | 993 | ||
958 | /* | 994 | /* |
959 | Macros that typecheck the init and exit functions, | 995 | * Macros that typecheck the init and exit functions, |
960 | ensures that they are called at init and cleanup, | 996 | * ensures that they are called at init and cleanup, |
961 | and eliminates warnings about unused functions. | 997 | * and eliminates warnings about unused functions. |
962 | */ | 998 | */ |
963 | module_init(init_befs_fs) | 999 | module_init(init_befs_fs) |
964 | module_exit(exit_befs_fs) | 1000 | module_exit(exit_befs_fs) |