return status;
}
+/*
+ * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN,
+ * so we do a temporary open here just to get an open file to pass to
+ * vfs_test_lock. (Arguably perhaps test_lock should be done with an
+ * inode operation.)
+ */
+static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
+{
+ struct file *file;
+ int err;
+
+ err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
+ if (err)
+ return err;
+ err = vfs_test_lock(file, lock);
+ nfsd_close(file);
+ return err;
+}
+
/*
* LOCKT operation
*/
struct nfsd4_lockt *lockt)
{
struct inode *inode;
- struct file file;
struct file_lock file_lock;
int error;
__be32 status;
nfs4_transform_lock_offset(&file_lock);
- /* vfs_test_lock uses the struct file _only_ to resolve the inode.
- * since LOCKT doesn't require an OPEN, and therefore a struct
- * file may not exist, pass vfs_test_lock a struct file with
- * only the dentry:inode set.
- */
- memset(&file, 0, sizeof (struct file));
- file.f_path.dentry = cstate->current_fh.fh_dentry;
-
status = nfs_ok;
- error = vfs_test_lock(&file, &file_lock);
+ error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
if (error) {
status = nfserrno(error);
goto out;