* Copyright (c) 1989 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)nfs_syscalls.c 7.4 (Berkeley) %G%
extern u_long nfs_prog
, nfs_vers
;
extern int (*nfsrv_procs
[NFS_NPROCS
])();
extern struct buf nfs_bqueue
;
extern int nfs_asyncdaemons
;
extern struct proc
*nfs_iodwant
[MAX_ASYNCDAEMON
];
* NFS server system calls
* getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
#define RETURN(value) { u.u_error = (value); return; }
* Get file handle system call
} *uap
= (struct a
*)u
.u_ap
;
register struct nameidata
*ndp
= &u
.u_nd
;
register struct vnode
*vp
;
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
ndp
->ni_nameiop
= LOOKUP
| LOCKLEAF
| FOLLOW
;
ndp
->ni_segflg
= UIO_USERSPACE
;
ndp
->ni_dirp
= uap
->fname
;
bzero((caddr_t
)&fh
, sizeof(fh
));
fh
.fh_fsid
= vp
->v_mount
->m_fsid
;
error
= VFS_VPTOFH(vp
, &fh
.fh_fid
);
error
= copyout((caddr_t
)&fh
, (caddr_t
)uap
->fhp
, sizeof (fh
));
* Mark a mount point in the filesystem exported
} *uap
= (struct a
*)u
.u_ap
;
register struct nameidata
*ndp
= &u
.u_nd
;
register struct vnode
*vp
;
register struct mount
*mp
;
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
ndp
->ni_nameiop
= LOOKUP
| LOCKLEAF
| FOLLOW
; /* Or NOFOLLOW ?? */
ndp
->ni_segflg
= UIO_USERSPACE
;
ndp
->ni_dirp
= uap
->fname
;
if (vp
->v_type
!= VDIR
) {
* If the filesystem has already been exported, just relax
* Otherwise export it with the given security
if (mp
->m_flag
& M_EXPORTED
) {
if ((uap
->exflags
& M_EXRDONLY
) == 0)
mp
->m_flag
&= ~M_EXRDONLY
;
mp
->m_exroot
= uap
->rootuid
;
if (uap
->exflags
& M_EXRDONLY
)
mp
->m_flag
|= M_EXRDONLY
;
mp
->m_flag
|= M_EXPORTED
;
* Nfs server psuedo system call for the nfsd's
* Never returns unless it fails or gets killed
} *uap
= (struct a
*)u
.u_ap
;
register struct ucred
*cr
;
struct mbuf
*mreq
, *mrep
, *nam
, *md
;
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
so
= (struct socket
*)fp
->f_data
;
cr
= u
.u_cred
= crcopy(u
.u_cred
); /* Copy it so others don't see changes */
* Just loop arround doin our stuff until SIGKILL
if (error
= nfs_getreq(so
, nfs_prog
, nfs_vers
, NFS_NPROCS
-1,
&nam
, &mrep
, &md
, &dpos
, &retxid
, &procid
, cr
)) {
if (error
= (*(nfsrv_procs
[procid
]))(mrep
, md
, dpos
,
nfsstats
.srvrpccnt
[procid
]++;
if (siz
<= 0 || siz
> 9216) {
printf("mbuf siz=%d\n",siz
);
panic("Bad nfs svc reply");
error
= nfs_udpsend(so
, nam
, mreq
, 0, siz
);
* Nfs pseudo system call for asynchronous i/o daemons.
* These babies just pretend to be disk interrupt service routines
* for client nfs. They are mainly here for read ahead/write behind.
* Never returns unless it fails or gets killed
register struct buf
*bp
, *dp
;
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
* Assign my position or return error if too many already running
if (nfs_asyncdaemons
> MAX_ASYNCDAEMON
)
myiod
= nfs_asyncdaemons
++;
* Just loop around doin our stuff until SIGKILL
while (dp
->b_actf
== NULL
) {
nfs_iodwant
[myiod
] = u
.u_procp
;
sleep((caddr_t
)&nfs_iodwant
[myiod
], PZERO
+1);
/* Take one off the end of the list */
dp
->b_actf
= dp
->b_actl
= (struct buf
*)0;