[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