diff options
author | Christoph Hellwig <hch@lst.de> | 2007-10-21 19:42:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-22 11:13:19 -0400 |
commit | 2596110a3994593f6aa3e2bb76345ad4791b1a14 (patch) | |
tree | 0f1773238265f83e1b5640256176851a60ff5ea8 /fs/libfs.c | |
parent | 6e91ea2bb0b6a3ddf6d4faeb54a9c20d4e20bc42 (diff) |
exportfs: add new methods
Add the guts for the new filesystem API to exportfs.
There's now a fh_to_dentry method that returns a dentry for the object looked
for given a filehandle fragment, and a fh_to_parent operation that returns the
dentry for the encoded parent directory in case the file handle contains it.
There are default implementations for these methods that only take a callback
for an nfs-enhanced iget variant and implement the rest of the semantics.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Neil Brown <neilb@suse.de>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: <linux-ext4@vger.kernel.org>
Cc: Dave Kleikamp <shaggy@austin.ibm.com>
Cc: Anton Altaparmakov <aia21@cantab.net>
Cc: David Chinner <dgc@sgi.com>
Cc: Timothy Shimmin <tes@sgi.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Chris Mason <mason@suse.com>
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: "Vladimir V. Saveliev" <vs@namesys.com>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Mark Fasheh <mark.fasheh@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/libfs.c')
-rw-r--r-- | fs/libfs.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/fs/libfs.c b/fs/libfs.c index ae51481e45e5..6e68b700958d 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/mount.h> | 8 | #include <linux/mount.h> |
9 | #include <linux/vfs.h> | 9 | #include <linux/vfs.h> |
10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
11 | #include <linux/exportfs.h> | ||
11 | 12 | ||
12 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
13 | 14 | ||
@@ -678,6 +679,93 @@ out: | |||
678 | return ret; | 679 | return ret; |
679 | } | 680 | } |
680 | 681 | ||
682 | /* | ||
683 | * This is what d_alloc_anon should have been. Once the exportfs | ||
684 | * argument transition has been finished I will update d_alloc_anon | ||
685 | * to this prototype and this wrapper will go away. --hch | ||
686 | */ | ||
687 | static struct dentry *exportfs_d_alloc(struct inode *inode) | ||
688 | { | ||
689 | struct dentry *dentry; | ||
690 | |||
691 | if (!inode) | ||
692 | return NULL; | ||
693 | if (IS_ERR(inode)) | ||
694 | return ERR_PTR(PTR_ERR(inode)); | ||
695 | |||
696 | dentry = d_alloc_anon(inode); | ||
697 | if (!dentry) { | ||
698 | iput(inode); | ||
699 | dentry = ERR_PTR(-ENOMEM); | ||
700 | } | ||
701 | return dentry; | ||
702 | } | ||
703 | |||
704 | /** | ||
705 | * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation | ||
706 | * @sb: filesystem to do the file handle conversion on | ||
707 | * @fid: file handle to convert | ||
708 | * @fh_len: length of the file handle in bytes | ||
709 | * @fh_type: type of file handle | ||
710 | * @get_inode: filesystem callback to retrieve inode | ||
711 | * | ||
712 | * This function decodes @fid as long as it has one of the well-known | ||
713 | * Linux filehandle types and calls @get_inode on it to retrieve the | ||
714 | * inode for the object specified in the file handle. | ||
715 | */ | ||
716 | struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid, | ||
717 | int fh_len, int fh_type, struct inode *(*get_inode) | ||
718 | (struct super_block *sb, u64 ino, u32 gen)) | ||
719 | { | ||
720 | struct inode *inode = NULL; | ||
721 | |||
722 | if (fh_len < 2) | ||
723 | return NULL; | ||
724 | |||
725 | switch (fh_type) { | ||
726 | case FILEID_INO32_GEN: | ||
727 | case FILEID_INO32_GEN_PARENT: | ||
728 | inode = get_inode(sb, fid->i32.ino, fid->i32.gen); | ||
729 | break; | ||
730 | } | ||
731 | |||
732 | return exportfs_d_alloc(inode); | ||
733 | } | ||
734 | EXPORT_SYMBOL_GPL(generic_fh_to_dentry); | ||
735 | |||
736 | /** | ||
737 | * generic_fh_to_dentry - generic helper for the fh_to_parent export operation | ||
738 | * @sb: filesystem to do the file handle conversion on | ||
739 | * @fid: file handle to convert | ||
740 | * @fh_len: length of the file handle in bytes | ||
741 | * @fh_type: type of file handle | ||
742 | * @get_inode: filesystem callback to retrieve inode | ||
743 | * | ||
744 | * This function decodes @fid as long as it has one of the well-known | ||
745 | * Linux filehandle types and calls @get_inode on it to retrieve the | ||
746 | * inode for the _parent_ object specified in the file handle if it | ||
747 | * is specified in the file handle, or NULL otherwise. | ||
748 | */ | ||
749 | struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid, | ||
750 | int fh_len, int fh_type, struct inode *(*get_inode) | ||
751 | (struct super_block *sb, u64 ino, u32 gen)) | ||
752 | { | ||
753 | struct inode *inode = NULL; | ||
754 | |||
755 | if (fh_len <= 2) | ||
756 | return NULL; | ||
757 | |||
758 | switch (fh_type) { | ||
759 | case FILEID_INO32_GEN_PARENT: | ||
760 | inode = get_inode(sb, fid->i32.parent_ino, | ||
761 | (fh_len > 3 ? fid->i32.parent_gen : 0)); | ||
762 | break; | ||
763 | } | ||
764 | |||
765 | return exportfs_d_alloc(inode); | ||
766 | } | ||
767 | EXPORT_SYMBOL_GPL(generic_fh_to_parent); | ||
768 | |||
681 | EXPORT_SYMBOL(dcache_dir_close); | 769 | EXPORT_SYMBOL(dcache_dir_close); |
682 | EXPORT_SYMBOL(dcache_dir_lseek); | 770 | EXPORT_SYMBOL(dcache_dir_lseek); |
683 | EXPORT_SYMBOL(dcache_dir_open); | 771 | EXPORT_SYMBOL(dcache_dir_open); |