[Labeled-nfs] [PATCH 12/13] NFS: Label change notification for NFSv4 Clients

Matthew N. Dodd Matthew.Dodd at sparta.com
Fri Nov 16 22:16:20 EST 2007


> diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
> index 72e55d8..6eddc48 100644
> --- a/fs/nfs/callback_proc.c
> +++ b/fs/nfs/callback_proc.c
> @@ -86,3 +88,105 @@ out:
>  	dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res));
>  	return res;
>  }
> +
> +#ifdef CONFIG_NFS_V4_SECURITY_LABEL
> +
> +struct nfs_testfh_desc {
> +	struct nfs_fh *fh;
> +	unsigned long ino;
> +};
> +
> +	static int
> +nfs_testfh(struct inode *inode, void *opaque)
> +{
> +	struct nfs_testfh_desc *desc = (struct nfs_testfh_desc *)opaque;
> +
> +	if (inode->i_ino != desc->ino)
> +		return (0);
> +	if (nfs_compare_fh(NFS_FH(inode), desc->fh))
> +		return (0);
> +	if (is_bad_inode(inode) || NFS_STALE(inode))
> +		return (0);
> +	return (1);
> +}
> +
> +/*
> + * Lookup an inode by filehandle, i_ino
> + */
> +struct inode *nfs_client_inode(struct nfs_client *client, struct nfs_fh *fh, unsigned long ino)
> +{
> +	struct nfs_testfh_desc desc = {
> +		.fh	= fh,
> +		.ino	= ino
> +	};
> +	struct nfs_server *server;
> +	struct super_block *sb;
> +	struct inode *inode;
> +
> +	list_for_each_entry(server, &client->cl_superblocks, client_link) {
> +		sb = nfs4_server_get_sb(server);
> +		if (IS_ERR(sb))
> +			continue;
> +
> +		inode = ilookup5_nowait(sb, ino, nfs_testfh, &desc);
> +		if (inode != NULL)
> +			return (inode);
> +	}
> +	return (NULL);
> +}

We're essentially trying to turn a 'sturct nfs_fh' into a 'struct inode'.

In BSD this would be VOP_FHTOVP().

Here I need the ino_t in addition to the nfs_fh to find the entry in the 
hash table.  (struct nfs_fh being opaque on the client.)

Ideas?

> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index 012211f..5faa9ac 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -1929,4 +1929,17 @@ error_splat_super:
>  	return error;
>  }
>  
> +struct super_block *
> +nfs4_server_get_sb(struct nfs_server *server)
> +{
> +	struct super_block *s;
> +
> +	list_for_each_entry(s, &nfs4_fs_type.fs_supers, s_instances) {
> +		if (server == NFS_SB(s))
> +			return (s);
> +		/* XXX: refcount? */
> +	}
> +	return NULL;
> +}
> +
>  #endif /* CONFIG_NFS_V4 */

The refcount/semaphore stuff for the returned 'struct super_block' 
aren't clear from other examples.  Suggestions welcome.


More information about the Labeled-nfs mailing list