summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/klm/nlm_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/klm/nlm_service.c')
-rw-r--r--usr/src/uts/common/klm/nlm_service.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/usr/src/uts/common/klm/nlm_service.c b/usr/src/uts/common/klm/nlm_service.c
index c170c1d208..d87e80448d 100644
--- a/usr/src/uts/common/klm/nlm_service.c
+++ b/usr/src/uts/common/klm/nlm_service.c
@@ -28,6 +28,7 @@
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2014 Joyent, Inc. All rights reserved.
*/
/*
@@ -159,6 +160,33 @@ nlm_init_flock(struct flock64 *fl, struct nlm4_lock *nl,
}
/*
+ * Convert an fhandle into a vnode.
+ * Uses the file id (fh_len + fh_data) in the fhandle to get the vnode.
+ * WARNING: users of this routine must do a VN_RELE on the vnode when they
+ * are done with it.
+ * This is just like nfs_fhtovp() but without the exportinfo argument.
+ */
+static vnode_t *
+lm_fhtovp(fhandle3_t *fh)
+{
+ vfs_t *vfsp;
+ vnode_t *vp;
+ int error;
+
+ vfsp = getvfs(&fh->_fh3_fsid);
+ if (vfsp == NULL)
+ return (NULL);
+
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
+ error = VFS_VGET(vfsp, &vp, (fid_t *)&(fh->_fh3_len));
+ VFS_RELE(vfsp);
+ if (error || vp == NULL)
+ return (NULL);
+
+ return (vp);
+}
+
+/*
* Gets vnode from client's filehandle
* NOTE: Holds vnode, it _must_ be explicitly
* released by VN_RELE().
@@ -166,19 +194,28 @@ nlm_init_flock(struct flock64 *fl, struct nlm4_lock *nl,
static vnode_t *
nlm_fh_to_vp(struct netobj *fh)
{
- fhandle_t *fhp;
+ fhandle3_t *fhp;
/*
* Get a vnode pointer for the given NFS file handle.
- * Note that it could be an NFSv2 for NFSv3 handle,
+ * Note that it could be an NFSv2 or NFSv3 handle,
* which means the size might vary. (don't copy)
*/
- if (fh->n_len < sizeof (*fhp))
+ if (fh->n_len < sizeof (fhandle_t))
return (NULL);
/* We know this is aligned (kmem_alloc) */
/* LINTED E_BAD_PTR_CAST_ALIGN */
- fhp = (fhandle_t *)fh->n_bytes;
+ fhp = (fhandle3_t *)fh->n_bytes;
+
+ /*
+ * See the comment for NFS_FH3MAXDATA in uts/common/nfs/nfs.h for
+ * converting fhandles. Check the NFSv3 file handle size. The lockmgr
+ * is not used for NFS v4.
+ */
+ if (fhp->_fh3_len > NFS_FH3MAXDATA || fhp->_fh3_len == 0)
+ return (NULL);
+
return (lm_fhtovp(fhp));
}