mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
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 <[email protected]> Cc: Neil Brown <[email protected]> Cc: "J. Bruce Fields" <[email protected]> Cc: <[email protected]> Cc: Dave Kleikamp <[email protected]> Cc: Anton Altaparmakov <[email protected]> Cc: David Chinner <[email protected]> Cc: Timothy Shimmin <[email protected]> Cc: OGAWA Hirofumi <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Chris Mason <[email protected]> Cc: Jeff Mahoney <[email protected]> Cc: "Vladimir V. Saveliev" <[email protected]> Cc: Steven Whitehouse <[email protected]> Cc: Mark Fasheh <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
6e91ea2bb0
commit
2596110a39
3 changed files with 248 additions and 6 deletions
88
fs/libfs.c
88
fs/libfs.c
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/mount.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/exportfs.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
|
@ -678,6 +679,93 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is what d_alloc_anon should have been. Once the exportfs
|
||||
* argument transition has been finished I will update d_alloc_anon
|
||||
* to this prototype and this wrapper will go away. --hch
|
||||
*/
|
||||
static struct dentry *exportfs_d_alloc(struct inode *inode)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
||||
if (!inode)
|
||||
return NULL;
|
||||
if (IS_ERR(inode))
|
||||
return ERR_PTR(PTR_ERR(inode));
|
||||
|
||||
dentry = d_alloc_anon(inode);
|
||||
if (!dentry) {
|
||||
iput(inode);
|
||||
dentry = ERR_PTR(-ENOMEM);
|
||||
}
|
||||
return dentry;
|
||||
}
|
||||
|
||||
/**
|
||||
* generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
|
||||
* @sb: filesystem to do the file handle conversion on
|
||||
* @fid: file handle to convert
|
||||
* @fh_len: length of the file handle in bytes
|
||||
* @fh_type: type of file handle
|
||||
* @get_inode: filesystem callback to retrieve inode
|
||||
*
|
||||
* This function decodes @fid as long as it has one of the well-known
|
||||
* Linux filehandle types and calls @get_inode on it to retrieve the
|
||||
* inode for the object specified in the file handle.
|
||||
*/
|
||||
struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
|
||||
int fh_len, int fh_type, struct inode *(*get_inode)
|
||||
(struct super_block *sb, u64 ino, u32 gen))
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
|
||||
if (fh_len < 2)
|
||||
return NULL;
|
||||
|
||||
switch (fh_type) {
|
||||
case FILEID_INO32_GEN:
|
||||
case FILEID_INO32_GEN_PARENT:
|
||||
inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
|
||||
break;
|
||||
}
|
||||
|
||||
return exportfs_d_alloc(inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
|
||||
|
||||
/**
|
||||
* generic_fh_to_dentry - generic helper for the fh_to_parent export operation
|
||||
* @sb: filesystem to do the file handle conversion on
|
||||
* @fid: file handle to convert
|
||||
* @fh_len: length of the file handle in bytes
|
||||
* @fh_type: type of file handle
|
||||
* @get_inode: filesystem callback to retrieve inode
|
||||
*
|
||||
* This function decodes @fid as long as it has one of the well-known
|
||||
* Linux filehandle types and calls @get_inode on it to retrieve the
|
||||
* inode for the _parent_ object specified in the file handle if it
|
||||
* is specified in the file handle, or NULL otherwise.
|
||||
*/
|
||||
struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
int fh_len, int fh_type, struct inode *(*get_inode)
|
||||
(struct super_block *sb, u64 ino, u32 gen))
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
|
||||
if (fh_len <= 2)
|
||||
return NULL;
|
||||
|
||||
switch (fh_type) {
|
||||
case FILEID_INO32_GEN_PARENT:
|
||||
inode = get_inode(sb, fid->i32.parent_ino,
|
||||
(fh_len > 3 ? fid->i32.parent_gen : 0));
|
||||
break;
|
||||
}
|
||||
|
||||
return exportfs_d_alloc(inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(generic_fh_to_parent);
|
||||
|
||||
EXPORT_SYMBOL(dcache_dir_close);
|
||||
EXPORT_SYMBOL(dcache_dir_lseek);
|
||||
EXPORT_SYMBOL(dcache_dir_open);
|
||||
|
|
|
|||
Loading…
Reference in a new issue