Re: [RFC] ->encode_fh() and related breakage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2011-12-30, at 12:27 AM, Al Viro wrote:
> 	One kinda-sorta solution (besides kicking cleancache out of tree)
> would be to modify ->encode_fh() API - instead of dentry + connectable
> pass it inode + NULL-or-parent-inode, with ->d_lock held by caller.  And
> demand it to be non-blocking, obviously...  It would obviously break
> ceph ->encode_fh(), since that sucker apparently wants the name of last
> component anyway.  OTOH, that's broken for reasons mentioned above.
> OTTH, fhandle encoding is bloody close to user-visible ABI ;-/

Is it possible to always pass d_parent if this is available, rather than
only if @connectable is passed?  For network filesystems re-exporting NFS
it is desirable to always be passed the parent directory.

> diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
> index b05acb7..f8f7029 100644
> --- a/fs/exportfs/expfs.c
> +++ b/fs/exportfs/expfs.c
> @@ -304,24 +304,23 @@ out:
> 
> /**
>  * export_encode_fh - default export_operations->encode_fh function
> - * @dentry:  the dentry to encode
> + * @inode:   the object to encode
>  * @fh:      where to store the file handle fragment
>  * @max_len: maximum length to store there
> - * @connectable: whether to store parent information
> + * @parent:  parent directory inode, if wanted
>  *
>  * This default encode_fh function assumes that the 32 inode number
>  * is suitable for locating an inode, and that the generation number
>  * can be used to check that it is still valid.  It places them in the
>  * filehandle fragment where export_decode_fh expects to find them.
>  */
> -static int export_encode_fh(struct dentry *dentry, struct fid *fid,
> -		int *max_len, int connectable)
> +static int export_encode_fh(struct inode *inode, struct fid *fid,
> +		int *max_len, struct inode *parent)
> {
> -	struct inode * inode = dentry->d_inode;
> 	int len = *max_len;
> 	int type = FILEID_INO32_GEN;
> 
> -	if (connectable && (len < 4)) {
> +	if (parent && (len < 4)) {
> 		*max_len = 4;
> 		return 255;
> 	} else if (len < 2) {
> @@ -332,14 +331,9 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid,
> 	len = 2;
> 	fid->i32.ino = inode->i_ino;
> 	fid->i32.gen = inode->i_generation;
> -	if (connectable && !S_ISDIR(inode->i_mode)) {
> -		struct inode *parent;
> -
> -		spin_lock(&dentry->d_lock);
> -		parent = dentry->d_parent->d_inode;
> +	if (parent) {
> 		fid->i32.parent_ino = parent->i_ino;
> 		fid->i32.parent_gen = parent->i_generation;
> -		spin_unlock(&dentry->d_lock);
> 		len = 4;
> 		type = FILEID_INO32_GEN_PARENT;
> 	}
> @@ -352,11 +346,19 @@ int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
> {
> 	const struct export_operations *nop = dentry->d_sb->s_export_op;
> 	int error;
> +	struct inode *inode = dentry->d_inode, *parent = NULL;
> 
> +	if (connectable && !S_ISDIR(inode->i_mode)) {
> +		spin_lock(&dentry->d_lock);
> +		parent = dentry->d_parent->d_inode;
> +		BUG_ON(!parent);
> +	}
> 	if (nop->encode_fh)
> -		error = nop->encode_fh(dentry, fid->raw, max_len, connectable);
> +		error = nop->encode_fh(inode, fid->raw, max_len, parent);
> 	else
> -		error = export_encode_fh(dentry, fid, max_len, connectable);
> +		error = export_encode_fh(inode, fid, max_len, parent);
> +	if (parent)
> +		spin_unlock(&dentry->d_lock);
> 
> 	return error;
> }

Cheers, Andreas





--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux