diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-08-26 11:23:02 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-10-22 20:24:34 -0400 |
commit | 8e656fd518784b49453f60c5f78b78703bc85cb2 (patch) | |
tree | 7adf4b71aba4bdf31dc05489a06933c48a0ea6f2 /fs/nilfs2/super.c | |
parent | 4d8d9293dce503eb0e083e17a02a328d397e7f00 (diff) |
nilfs2: make snapshots in checkpoint tree exportable
The previous export operations cannot handle multiple versions of
a filesystem if they belong to the same sb instance.
This adds a new type of file handle and extends export operations so
that they can get the inode specified by a checkpoint number as well
as an inode number and a generation number.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 52 |
1 files changed, 1 insertions, 51 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index a1c0e38a7706..adbf5826b837 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -48,10 +48,10 @@ | |||
48 | #include <linux/vfs.h> | 48 | #include <linux/vfs.h> |
49 | #include <linux/writeback.h> | 49 | #include <linux/writeback.h> |
50 | #include <linux/kobject.h> | 50 | #include <linux/kobject.h> |
51 | #include <linux/exportfs.h> | ||
52 | #include <linux/seq_file.h> | 51 | #include <linux/seq_file.h> |
53 | #include <linux/mount.h> | 52 | #include <linux/mount.h> |
54 | #include "nilfs.h" | 53 | #include "nilfs.h" |
54 | #include "export.h" | ||
55 | #include "mdt.h" | 55 | #include "mdt.h" |
56 | #include "alloc.h" | 56 | #include "alloc.h" |
57 | #include "btree.h" | 57 | #include "btree.h" |
@@ -556,56 +556,6 @@ static const struct super_operations nilfs_sops = { | |||
556 | .show_options = nilfs_show_options | 556 | .show_options = nilfs_show_options |
557 | }; | 557 | }; |
558 | 558 | ||
559 | static struct inode * | ||
560 | nilfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) | ||
561 | { | ||
562 | struct inode *inode; | ||
563 | struct nilfs_root *root; | ||
564 | |||
565 | if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO && | ||
566 | ino != NILFS_SKETCH_INO) | ||
567 | return ERR_PTR(-ESTALE); | ||
568 | |||
569 | root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, | ||
570 | NILFS_CPTREE_CURRENT_CNO); | ||
571 | if (!root) | ||
572 | return ERR_PTR(-ESTALE); | ||
573 | |||
574 | /* new file handle type is required to export snapshots */ | ||
575 | inode = nilfs_iget(sb, root, ino); | ||
576 | nilfs_put_root(root); | ||
577 | if (IS_ERR(inode)) | ||
578 | return ERR_CAST(inode); | ||
579 | if (generation && inode->i_generation != generation) { | ||
580 | iput(inode); | ||
581 | return ERR_PTR(-ESTALE); | ||
582 | } | ||
583 | |||
584 | return inode; | ||
585 | } | ||
586 | |||
587 | static struct dentry * | ||
588 | nilfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, | ||
589 | int fh_type) | ||
590 | { | ||
591 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, | ||
592 | nilfs_nfs_get_inode); | ||
593 | } | ||
594 | |||
595 | static struct dentry * | ||
596 | nilfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, | ||
597 | int fh_type) | ||
598 | { | ||
599 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, | ||
600 | nilfs_nfs_get_inode); | ||
601 | } | ||
602 | |||
603 | static const struct export_operations nilfs_export_ops = { | ||
604 | .fh_to_dentry = nilfs_fh_to_dentry, | ||
605 | .fh_to_parent = nilfs_fh_to_parent, | ||
606 | .get_parent = nilfs_get_parent, | ||
607 | }; | ||
608 | |||
609 | enum { | 559 | enum { |
610 | Opt_err_cont, Opt_err_panic, Opt_err_ro, | 560 | Opt_err_cont, Opt_err_panic, Opt_err_ro, |
611 | Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, | 561 | Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, |