exportfs: remove iget abuse
Subsystems (4)
PATCH 2/8 exportfs: remove iget abuse
When the exportfs interface was added the expectation was that filesystems provide an operation to convert from a file handle to an inode/dentry, but it kept a backwards compat option that sill calls into iget.
Calling into iget from non-filesystem code is very bad, because it gives to little information to filesystem, and simply crashes if the filesystem doesn't implement the ->read_inode routine.
Fortunately ther are only two filesystems left using this fallback:
efs and jfs. This patch moves a copy of export_iget to each of those to implement the get_dentry method.
While this is a temporary increase of lines of code in the kernel it allows for a much cleaner interface and important code restructuring in later patches.
fs/exportfs/expfs.c +3 -53
@@ -392,61 +392,11 @@return error; } - -static struct dentry *export_iget (struct super_block *sb,unsigned long ino,__u32 generation) +static struct dentry *get_dentry (struct super_block *sb,void *vobjp) { - -/* iget isn't really right if the inode is currently unallocated!! -* This should really all be done inside each filesystem -* -* ext2fs' read_inode has been strengthed to return a bad_inode if -* the inode had been deleted. -* -* Currently we don't know the generation for parent directory, so -* a generation of 0 means "accept any" -*/ -struct inode *inode; -struct dentry *result; -if (ino ==0 ) -return ERR_PTR (-ESTALE ); - inode =iget (sb, ino); -if (inode ==NULL ) -return ERR_PTR (-ENOMEM ); -if (is_bad_inode (inode) - || (generation && inode->i_generation != generation) - ) { -/* we didn't find the right inode.. */ -dprintk ("fh_verify: Inode %lu, Bad count: %d %d or version %u %u\n" , - inode->i_ino, - inode->i_nlink,atomic_read (&inode->i_count), - inode->i_generation, - generation); - -iput (inode); -return ERR_PTR (-ESTALE ); - } -/* now to find a dentry. -* If possible, get a well-connected one -*/ - result =d_alloc_anon (inode); -if (!result) { -iput (inode); -return ERR_PTR (-ENOMEM ); - } -return result; +return ERR_PTR (-ESTALE ); } - -static struct dentry *get_object (struct super_block *sb,void *vobjp) -{ -__u32 *objp = vobjp; -unsigned long ino = objp[0 ]; -__u32 generation = objp[1 ]; - -return export_iget (sb, ino, generation); -} - -/** * export_encode_fh - default export_operations->encode_fh function * @dentry: the dentry to encode
@@ -525,7 +475,7 @@ .get_name = get_name, .get_parent = get_parent, - .get_dentry = get_object, + .get_dentry = get_dentry, };EXPORT_SYMBOL (export_op_default);
fs/jfs/jfs_inode.h +1 -0
@@ -31,6 +31,7 @@extern void jfs_truncate_nolock (struct inode *,loff_t );extern void jfs_free_zero_link (struct inode *);extern struct dentry *jfs_get_parent (struct dentry *dentry); +extern struct dentry *jfs_get_dentry (struct super_block *sb,void *vobjp);extern void jfs_set_inode_flags (struct inode *);extern int jfs_get_block (struct inode *,sector_t ,struct buffer_head *,int );
fs/jfs/namei.c +32 -0
@@ -1477,6 +1477,38 @@return dentry; } +struct dentry *jfs_get_dentry (struct super_block *sb,void *vobjp) +{ +__u32 *objp = vobjp; +unsigned long ino = objp[0 ]; +__u32 generation = objp[1 ]; +struct inode *inode; +struct dentry *result; + +if (ino ==0 ) +return ERR_PTR (-ESTALE ); + inode =iget (sb, ino); +if (inode ==NULL ) +return ERR_PTR (-ENOMEM ); + +if (is_bad_inode (inode) || + (generation && inode->i_generation != generation)) { + result =ERR_PTR (-ESTALE ); + goto out_iput; + } + + result =d_alloc_anon (inode); +if (!result) { + result =ERR_PTR (-ENOMEM ); + goto out_iput; + } +return result; + + out_iput: +iput (inode); +return result; +} +struct dentry *jfs_get_parent (struct dentry *dentry) {struct super_block *sb = dentry->d_inode->i_sb;
fs/jfs/super.c +1 -0
@@ -738,6 +738,7 @@ };static struct export_operations jfs_export_operations = { + .get_dentry = jfs_get_dentry, .get_parent = jfs_get_parent, };
fs/efs/namei.c +32 -0
@@ -75,6 +75,38 @@return NULL ; } +struct dentry *efs_get_dentry (struct super_block *sb,void *vobjp) +{ +__u32 *objp = vobjp; +unsigned long ino = objp[0 ]; +__u32 generation = objp[1 ]; +struct inode *inode; +struct dentry *result; + +if (ino ==0 ) +return ERR_PTR (-ESTALE ); + inode =iget (sb, ino); +if (inode ==NULL ) +return ERR_PTR (-ENOMEM ); + +if (is_bad_inode (inode) || + (generation && inode->i_generation != generation)) { + result =ERR_PTR (-ESTALE ); + goto out_iput; + } + + result =d_alloc_anon (inode); +if (!result) { + result =ERR_PTR (-ENOMEM ); + goto out_iput; + } +return result; + + out_iput: +iput (inode); +return result; +} +struct dentry *efs_get_parent (struct dentry *child) {struct dentry *parent;
fs/efs/super.c +1 -0
@@ -116,6 +116,7 @@ };static struct export_operations efs_export_ops = { + .get_dentry = efs_get_dentry, .get_parent = efs_get_parent, };
include/linux/efs_fs.h +1 -0
@@ -45,6 +45,7 @@extern int efs_get_block (struct inode *,sector_t ,struct buffer_head *,int );extern struct dentry *efs_lookup (struct inode *,struct dentry *,struct nameidata *); +extern struct dentry *efs_get_dentry (struct super_block *sb,void *vobjp);extern struct dentry *efs_get_parent (struct dentry *);extern int efs_bmap (struct inode *,int );
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs