xref: /csrg-svn/sys/nfs/nfs_vfsops.c (revision 43355)
138414Smckusick /*
238414Smckusick  * Copyright (c) 1989 The Regents of the University of California.
338414Smckusick  * All rights reserved.
438414Smckusick  *
538414Smckusick  * This code is derived from software contributed to Berkeley by
638414Smckusick  * Rick Macklem at The University of Guelph.
738414Smckusick  *
838414Smckusick  * Redistribution and use in source and binary forms are permitted
938414Smckusick  * provided that the above copyright notice and this paragraph are
1038414Smckusick  * duplicated in all such forms and that any documentation,
1138414Smckusick  * advertising materials, and other materials related to such
1238414Smckusick  * distribution and use acknowledge that the software was developed
1338414Smckusick  * by the University of California, Berkeley.  The name of the
1438414Smckusick  * University may not be used to endorse or promote products derived
1538414Smckusick  * from this software without specific prior written permission.
1638414Smckusick  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1738414Smckusick  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1838414Smckusick  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1938414Smckusick  *
20*43355Smckusick  *	@(#)nfs_vfsops.c	7.23 (Berkeley) 06/21/90
2138414Smckusick  */
2238414Smckusick 
2338414Smckusick #include "param.h"
2438414Smckusick #include "signal.h"
2538414Smckusick #include "user.h"
2638414Smckusick #include "proc.h"
2738414Smckusick #include "vnode.h"
2838414Smckusick #include "mount.h"
2938414Smckusick #include "errno.h"
3040120Smckusick #include "buf.h"
3138414Smckusick #include "mbuf.h"
3238414Smckusick #include "socket.h"
3340120Smckusick #include "systm.h"
3438414Smckusick #include "nfsv2.h"
3538414Smckusick #include "nfsnode.h"
3638414Smckusick #include "nfsmount.h"
3738414Smckusick #include "nfs.h"
3841904Smckusick #include "xdr_subs.h"
3941904Smckusick #include "nfsm_subs.h"
4038414Smckusick 
4138414Smckusick /*
4238414Smckusick  * nfs vfs operations.
4338414Smckusick  */
4438414Smckusick int nfs_mount();
4538874Smckusick int nfs_start();
4638414Smckusick int nfs_unmount();
4738414Smckusick int nfs_root();
4841294Smckusick int nfs_quotactl();
4939443Smckusick int nfs_statfs();
5038414Smckusick int nfs_sync();
5138414Smckusick int nfs_fhtovp();
5238414Smckusick int nfs_vptofh();
5339443Smckusick int nfs_init();
5438414Smckusick 
5538414Smckusick struct vfsops nfs_vfsops = {
5638414Smckusick 	nfs_mount,
5738874Smckusick 	nfs_start,
5838414Smckusick 	nfs_unmount,
5938414Smckusick 	nfs_root,
6041294Smckusick 	nfs_quotactl,
6138414Smckusick 	nfs_statfs,
6238414Smckusick 	nfs_sync,
6338414Smckusick 	nfs_fhtovp,
6438414Smckusick 	nfs_vptofh,
6539443Smckusick 	nfs_init,
6638414Smckusick };
6738414Smckusick 
6839757Smckusick static u_char nfs_mntid;
6941904Smckusick extern u_long nfs_procids[NFS_NPROCS];
7041904Smckusick extern u_long nfs_prog, nfs_vers;
7141904Smckusick void nfs_disconnect();
7238414Smckusick 
7341904Smckusick #define TRUE	1
7441904Smckusick #define	FALSE	0
7541904Smckusick 
7638414Smckusick /*
7741904Smckusick  * nfs statfs call
7841904Smckusick  */
7941904Smckusick nfs_statfs(mp, sbp)
8041904Smckusick 	struct mount *mp;
8141904Smckusick 	register struct statfs *sbp;
8241904Smckusick {
8341904Smckusick 	register struct vnode *vp;
8441904Smckusick 	register struct nfsv2_statfs *sfp;
8541904Smckusick 	register caddr_t cp;
8641904Smckusick 	register long t1;
8741904Smckusick 	caddr_t bpos, dpos, cp2;
8841904Smckusick 	u_long xid;
8941904Smckusick 	int error = 0;
9041904Smckusick 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
9141904Smckusick 	struct nfsmount *nmp;
9241904Smckusick 	struct ucred *cred;
9341904Smckusick 	struct nfsnode *np;
9441904Smckusick 
9541904Smckusick 	nmp = VFSTONFS(mp);
9641904Smckusick 	if (error = nfs_nget(mp, &nmp->nm_fh, &np))
9741904Smckusick 		return (error);
9841904Smckusick 	vp = NFSTOV(np);
9941904Smckusick 	nfsstats.rpccnt[NFSPROC_STATFS]++;
10041904Smckusick 	cred = crget();
10141904Smckusick 	cred->cr_ngroups = 1;
10241904Smckusick 	nfsm_reqhead(nfs_procids[NFSPROC_STATFS], cred, NFSX_FH);
10341904Smckusick 	nfsm_fhtom(vp);
104*43355Smckusick 	nfsm_request(vp, NFSPROC_STATFS, u.u_procp, 0);
10541904Smckusick 	nfsm_disect(sfp, struct nfsv2_statfs *, NFSX_STATFS);
10641904Smckusick 	sbp->f_type = MOUNT_NFS;
10741904Smckusick 	sbp->f_flags = nmp->nm_flag;
10841904Smckusick 	sbp->f_bsize = fxdr_unsigned(long, sfp->sf_tsize);
10941904Smckusick 	sbp->f_fsize = fxdr_unsigned(long, sfp->sf_bsize);
11041904Smckusick 	sbp->f_blocks = fxdr_unsigned(long, sfp->sf_blocks);
11141904Smckusick 	sbp->f_bfree = fxdr_unsigned(long, sfp->sf_bfree);
11241904Smckusick 	sbp->f_bavail = fxdr_unsigned(long, sfp->sf_bavail);
11341904Smckusick 	sbp->f_files = 0;
11441904Smckusick 	sbp->f_ffree = 0;
11541904Smckusick 	if (sbp != &mp->mnt_stat) {
11641904Smckusick 		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
11741904Smckusick 		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
11841904Smckusick 	}
11941904Smckusick 	nfsm_reqdone;
12041904Smckusick 	nfs_nput(vp);
12141904Smckusick 	crfree(cred);
12241904Smckusick 	return (error);
12341904Smckusick }
12441904Smckusick 
12541904Smckusick /*
12638414Smckusick  * Called by vfs_mountroot when nfs is going to be mounted as root
12738414Smckusick  * Not Yet (By a LONG shot)
12838414Smckusick  */
12938414Smckusick nfs_mountroot()
13038414Smckusick {
13138414Smckusick 	return (ENODEV);
13238414Smckusick }
13338414Smckusick 
13438414Smckusick /*
13538414Smckusick  * VFS Operations.
13638414Smckusick  *
13738414Smckusick  * mount system call
13838414Smckusick  * It seems a bit dumb to copyinstr() the host and path here and then
13938414Smckusick  * bcopy() them in mountnfs(), but I wanted to detect errors before
14038414Smckusick  * doing the sockargs() call because sockargs() allocates an mbuf and
14138414Smckusick  * an error after that means that I have to release the mbuf.
14238414Smckusick  */
14339494Smckusick /* ARGSUSED */
14438414Smckusick nfs_mount(mp, path, data, ndp)
14538414Smckusick 	struct mount *mp;
14638414Smckusick 	char *path;
14738414Smckusick 	caddr_t data;
14838414Smckusick 	struct nameidata *ndp;
14938414Smckusick {
15038414Smckusick 	int error;
15138414Smckusick 	struct nfs_args args;
15241904Smckusick 	struct mbuf *nam;
15338414Smckusick 	char pth[MNAMELEN], hst[MNAMELEN];
15438414Smckusick 	int len;
15538414Smckusick 	nfsv2fh_t nfh;
15638414Smckusick 
15741398Smckusick 	if (mp->mnt_flag & MNT_UPDATE)
15839460Smckusick 		return (0);
15938414Smckusick 	if (error = copyin(data, (caddr_t)&args, sizeof (struct nfs_args)))
16038414Smckusick 		return (error);
16138414Smckusick 	if (error=copyin((caddr_t)args.fh, (caddr_t)&nfh, sizeof (nfsv2fh_t)))
16238414Smckusick 		return (error);
16338414Smckusick 	if (error = copyinstr(path, pth, MNAMELEN-1, &len))
16438414Smckusick 		return (error);
16538414Smckusick 	bzero(&pth[len], MNAMELEN-len);
16638414Smckusick 	if (error = copyinstr(args.hostname, hst, MNAMELEN-1, &len))
16738414Smckusick 		return (error);
16838414Smckusick 	bzero(&hst[len], MNAMELEN-len);
16938414Smckusick 	/* sockargs() call must be after above copyin() calls */
17041904Smckusick 	if (error = sockargs(&nam, (caddr_t)args.addr,
17140120Smckusick 		sizeof (struct sockaddr), MT_SONAME))
17238414Smckusick 		return (error);
17338414Smckusick 	args.fh = &nfh;
17441904Smckusick 	error = mountnfs(&args, mp, nam, pth, hst);
17538414Smckusick 	return (error);
17638414Smckusick }
17738414Smckusick 
17838414Smckusick /*
17938414Smckusick  * Common code for mount and mountroot
18038414Smckusick  */
18141904Smckusick mountnfs(argp, mp, nam, pth, hst)
18238414Smckusick 	register struct nfs_args *argp;
18338414Smckusick 	register struct mount *mp;
18441904Smckusick 	struct mbuf *nam;
18538414Smckusick 	char *pth, *hst;
18638414Smckusick {
18738414Smckusick 	register struct nfsmount *nmp;
18840010Smckusick 	struct nfsnode *np;
18940120Smckusick 	int error;
19039757Smckusick 	fsid_t tfsid;
19138414Smckusick 
19240120Smckusick 	MALLOC(nmp, struct nfsmount *, sizeof *nmp, M_NFSMNT, M_WAITOK);
19340120Smckusick 	bzero((caddr_t)nmp, sizeof *nmp);
19441398Smckusick 	mp->mnt_data = (qaddr_t)nmp;
19539757Smckusick 	/*
19639757Smckusick 	 * Generate a unique nfs mount id. The problem is that a dev number
19739757Smckusick 	 * is not unique across multiple systems. The techique is as follows:
19839757Smckusick 	 * 1) Set to nblkdev,0 which will never be used otherwise
19939757Smckusick 	 * 2) Generate a first guess as nblkdev,nfs_mntid where nfs_mntid is
20039757Smckusick 	 *	NOT 0
20139757Smckusick 	 * 3) Loop searching the mount list for another one with same id
20239757Smckusick 	 *	If a match, increment val[0] and try again
20339757Smckusick 	 * NB: I increment val[0] { a long } instead of nfs_mntid { a u_char }
20439757Smckusick 	 *	so that nfs is not limited to 255 mount points
20539757Smckusick 	 *     Incrementing the high order bits does no real harm, since it
20639757Smckusick 	 *     simply makes the major dev number tick up. The upper bound is
20739757Smckusick 	 *     set to major dev 127 to avoid any sign extention problems
20839757Smckusick 	 */
20941398Smckusick 	mp->mnt_stat.f_fsid.val[0] = makedev(nblkdev, 0);
21041398Smckusick 	mp->mnt_stat.f_fsid.val[1] = MOUNT_NFS;
21139757Smckusick 	if (++nfs_mntid == 0)
21239757Smckusick 		++nfs_mntid;
21339757Smckusick 	tfsid.val[0] = makedev(nblkdev, nfs_mntid);
21439757Smckusick 	tfsid.val[1] = MOUNT_NFS;
21539757Smckusick 	while (getvfs(&tfsid)) {
21639757Smckusick 		tfsid.val[0]++;
21739757Smckusick 		nfs_mntid++;
21839757Smckusick 	}
21939757Smckusick 	if (major(tfsid.val[0]) > 127) {
22039757Smckusick 		error = ENOENT;
22139757Smckusick 		goto bad;
22239757Smckusick 	}
22341398Smckusick 	mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
22438414Smckusick 	nmp->nm_mountp = mp;
22538414Smckusick 	nmp->nm_flag = argp->flags;
22640120Smckusick 	nmp->nm_rto = NFS_TIMEO;
22740120Smckusick 	nmp->nm_rtt = -1;
22840120Smckusick 	nmp->nm_rttvar = nmp->nm_rto << 1;
22940120Smckusick 	nmp->nm_retry = NFS_RETRANS;
23040120Smckusick 	nmp->nm_wsize = NFS_WSIZE;
23140120Smckusick 	nmp->nm_rsize = NFS_RSIZE;
23240120Smckusick 	bcopy((caddr_t)argp->fh, (caddr_t)&nmp->nm_fh, sizeof(nfsv2fh_t));
23341398Smckusick 	mp->mnt_stat.f_type = MOUNT_NFS;
23441398Smckusick 	bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
23541398Smckusick 	bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN);
23641904Smckusick 	nmp->nm_nam = nam;
23740120Smckusick 
23840120Smckusick 	if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
23940120Smckusick 		nmp->nm_rto = argp->timeo;
24040120Smckusick 		/* NFS timeouts are specified in 1/10 sec. */
24140120Smckusick 		nmp->nm_rto = (nmp->nm_rto * 10) / NFS_HZ;
24240120Smckusick 		if (nmp->nm_rto < NFS_MINTIMEO)
24340120Smckusick 			nmp->nm_rto = NFS_MINTIMEO;
24440120Smckusick 		else if (nmp->nm_rto > NFS_MAXTIMEO)
24540120Smckusick 			nmp->nm_rto = NFS_MAXTIMEO;
24640120Smckusick 		nmp->nm_rttvar = nmp->nm_rto << 1;
24740120Smckusick 	}
24840120Smckusick 
249*43355Smckusick 	if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
25040120Smckusick 		nmp->nm_retry = argp->retrans;
25140120Smckusick 		if (nmp->nm_retry > NFS_MAXREXMIT)
25240120Smckusick 			nmp->nm_retry = NFS_MAXREXMIT;
25340120Smckusick 	}
25440120Smckusick 
25540120Smckusick 	if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
25638414Smckusick 		nmp->nm_wsize = argp->wsize;
25740120Smckusick 		/* Round down to multiple of blocksize */
25840120Smckusick 		nmp->nm_wsize &= ~0x1ff;
25940120Smckusick 		if (nmp->nm_wsize <= 0)
26040120Smckusick 			nmp->nm_wsize = 512;
26140120Smckusick 		else if (nmp->nm_wsize > NFS_MAXDATA)
26240120Smckusick 			nmp->nm_wsize = NFS_MAXDATA;
26340120Smckusick 	}
264*43355Smckusick 	if (nmp->nm_wsize > MAXBSIZE)
265*43355Smckusick 		nmp->nm_wsize = MAXBSIZE;
26640120Smckusick 
26740120Smckusick 	if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
26838414Smckusick 		nmp->nm_rsize = argp->rsize;
26940120Smckusick 		/* Round down to multiple of blocksize */
27040120Smckusick 		nmp->nm_rsize &= ~0x1ff;
27140120Smckusick 		if (nmp->nm_rsize <= 0)
27240120Smckusick 			nmp->nm_rsize = 512;
27340120Smckusick 		else if (nmp->nm_rsize > NFS_MAXDATA)
27440120Smckusick 			nmp->nm_rsize = NFS_MAXDATA;
27540120Smckusick 	}
276*43355Smckusick 	if (nmp->nm_rsize > MAXBSIZE)
277*43355Smckusick 		nmp->nm_rsize = MAXBSIZE;
27840120Smckusick 	/* Set up the sockets and per-host congestion */
27941904Smckusick 	nmp->nm_sotype = argp->sotype;
28041904Smckusick 	nmp->nm_soproto = argp->proto;
28141904Smckusick 	if (error = nfs_connect(nmp))
28240120Smckusick 		goto bad;
28340120Smckusick 
28441398Smckusick 	if (error = nfs_statfs(mp, &mp->mnt_stat))
28540353Smckusick 		goto bad;
28638414Smckusick 	/*
28740010Smckusick 	 * A reference count is needed on the nfsnode representing the
28840010Smckusick 	 * remote root.  If this object is not persistent, then backward
28940010Smckusick 	 * traversals of the mount point (i.e. "..") will not work if
29040010Smckusick 	 * the nfsnode gets flushed out of the cache. Ufs does not have
29140010Smckusick 	 * this problem, because one can identify root inodes by their
29240010Smckusick 	 * number == ROOTINO (2).
29340010Smckusick 	 */
29440010Smckusick 	if (error = nfs_nget(mp, &nmp->nm_fh, &np))
29540010Smckusick 		goto bad;
29640010Smckusick 	/*
29740010Smckusick 	 * Unlock it, but keep the reference count.
29840010Smckusick 	 */
29940010Smckusick 	nfs_unlock(NFSTOV(np));
30041904Smckusick 
30140353Smckusick 	return (0);
30238414Smckusick bad:
30340120Smckusick 	nfs_disconnect(nmp);
30440120Smckusick 	FREE(nmp, M_NFSMNT);
30541904Smckusick 	m_freem(nam);
30638414Smckusick 	return (error);
30738414Smckusick }
30838414Smckusick 
30938414Smckusick /*
31038414Smckusick  * unmount system call
31138414Smckusick  */
31241294Smckusick nfs_unmount(mp, mntflags)
31338414Smckusick 	struct mount *mp;
31441294Smckusick 	int mntflags;
31538414Smckusick {
31638414Smckusick 	register struct nfsmount *nmp;
31740010Smckusick 	struct nfsnode *np;
31840120Smckusick 	struct vnode *vp;
31941294Smckusick 	int flags = 0;
32038414Smckusick 	int error;
32138414Smckusick 
32241294Smckusick 	if (mntflags & MNT_FORCE)
32338414Smckusick 		return (EINVAL);
32441294Smckusick 	if (mntflags & MNT_FORCE)
32541294Smckusick 		flags |= FORCECLOSE;
32641398Smckusick 	nmp = VFSTONFS(mp);
32738414Smckusick 	/*
32838884Smacklem 	 * Clear out the buffer cache
32938884Smacklem 	 */
33039669Smckusick 	mntflushbuf(mp, 0);
33139669Smckusick 	if (mntinvalbuf(mp))
33238884Smacklem 		return (EBUSY);
33338884Smacklem 	/*
33438414Smckusick 	 * Goes something like this..
33540120Smckusick 	 * - Check for activity on the root vnode (other than ourselves).
33640120Smckusick 	 * - Call vflush() to clear out vnodes for this file system,
33740120Smckusick 	 *   except for the root vnode.
33840120Smckusick 	 * - Decrement reference on the vnode representing remote root.
33938414Smckusick 	 * - Close the socket
34038414Smckusick 	 * - Free up the data structures
34138414Smckusick 	 */
34240010Smckusick 	/*
34340010Smckusick 	 * We need to decrement the ref. count on the nfsnode representing
34440010Smckusick 	 * the remote root.  See comment in mountnfs().  The VFS unmount()
34540010Smckusick 	 * has done vput on this vnode, otherwise we would get deadlock!
34640010Smckusick 	 */
34740010Smckusick 	if (error = nfs_nget(mp, &nmp->nm_fh, &np))
34840010Smckusick 		return(error);
34940120Smckusick 	vp = NFSTOV(np);
35040120Smckusick 	if (vp->v_usecount > 2) {
35140120Smckusick 		vput(vp);
35240120Smckusick 		return (EBUSY);
35340120Smckusick 	}
35440120Smckusick 	if (error = vflush(mp, vp, flags)) {
35540120Smckusick 		vput(vp);
35640120Smckusick 		return (error);
35740120Smckusick 	}
35840010Smckusick 	/*
35940010Smckusick 	 * Get rid of two reference counts, and unlock it on the second.
36040010Smckusick 	 */
36140120Smckusick 	vrele(vp);
36240120Smckusick 	vput(vp);
36340120Smckusick 	nfs_disconnect(nmp);
36441904Smckusick 	m_freem(nmp->nm_nam);
36538414Smckusick 	free((caddr_t)nmp, M_NFSMNT);
36638414Smckusick 	return (0);
36738414Smckusick }
36838414Smckusick 
36938414Smckusick /*
37038414Smckusick  * Return root of a filesystem
37138414Smckusick  */
37238414Smckusick nfs_root(mp, vpp)
37338414Smckusick 	struct mount *mp;
37438414Smckusick 	struct vnode **vpp;
37538414Smckusick {
37638414Smckusick 	register struct vnode *vp;
37738414Smckusick 	struct nfsmount *nmp;
37838414Smckusick 	struct nfsnode *np;
37938414Smckusick 	int error;
38038414Smckusick 
38141398Smckusick 	nmp = VFSTONFS(mp);
38238414Smckusick 	if (error = nfs_nget(mp, &nmp->nm_fh, &np))
38338414Smckusick 		return (error);
38438414Smckusick 	vp = NFSTOV(np);
38538414Smckusick 	vp->v_type = VDIR;
38638414Smckusick 	vp->v_flag = VROOT;
38738414Smckusick 	*vpp = vp;
38838414Smckusick 	return (0);
38938414Smckusick }
39038414Smckusick 
39138884Smacklem extern int syncprt;
39238884Smacklem 
39338414Smckusick /*
39438884Smacklem  * Flush out the buffer cache
39538414Smckusick  */
39639494Smckusick /* ARGSUSED */
39738414Smckusick nfs_sync(mp, waitfor)
39838414Smckusick 	struct mount *mp;
39938414Smckusick 	int waitfor;
40038414Smckusick {
40138884Smacklem 	if (syncprt)
40238884Smacklem 		bufstats();
40338884Smacklem 	/*
40438884Smacklem 	 * Force stale buffer cache information to be flushed.
40538884Smacklem 	 */
40640035Smckusick 	mntflushbuf(mp, waitfor == MNT_WAIT ? B_SYNC : 0);
40738414Smckusick 	return (0);
40838414Smckusick }
40938414Smckusick 
41038414Smckusick /*
41138414Smckusick  * At this point, this should never happen
41238414Smckusick  */
41339494Smckusick /* ARGSUSED */
41438414Smckusick nfs_fhtovp(mp, fhp, vpp)
41538414Smckusick 	struct mount *mp;
41638414Smckusick 	struct fid *fhp;
41738414Smckusick 	struct vnode **vpp;
41838414Smckusick {
41939494Smckusick 
42038414Smckusick 	return (EINVAL);
42138414Smckusick }
42238414Smckusick 
42338414Smckusick /*
42438414Smckusick  * Vnode pointer to File handle, should never happen either
42538414Smckusick  */
42639494Smckusick /* ARGSUSED */
42738414Smckusick nfs_vptofh(mp, fhp, vpp)
42838414Smckusick 	struct mount *mp;
42938414Smckusick 	struct fid *fhp;
43038414Smckusick 	struct vnode **vpp;
43138414Smckusick {
43239494Smckusick 
43338414Smckusick 	return (EINVAL);
43438414Smckusick }
43538884Smacklem 
43638884Smacklem /*
43738884Smacklem  * Vfs start routine, a no-op.
43838884Smacklem  */
43939494Smckusick /* ARGSUSED */
44038884Smacklem nfs_start(mp, flags)
44138884Smacklem 	struct mount *mp;
44238884Smacklem 	int flags;
44338884Smacklem {
44439494Smckusick 
44538884Smacklem 	return (0);
44638884Smacklem }
44741294Smckusick 
44841294Smckusick /*
44941294Smckusick  * Do operations associated with quotas, not supported
45041294Smckusick  */
45141294Smckusick nfs_quotactl(mp, cmd, uid, arg)
45241294Smckusick 	struct mount *mp;
45341294Smckusick 	int cmd;
45441294Smckusick 	uid_t uid;
45541294Smckusick 	caddr_t arg;
45641294Smckusick {
45742245Smckusick #ifdef lint
45842245Smckusick 	mp = mp; cmd = cmd; uid = uid; arg = arg;
45942245Smckusick #endif /* lint */
46041294Smckusick 	return (EOPNOTSUPP);
46141294Smckusick }
462