summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-06-26 10:21:54 +0000
committerdfr <dfr@FreeBSD.org>2008-06-26 10:21:54 +0000
commit41cea6d5ca71b8cf057f9face8055b218b30e18e (patch)
tree994a214037913bc4e44eaee5070c65aeadf53485 /sys/nfsclient
parentca3c788812715a263f83dcec4bdabaf6c10eb922 (diff)
downloadFreeBSD-src-41cea6d5ca71b8cf057f9face8055b218b30e18e.zip
FreeBSD-src-41cea6d5ca71b8cf057f9face8055b218b30e18e.tar.gz
Re-implement the client side of rpc.lockd in the kernel. This implementation
provides the correct semantics for flock(2) style locks which are used by the lockf(1) command line tool and the pidfile(3) library. It also implements recovery from server restarts and ensures that dirty cache blocks are written to the server before obtaining locks (allowing multiple clients to use file locking to safely share data). Sponsored by: Isilon Systems PR: 94256 MFC after: 2 weeks
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/nfs.h1
-rw-r--r--sys/nfsclient/nfs_node.c7
-rw-r--r--sys/nfsclient/nfs_vfsops.c7
-rw-r--r--sys/nfsclient/nfs_vnops.c11
-rw-r--r--sys/nfsclient/nfsmount.h1
-rw-r--r--sys/nfsclient/nfsnode.h3
6 files changed, 28 insertions, 2 deletions
diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h
index 29fb332..9e52420 100644
--- a/sys/nfsclient/nfs.h
+++ b/sys/nfsclient/nfs.h
@@ -93,6 +93,7 @@
#define NFSSTA_SNDLOCK 0x01000000 /* Send socket lock */
#define NFSSTA_WANTSND 0x02000000 /* Want above */
#define NFSSTA_TIMEO 0x10000000 /* Experiencing a timeout */
+#define NFSSTA_LOCKTIMEO 0x20000000 /* Experiencing a lockd timeout */
/*
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 7876d32..03e672a 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -234,6 +234,13 @@ nfs_reclaim(struct vop_reclaim_args *ap)
vprint("nfs_reclaim: pushing active", vp);
/*
+ * If the NLM is running, give it a chance to abort pending
+ * locks.
+ */
+ if (nfs_reclaim_p)
+ nfs_reclaim_p(ap);
+
+ /*
* Destroy the vm object and flush associated pages.
*/
vnode_destroy_vobject(vp);
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index f342211..17536491 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -495,6 +495,7 @@ nfs_mountroot(struct mount *mp, struct thread *td)
(l >> 24) & 0xff, (l >> 16) & 0xff,
(l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
printf("NFS ROOT: %s\n", buf);
+ nd->root_args.hostname = buf;
if ((error = nfs_mountdiskless(buf,
&nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
return (error);
@@ -540,6 +541,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp)
int s;
int adjsock;
int maxio;
+ char *p;
s = splnet();
@@ -699,6 +701,11 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp)
(void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
}
}
+
+ strlcpy(nmp->nm_hostname, argp->hostname, sizeof(nmp->nm_hostname));
+ p = strchr(nmp->nm_hostname, ':');
+ if (p)
+ *p = '\0';
}
static const char *nfs_opts[] = { "from", "nfs_args",
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 524c564..3711165 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -198,6 +198,8 @@ struct mtx nfs_iod_mtx;
struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
int nfs_numasync = 0;
+vop_advlock_t *nfs_advlock_p = nfs_dolock;
+vop_reclaim_t *nfs_reclaim_p = NULL;
#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
SYSCTL_DECL(_vfs_nfs);
@@ -3051,8 +3053,13 @@ nfs_advlock(struct vop_advlock_args *ap)
size = VTONFS(vp)->n_size;
VOP_UNLOCK(vp, 0);
error = lf_advlock(ap, &(vp->v_lockf), size);
- } else
- error = nfs_dolock(ap);
+ } else {
+ if (nfs_advlock_p)
+ error = nfs_advlock_p(ap);
+ else
+ error = ENOLCK;
+ }
+
return (error);
}
diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h
index 8615846..6fa7f8b 100644
--- a/sys/nfsclient/nfsmount.h
+++ b/sys/nfsclient/nfsmount.h
@@ -91,6 +91,7 @@ struct nfsmount {
int nm_tprintf_initial_delay; /* initial delay */
int nm_tprintf_delay; /* interval for messages */
struct nfs_tcp_mountstate nm_nfstcpstate;
+ char nm_hostname[MNAMELEN]; /* server's name */
/* NFSv4 */
uint64_t nm_clientid;
diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h
index f227361..03e5e7f 100644
--- a/sys/nfsclient/nfsnode.h
+++ b/sys/nfsclient/nfsnode.h
@@ -187,6 +187,9 @@ extern struct vop_vector nfs4_vnodeops;
extern struct buf_ops buf_ops_nfs;
extern struct buf_ops buf_ops_nfs4;
+extern vop_advlock_t *nfs_advlock_p;
+extern vop_reclaim_t *nfs_reclaim_p;
+
/*
* Prototypes for NFS vnode operations
*/
OpenPOWER on IntegriCloud