38 */ 39 40#include <sys/param.h> 41#include <sys/sockio.h> 42#include <sys/proc.h> 43#include <sys/vnode.h> 44#include <sys/kernel.h> 45#include <sys/sysctl.h> 46#include <sys/malloc.h> 47#include <sys/mount.h> 48#include <sys/mbuf.h> 49#include <sys/socket.h> 50#include <sys/socketvar.h> 51#include <sys/systm.h> 52 53#include <vm/vm.h> 54#include <vm/vm_extern.h> 55#include <vm/vm_zone.h> 56 57#include <net/if.h> 58#include <net/route.h> 59#include <netinet/in.h> 60 61#include <nfs/rpcv2.h> 62#include <nfs/nfsproto.h> 63#include <nfs/nfs.h> 64#include <nfs/nfsnode.h> 65#include <nfs/nfsmount.h> 66#include <nfs/xdr_subs.h> 67#include <nfs/nfsm_subs.h> 68#include <nfs/nfsdiskless.h> 69#include <nfs/nqnfs.h> 70 71extern int nfs_mountroot __P((struct mount *mp)); 72 73extern int nfs_ticks; 74 75MALLOC_DEFINE(M_NFSREQ, "NFS req", "NFS request header"); 76MALLOC_DEFINE(M_NFSBIGFH, "NFSV3 bigfh", "NFS version 3 file handle"); 77MALLOC_DEFINE(M_NFSD, "NFS daemon", "Nfs server daemon structure"); 78MALLOC_DEFINE(M_NFSDIROFF, "NFSV3 diroff", "NFS directory offset data"); 79MALLOC_DEFINE(M_NFSRVDESC, "NFSV3 srvdesc", "NFS server socket descriptor"); 80MALLOC_DEFINE(M_NFSUID, "NFS uid", "Nfs uid mapping structure"); 81MALLOC_DEFINE(M_NQLEASE, "NQNFS Lease", "Nqnfs lease"); 82MALLOC_DEFINE(M_NFSHASH, "NFS hash", "NFS hash tables"); 83 84vm_zone_t nfsmount_zone; 85 86struct nfsstats nfsstats; 87SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem"); 88SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RD, 89 &nfsstats, nfsstats, ""); 90#ifdef NFS_DEBUG 91int nfs_debug; 92SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, ""); 93#endif 94 95static int nfs_iosize __P((struct nfsmount *nmp)); 96static void nfs_decode_args __P((struct nfsmount *nmp, 97 struct nfs_args *argp)); 98static int mountnfs __P((struct nfs_args *,struct mount *, 99 struct sockaddr *,char *,char *,struct vnode **)); 100static int nfs_mount __P(( struct mount *mp, char *path, caddr_t data, 101 struct nameidata *ndp, struct proc *p)); 102static int nfs_start __P(( struct mount *mp, int flags, 103 struct proc *p)); 104static int nfs_unmount __P(( struct mount *mp, int mntflags, 105 struct proc *p)); 106static int nfs_root __P(( struct mount *mp, struct vnode **vpp)); 107static int nfs_quotactl __P(( struct mount *mp, int cmds, uid_t uid, 108 caddr_t arg, struct proc *p)); 109static int nfs_statfs __P(( struct mount *mp, struct statfs *sbp, 110 struct proc *p)); 111static int nfs_sync __P(( struct mount *mp, int waitfor, 112 struct ucred *cred, struct proc *p)); 113static int nfs_vptofh __P(( struct vnode *vp, struct fid *fhp)); 114static int nfs_fhtovp __P((struct mount *mp, struct fid *fhp, 115 struct sockaddr *nam, struct vnode **vpp, 116 int *exflagsp, struct ucred **credanonp)); 117static int nfs_vget __P((struct mount *, ino_t, struct vnode **)); 118 119 120/* 121 * nfs vfs operations. 122 */ 123static struct vfsops nfs_vfsops = { 124 nfs_mount, 125 nfs_start, 126 nfs_unmount, 127 nfs_root, 128 nfs_quotactl, 129 nfs_statfs, 130 nfs_sync, 131 nfs_vget, 132 nfs_fhtovp, 133 nfs_vptofh, 134 nfs_init, 135 nfs_uninit, 136 &sysctl___vfs_nfs 137}; 138VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK); 139 140/* 141 * This structure must be filled in by a primary bootstrap or bootstrap 142 * server for a diskless/dataless machine. It is initialized below just 143 * to ensure that it is allocated to initialized data (.data not .bss). 144 */ 145struct nfs_diskless nfs_diskless = { 0 }; 146struct nfsv3_diskless nfsv3_diskless = { 0 }; 147int nfs_diskless_valid = 0; 148 149SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD, 150 &nfs_diskless_valid, 0, ""); 151 152SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD, 153 nfsv3_diskless.root_hostnam, 0, ""); 154 155SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD, 156 &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr, 157 "%Ssockaddr_in", ""); 158 159SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_swappath, CTLFLAG_RD, 160 nfsv3_diskless.swap_hostnam, 0, ""); 161 162SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_swapaddr, CTLFLAG_RD, 163 &nfsv3_diskless.swap_saddr, sizeof nfsv3_diskless.swap_saddr, 164 "%Ssockaddr_in",""); 165 166 167void nfsargs_ntoh __P((struct nfs_args *)); 168static int nfs_mountdiskless __P((char *, char *, int, 169 struct sockaddr_in *, struct nfs_args *, 170 struct proc *, struct vnode **, 171 struct mount **)); 172static void nfs_convert_diskless __P((void)); 173static void nfs_convert_oargs __P((struct nfs_args *args, 174 struct onfs_args *oargs)); 175 176static int 177nfs_iosize(nmp) 178 struct nfsmount* nmp; 179{ 180 int iosize; 181 182 /* 183 * Calculate the size used for io buffers. Use the larger 184 * of the two sizes to minimise nfs requests but make sure 185 * that it is at least one VM page to avoid wasting buffer 186 * space. 187 */ 188 iosize = max(nmp->nm_rsize, nmp->nm_wsize); 189 if (iosize < PAGE_SIZE) iosize = PAGE_SIZE; 190 return iosize; 191} 192 193static void 194nfs_convert_oargs(args, oargs) 195 struct nfs_args *args; 196 struct onfs_args *oargs; 197{ 198 args->version = NFS_ARGSVERSION; 199 args->addr = oargs->addr; 200 args->addrlen = oargs->addrlen; 201 args->sotype = oargs->sotype; 202 args->proto = oargs->proto; 203 args->fh = oargs->fh; 204 args->fhsize = oargs->fhsize; 205 args->flags = oargs->flags; 206 args->wsize = oargs->wsize; 207 args->rsize = oargs->rsize; 208 args->readdirsize = oargs->readdirsize; 209 args->timeo = oargs->timeo; 210 args->retrans = oargs->retrans; 211 args->maxgrouplist = oargs->maxgrouplist; 212 args->readahead = oargs->readahead; 213 args->leaseterm = oargs->leaseterm; 214 args->deadthresh = oargs->deadthresh; 215 args->hostname = oargs->hostname; 216} 217 218static void 219nfs_convert_diskless() 220{ 221 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif, 222 sizeof(struct ifaliasreq)); 223 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway, 224 sizeof(struct sockaddr_in)); 225 nfs_convert_oargs(&nfsv3_diskless.swap_args,&nfs_diskless.swap_args); 226 nfsv3_diskless.swap_fhsize = NFSX_V2FH; 227 bcopy(nfs_diskless.swap_fh,nfsv3_diskless.swap_fh,NFSX_V2FH); 228 bcopy(&nfs_diskless.swap_saddr,&nfsv3_diskless.swap_saddr, 229 sizeof(struct sockaddr_in)); 230 bcopy(nfs_diskless.swap_hostnam,nfsv3_diskless.swap_hostnam, MNAMELEN); 231 nfsv3_diskless.swap_nblks = nfs_diskless.swap_nblks; 232 bcopy(&nfs_diskless.swap_ucred, &nfsv3_diskless.swap_ucred, 233 sizeof(struct ucred)); 234 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args); 235 nfsv3_diskless.root_fhsize = NFSX_V2FH; 236 bcopy(nfs_diskless.root_fh,nfsv3_diskless.root_fh,NFSX_V2FH); 237 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr, 238 sizeof(struct sockaddr_in)); 239 bcopy(nfs_diskless.root_hostnam,nfsv3_diskless.root_hostnam, MNAMELEN); 240 nfsv3_diskless.root_time = nfs_diskless.root_time; 241 bcopy(nfs_diskless.my_hostnam,nfsv3_diskless.my_hostnam, 242 MAXHOSTNAMELEN); 243 nfs_diskless_valid = 3; 244} 245 246/* 247 * nfs statfs call 248 */ 249int 250nfs_statfs(mp, sbp, p) 251 struct mount *mp; 252 register struct statfs *sbp; 253 struct proc *p; 254{ 255 register struct vnode *vp; 256 register struct nfs_statfs *sfp; 257 register caddr_t cp; 258 register u_int32_t *tl; 259 register int32_t t1, t2; 260 caddr_t bpos, dpos, cp2; 261 struct nfsmount *nmp = VFSTONFS(mp); 262 int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr; 263 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 264 struct ucred *cred; 265 struct nfsnode *np; 266 u_quad_t tquad; 267 268#ifndef nolint 269 sfp = (struct nfs_statfs *)0; 270#endif 271 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np); 272 if (error) 273 return (error); 274 vp = NFSTOV(np); 275 cred = crget(); 276 cred->cr_ngroups = 1; 277 if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) 278 (void)nfs_fsinfo(nmp, vp, cred, p); 279 nfsstats.rpccnt[NFSPROC_FSSTAT]++; 280 nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3)); 281 nfsm_fhtom(vp, v3); 282 nfsm_request(vp, NFSPROC_FSSTAT, p, cred); 283 if (v3) 284 nfsm_postop_attr(vp, retattr); 285 if (error) { 286 if (mrep != NULL) 287 m_free(mrep); 288 goto nfsmout; 289 } 290 nfsm_dissect(sfp, struct nfs_statfs *, NFSX_STATFS(v3)); 291 sbp->f_flags = nmp->nm_flag; 292 sbp->f_iosize = nfs_iosize(nmp); 293 if (v3) { 294 sbp->f_bsize = NFS_FABLKSIZE; 295 fxdr_hyper(&sfp->sf_tbytes, &tquad); 296 sbp->f_blocks = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE)); 297 fxdr_hyper(&sfp->sf_fbytes, &tquad); 298 sbp->f_bfree = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE)); 299 fxdr_hyper(&sfp->sf_abytes, &tquad); 300 sbp->f_bavail = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE)); 301 sbp->f_files = (fxdr_unsigned(int32_t, 302 sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff); 303 sbp->f_ffree = (fxdr_unsigned(int32_t, 304 sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff); 305 } else { 306 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize); 307 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks); 308 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree); 309 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail); 310 sbp->f_files = 0; 311 sbp->f_ffree = 0; 312 } 313 if (sbp != &mp->mnt_stat) { 314 sbp->f_type = mp->mnt_vfc->vfc_typenum; 315 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 316 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 317 } 318 nfsm_reqdone; 319 vput(vp); 320 crfree(cred); 321 return (error); 322} 323 324/* 325 * nfs version 3 fsinfo rpc call 326 */ 327int 328nfs_fsinfo(nmp, vp, cred, p) 329 register struct nfsmount *nmp; 330 register struct vnode *vp; 331 struct ucred *cred; 332 struct proc *p; 333{ 334 register struct nfsv3_fsinfo *fsp; 335 register caddr_t cp; 336 register int32_t t1, t2; 337 register u_int32_t *tl, pref, max; 338 caddr_t bpos, dpos, cp2; 339 int error = 0, retattr; 340 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 341 u_int64_t maxfsize; 342 343 nfsstats.rpccnt[NFSPROC_FSINFO]++; 344 nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1)); 345 nfsm_fhtom(vp, 1); 346 nfsm_request(vp, NFSPROC_FSINFO, p, cred); 347 nfsm_postop_attr(vp, retattr); 348 if (!error) { 349 nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO); 350 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref); 351 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE) 352 nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & 353 ~(NFS_FABLKSIZE - 1); 354 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax); 355 if (max < nmp->nm_wsize && max > 0) { 356 nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1); 357 if (nmp->nm_wsize == 0) 358 nmp->nm_wsize = max; 359 } 360 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref); 361 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE) 362 nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & 363 ~(NFS_FABLKSIZE - 1); 364 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax); 365 if (max < nmp->nm_rsize && max > 0) { 366 nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1); 367 if (nmp->nm_rsize == 0) 368 nmp->nm_rsize = max; 369 } 370 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref); 371 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ) 372 nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & 373 ~(NFS_DIRBLKSIZ - 1); 374 if (max < nmp->nm_readdirsize && max > 0) { 375 nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1); 376 if (nmp->nm_readdirsize == 0) 377 nmp->nm_readdirsize = max; 378 } 379 fxdr_hyper(&fsp->fs_maxfilesize, &maxfsize); 380 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize) 381 nmp->nm_maxfilesize = maxfsize; 382 nmp->nm_state |= NFSSTA_GOTFSINFO; 383 } 384 nfsm_reqdone; 385 return (error); 386} 387 388/* 389 * Mount a remote root fs via. nfs. This depends on the info in the 390 * nfs_diskless structure that has been filled in properly by some primary 391 * bootstrap. 392 * It goes something like this: 393 * - do enough of "ifconfig" by calling ifioctl() so that the system 394 * can talk to the server 395 * - If nfs_diskless.mygateway is filled in, use that address as 396 * a default gateway. 397 * - build the rootfs mount point and call mountnfs() to do the rest. 398 */ 399int 400nfs_mountroot(mp) 401 struct mount *mp; 402{ 403 struct mount *swap_mp; 404 struct nfsv3_diskless *nd = &nfsv3_diskless; 405 struct socket *so; 406 struct vnode *vp; 407 struct proc *p = curproc; /* XXX */ 408 int error, i; 409 u_long l; 410 char buf[128]; 411 412 /* 413 * XXX time must be non-zero when we init the interface or else 414 * the arp code will wedge... 415 */ 416 while (time_second == 0) 417 tsleep(&time_second, PZERO+8, "arpkludge", 10); 418 419 if (nfs_diskless_valid==1) 420 nfs_convert_diskless(); 421 422 /* 423 * XXX splnet, so networks will receive... 424 */ 425 splnet(); 426 427#ifdef notyet 428 /* Set up swap credentials. */ 429 proc0.p_ucred->cr_uid = ntohl(nd->swap_ucred.cr_uid); 430 proc0.p_ucred->cr_gid = ntohl(nd->swap_ucred.cr_gid); 431 if ((proc0.p_ucred->cr_ngroups = ntohs(nd->swap_ucred.cr_ngroups)) > 432 NGROUPS) 433 proc0.p_ucred->cr_ngroups = NGROUPS; 434 for (i = 0; i < proc0.p_ucred->cr_ngroups; i++) 435 proc0.p_ucred->cr_groups[i] = ntohl(nd->swap_ucred.cr_groups[i]); 436#endif 437 438 /* 439 * Do enough of ifconfig(8) so that the critical net interface can 440 * talk to the server. 441 */ 442 error = socreate(nd->myif.ifra_addr.sa_family, &so, SOCK_DGRAM, 0, p); 443 if (error) 444 panic("nfs_mountroot: socreate(%04x): %d", 445 nd->myif.ifra_addr.sa_family, error); 446 447 /* 448 * We might not have been told the right interface, so we pass 449 * over the first ten interfaces of the same kind, until we get 450 * one of them configured. 451 */ 452 453 for (i = strlen(nd->myif.ifra_name) - 1; 454 nd->myif.ifra_name[i] >= '0' && 455 nd->myif.ifra_name[i] <= '9'; 456 nd->myif.ifra_name[i] ++) { 457 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, p); 458 if(!error) 459 break; 460 } 461 if (error) 462 panic("nfs_mountroot: SIOCAIFADDR: %d", error); 463 soclose(so); 464 465 /* 466 * If the gateway field is filled in, set it as the default route. 467 */ 468 if (nd->mygateway.sin_len != 0) { 469 struct sockaddr_in mask, sin; 470 471 bzero((caddr_t)&mask, sizeof(mask)); 472 sin = mask; 473 sin.sin_family = AF_INET; 474 sin.sin_len = sizeof(sin); 475 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin, 476 (struct sockaddr *)&nd->mygateway, 477 (struct sockaddr *)&mask, 478 RTF_UP | RTF_GATEWAY, (struct rtentry **)0); 479 if (error) 480 panic("nfs_mountroot: RTM_ADD: %d", error); 481 } 482 483 /* 484 * Create the rootfs mount point. 485 */ 486 nd->root_args.fh = nd->root_fh; 487 nd->root_args.fhsize = nd->root_fhsize; 488 l = ntohl(nd->root_saddr.sin_addr.s_addr); 489 sprintf(buf,"%ld.%ld.%ld.%ld:%s", 490 (l >> 24) & 0xff, (l >> 16) & 0xff, 491 (l >> 8) & 0xff, (l >> 0) & 0xff,nd->root_hostnam); 492 printf("NFS ROOT: %s\n",buf); 493 if (error = nfs_mountdiskless(buf, "/", MNT_RDONLY, 494 &nd->root_saddr, &nd->root_args, p, &vp, &mp)) { 495 if (swap_mp) { 496 mp->mnt_vfc->vfc_refcount--; 497 free(swap_mp, M_MOUNT); 498 } 499 return (error); 500 } 501 502 swap_mp = NULL; 503 if (nd->swap_nblks) { 504 505 /* Convert to DEV_BSIZE instead of Kilobyte */ 506 nd->swap_nblks *= 2; 507 508 /* 509 * Create a fake mount point just for the swap vnode so that the 510 * swap file can be on a different server from the rootfs. 511 */ 512 nd->swap_args.fh = nd->swap_fh; 513 nd->swap_args.fhsize = nd->swap_fhsize; 514 l = ntohl(nd->swap_saddr.sin_addr.s_addr); 515 sprintf(buf,"%ld.%ld.%ld.%ld:%s", 516 (l >> 24) & 0xff, (l >> 16) & 0xff, 517 (l >> 8) & 0xff, (l >> 0) & 0xff,nd->swap_hostnam); 518 printf("NFS SWAP: %s\n",buf); 519 if (error = nfs_mountdiskless(buf, "/swap", 0, 520 &nd->swap_saddr, &nd->swap_args, p, &vp, &swap_mp)) 521 return (error); 522 vfs_unbusy(swap_mp, p); 523 524 VTONFS(vp)->n_size = VTONFS(vp)->n_vattr.va_size = 525 nd->swap_nblks * DEV_BSIZE ; 526 527 /* 528 * Since the swap file is not the root dir of a file system, 529 * hack it to a regular file. 530 */ 531 vp->v_type = VREG; 532 vp->v_flag = 0; 533 VREF(vp); 534 swaponvp(p, vp, NODEV, nd->swap_nblks); 535 } 536 537 mp->mnt_flag |= MNT_ROOTFS; 538 mp->mnt_vnodecovered = NULLVP; 539 rootvp = vp; 540 vfs_unbusy(mp, p); 541 542 /* 543 * This is not really an nfs issue, but it is much easier to 544 * set hostname here and then let the "/etc/rc.xxx" files 545 * mount the right /var based upon its preset value. 546 */ 547 bcopy(nd->my_hostnam, hostname, MAXHOSTNAMELEN); 548 hostname[MAXHOSTNAMELEN - 1] = '\0'; 549 for (i = 0; i < MAXHOSTNAMELEN; i++) 550 if (hostname[i] == '\0') 551 break; 552 inittodr(ntohl(nd->root_time)); 553 return (0); 554} 555 556/* 557 * Internal version of mount system call for diskless setup. 558 */ 559static int 560nfs_mountdiskless(path, which, mountflag, sin, args, p, vpp, mpp) 561 char *path; 562 char *which; 563 int mountflag; 564 struct sockaddr_in *sin; 565 struct nfs_args *args; 566 struct proc *p; 567 struct vnode **vpp; 568 struct mount **mpp; 569{ 570 struct mount *mp; 571 struct sockaddr *nam; 572 int error; 573 574 mp = *mpp; 575 576 if (!mp && (error = vfs_rootmountalloc("nfs", path, &mp))) { 577 printf("nfs_mountroot: NFS not configured"); 578 return (error); 579 } 580 581 mp->mnt_kern_flag = 0; 582 mp->mnt_flag = mountflag; 583 nam = dup_sockaddr((struct sockaddr *)sin, 1); 584 if (error = mountnfs(args, mp, nam, which, path, vpp)) { 585 printf("nfs_mountroot: mount %s on %s: %d", path, which, error); 586 mp->mnt_vfc->vfc_refcount--; 587 vfs_unbusy(mp, p); 588 free(mp, M_MOUNT); 589 FREE(nam, M_SONAME); 590 return (error); 591 } 592 (void) copystr(which, mp->mnt_stat.f_mntonname, MNAMELEN - 1, 0); 593 *mpp = mp; 594 return (0); 595} 596 597static void 598nfs_decode_args(nmp, argp) 599 struct nfsmount *nmp; 600 struct nfs_args *argp; 601{ 602 int s; 603 int adjsock; 604 int maxio; 605 606 s = splnet(); 607 /* 608 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes 609 * no sense in that context. 610 */ 611 if (argp->sotype == SOCK_STREAM) 612 nmp->nm_flag &= ~NFSMNT_NOCONN; 613 614 /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */ 615 if ((argp->flags & NFSMNT_NFSV3) == 0) 616 nmp->nm_flag &= ~NFSMNT_RDIRPLUS; 617 618 /* Re-bind if rsrvd port requested and wasn't on one */ 619 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT) 620 && (argp->flags & NFSMNT_RESVPORT); 621 /* Also re-bind if we're switching to/from a connected UDP socket */ 622 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != 623 (argp->flags & NFSMNT_NOCONN)); 624 625 /* Update flags atomically. Don't change the lock bits. */ 626 nmp->nm_flag = argp->flags | nmp->nm_flag; 627 splx(s); 628 629 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) { 630 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10; 631 if (nmp->nm_timeo < NFS_MINTIMEO) 632 nmp->nm_timeo = NFS_MINTIMEO; 633 else if (nmp->nm_timeo > NFS_MAXTIMEO) 634 nmp->nm_timeo = NFS_MAXTIMEO; 635 } 636 637 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) { 638 nmp->nm_retry = argp->retrans; 639 if (nmp->nm_retry > NFS_MAXREXMIT) 640 nmp->nm_retry = NFS_MAXREXMIT; 641 } 642 643 if (argp->flags & NFSMNT_NFSV3) { 644 if (argp->sotype == SOCK_DGRAM) 645 maxio = NFS_MAXDGRAMDATA; 646 else 647 maxio = NFS_MAXDATA; 648 } else 649 maxio = NFS_V2MAXDATA; 650 651 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) { 652 nmp->nm_wsize = argp->wsize; 653 /* Round down to multiple of blocksize */ 654 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1); 655 if (nmp->nm_wsize <= 0) 656 nmp->nm_wsize = NFS_FABLKSIZE; 657 } 658 if (nmp->nm_wsize > maxio) 659 nmp->nm_wsize = maxio; 660 if (nmp->nm_wsize > MAXBSIZE) 661 nmp->nm_wsize = MAXBSIZE; 662 663 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) { 664 nmp->nm_rsize = argp->rsize; 665 /* Round down to multiple of blocksize */ 666 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1); 667 if (nmp->nm_rsize <= 0) 668 nmp->nm_rsize = NFS_FABLKSIZE; 669 } 670 if (nmp->nm_rsize > maxio) 671 nmp->nm_rsize = maxio; 672 if (nmp->nm_rsize > MAXBSIZE) 673 nmp->nm_rsize = MAXBSIZE; 674 675 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) { 676 nmp->nm_readdirsize = argp->readdirsize; 677 } 678 if (nmp->nm_readdirsize > maxio) 679 nmp->nm_readdirsize = maxio; 680 if (nmp->nm_readdirsize > nmp->nm_rsize) 681 nmp->nm_readdirsize = nmp->nm_rsize; 682 683 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0) 684 nmp->nm_acregmin = argp->acregmin; 685 else 686 nmp->nm_acregmin = NFS_MINATTRTIMO; 687 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0) 688 nmp->nm_acregmax = argp->acregmax; 689 else 690 nmp->nm_acregmax = NFS_MAXATTRTIMO; 691 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0) 692 nmp->nm_acdirmin = argp->acdirmin; 693 else 694 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO; 695 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0) 696 nmp->nm_acdirmax = argp->acdirmax; 697 else 698 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO; 699 if (nmp->nm_acdirmin > nmp->nm_acdirmax) 700 nmp->nm_acdirmin = nmp->nm_acdirmax; 701 if (nmp->nm_acregmin > nmp->nm_acregmax) 702 nmp->nm_acregmin = nmp->nm_acregmax; 703 704 if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 && 705 argp->maxgrouplist <= NFS_MAXGRPS) 706 nmp->nm_numgrps = argp->maxgrouplist; 707 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 && 708 argp->readahead <= NFS_MAXRAHEAD) 709 nmp->nm_readahead = argp->readahead; 710 if ((argp->flags & NFSMNT_LEASETERM) && argp->leaseterm >= 2 && 711 argp->leaseterm <= NQ_MAXLEASE) 712 nmp->nm_leaseterm = argp->leaseterm; 713 if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 1 && 714 argp->deadthresh <= NQ_NEVERDEAD) 715 nmp->nm_deadthresh = argp->deadthresh; 716 717 adjsock |= ((nmp->nm_sotype != argp->sotype) || 718 (nmp->nm_soproto != argp->proto)); 719 nmp->nm_sotype = argp->sotype; 720 nmp->nm_soproto = argp->proto; 721 722 if (nmp->nm_so && adjsock) { 723 nfs_safedisconnect(nmp); 724 if (nmp->nm_sotype == SOCK_DGRAM) 725 while (nfs_connect(nmp, (struct nfsreq *)0)) { 726 printf("nfs_args: retrying connect\n"); 727 (void) tsleep((caddr_t)&lbolt, 728 PSOCK, "nfscon", 0); 729 } 730 } 731} 732 733/* 734 * VFS Operations. 735 * 736 * mount system call 737 * It seems a bit dumb to copyinstr() the host and path here and then 738 * bcopy() them in mountnfs(), but I wanted to detect errors before 739 * doing the sockargs() call because sockargs() allocates an mbuf and 740 * an error after that means that I have to release the mbuf. 741 */ 742/* ARGSUSED */ 743static int 744nfs_mount(mp, path, data, ndp, p) 745 struct mount *mp; 746 char *path; 747 caddr_t data; 748 struct nameidata *ndp; 749 struct proc *p; 750{ 751 int error; 752 struct nfs_args args; 753 struct sockaddr *nam; 754 struct vnode *vp; 755 char pth[MNAMELEN], hst[MNAMELEN]; 756 size_t len; 757 u_char nfh[NFSX_V3FHMAX]; 758 759 if (path == NULL) { 760 nfs_mountroot(mp); 761 return (0); 762 } 763 error = copyin(data, (caddr_t)&args, sizeof (struct nfs_args)); 764 if (error) 765 return (error); 766 if (args.version != NFS_ARGSVERSION) { 767#ifdef COMPAT_PRELITE2 768 /* 769 * If the argument version is unknown, then assume the 770 * caller is a pre-lite2 4.4BSD client and convert its 771 * arguments. 772 */ 773 struct onfs_args oargs; 774 error = copyin(data, (caddr_t)&oargs, sizeof (struct onfs_args)); 775 if (error) 776 return (error); 777 nfs_convert_oargs(&args,&oargs); 778#else /* !COMPAT_PRELITE2 */ 779 return (EPROGMISMATCH); 780#endif /* COMPAT_PRELITE2 */ 781 } 782 if (mp->mnt_flag & MNT_UPDATE) { 783 register struct nfsmount *nmp = VFSTONFS(mp); 784 785 if (nmp == NULL) 786 return (EIO); 787 /* 788 * When doing an update, we can't change from or to 789 * v3 and/or nqnfs, or change cookie translation 790 */ 791 args.flags = (args.flags & 792 ~(NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/)) | 793 (nmp->nm_flag & 794 (NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/)); 795 nfs_decode_args(nmp, &args); 796 return (0); 797 } 798 error = copyin((caddr_t)args.fh, (caddr_t)nfh, args.fhsize); 799 if (error) 800 return (error); 801 error = copyinstr(path, pth, MNAMELEN-1, &len); 802 if (error) 803 return (error); 804 bzero(&pth[len], MNAMELEN - len); 805 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len); 806 if (error) 807 return (error); 808 bzero(&hst[len], MNAMELEN - len); 809 /* sockargs() call must be after above copyin() calls */ 810 error = getsockaddr(&nam, (caddr_t)args.addr, args.addrlen); 811 if (error) 812 return (error); 813 args.fh = nfh; 814 error = mountnfs(&args, mp, nam, pth, hst, &vp); 815 return (error); 816} 817 818/* 819 * Common code for mount and mountroot 820 */ 821static int 822mountnfs(argp, mp, nam, pth, hst, vpp) 823 register struct nfs_args *argp; 824 register struct mount *mp; 825 struct sockaddr *nam; 826 char *pth, *hst; 827 struct vnode **vpp; 828{ 829 register struct nfsmount *nmp; 830 struct nfsnode *np; 831 int error; 832 struct vattr attrs; 833 834 if (mp->mnt_flag & MNT_UPDATE) { 835 nmp = VFSTONFS(mp); 836 /* update paths, file handles, etc, here XXX */ 837 FREE(nam, M_SONAME); 838 return (0); 839 } else { 840 nmp = zalloc(nfsmount_zone); 841 bzero((caddr_t)nmp, sizeof (struct nfsmount)); 842 TAILQ_INIT(&nmp->nm_uidlruhead); 843 TAILQ_INIT(&nmp->nm_bufq); 844 mp->mnt_data = (qaddr_t)nmp; 845 } 846 vfs_getnewfsid(mp); 847 nmp->nm_mountp = mp; 848 if (argp->flags & NFSMNT_NQNFS) 849 /* 850 * We have to set mnt_maxsymlink to a non-zero value so 851 * that COMPAT_43 routines will know that we are setting 852 * the d_type field in directories (and can zero it for 853 * unsuspecting binaries). 854 */ 855 mp->mnt_maxsymlinklen = 1; 856 857 /* 858 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too 859 * high, depending on whether we end up with negative offsets in 860 * the client or server somewhere. 2GB-1 may be safer. 861 * 862 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum 863 * that we can handle until we find out otherwise. 864 * XXX Our "safe" limit on the client is what we can store in our 865 * buffer cache using signed(!) block numbers. 866 */ 867 if ((argp->flags & NFSMNT_NFSV3) == 0) 868 nmp->nm_maxfilesize = 0xffffffffLL; 869 else 870 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1; 871 872 nmp->nm_timeo = NFS_TIMEO; 873 nmp->nm_retry = NFS_RETRANS; 874 nmp->nm_wsize = NFS_WSIZE; 875 nmp->nm_rsize = NFS_RSIZE; 876 nmp->nm_readdirsize = NFS_READDIRSIZE; 877 nmp->nm_numgrps = NFS_MAXGRPS; 878 nmp->nm_readahead = NFS_DEFRAHEAD; 879 nmp->nm_leaseterm = NQ_DEFLEASE; 880 nmp->nm_deadthresh = NQ_DEADTHRESH; 881 CIRCLEQ_INIT(&nmp->nm_timerhead); 882 nmp->nm_inprog = NULLVP; 883 nmp->nm_fhsize = argp->fhsize; 884 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize); 885 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN); 886 bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN); 887 nmp->nm_nam = nam; 888 /* Set up the sockets and per-host congestion */ 889 nmp->nm_sotype = argp->sotype; 890 nmp->nm_soproto = argp->proto; 891 892 nfs_decode_args(nmp, argp); 893 894 /* 895 * For Connection based sockets (TCP,...) defer the connect until 896 * the first request, in case the server is not responding. 897 */ 898 if (nmp->nm_sotype == SOCK_DGRAM && 899 (error = nfs_connect(nmp, (struct nfsreq *)0))) 900 goto bad; 901 902 /* 903 * This is silly, but it has to be set so that vinifod() works. 904 * We do not want to do an nfs_statfs() here since we can get 905 * stuck on a dead server and we are holding a lock on the mount 906 * point. 907 */ 908 mp->mnt_stat.f_iosize = nfs_iosize(nmp); 909 /* 910 * A reference count is needed on the nfsnode representing the 911 * remote root. If this object is not persistent, then backward 912 * traversals of the mount point (i.e. "..") will not work if 913 * the nfsnode gets flushed out of the cache. Ufs does not have 914 * this problem, because one can identify root inodes by their 915 * number == ROOTINO (2). 916 */ 917 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np); 918 if (error) 919 goto bad; 920 *vpp = NFSTOV(np); 921 922 /* 923 * Get file attributes for the mountpoint. This has the side 924 * effect of filling in (*vpp)->v_type with the correct value. 925 */ 926 VOP_GETATTR(*vpp, &attrs, curproc->p_ucred, curproc); 927 928 /* 929 * Lose the lock but keep the ref. 930 */ 931 VOP_UNLOCK(*vpp, 0, curproc); 932 933 return (0); 934bad: 935 nfs_disconnect(nmp); 936 zfree(nfsmount_zone, nmp); 937 FREE(nam, M_SONAME); 938 return (error); 939} 940 941/* 942 * unmount system call 943 */ 944static int 945nfs_unmount(mp, mntflags, p) 946 struct mount *mp; 947 int mntflags; 948 struct proc *p; 949{ 950 register struct nfsmount *nmp; 951 struct nfsnode *np; 952 struct vnode *vp; 953 int error, flags = 0; 954 955 if (mntflags & MNT_FORCE) 956 flags |= FORCECLOSE; 957 nmp = VFSTONFS(mp); 958 /* 959 * Goes something like this.. 960 * - Check for activity on the root vnode (other than ourselves). 961 * - Call vflush() to clear out vnodes for this file system, 962 * except for the root vnode. 963 * - Decrement reference on the vnode representing remote root. 964 * - Close the socket 965 * - Free up the data structures 966 */ 967 /* 968 * We need to decrement the ref. count on the nfsnode representing 969 * the remote root. See comment in mountnfs(). The VFS unmount() 970 * has done vput on this vnode, otherwise we would get deadlock! 971 */ 972 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np); 973 if (error) 974 return(error); 975 vp = NFSTOV(np); 976 if (vp->v_usecount > 2) { 977 vput(vp); 978 return (EBUSY); 979 } 980 981 /* 982 * Must handshake with nqnfs_clientd() if it is active. 983 */ 984 nmp->nm_state |= NFSSTA_DISMINPROG; 985 while (nmp->nm_inprog != NULLVP) 986 (void) tsleep((caddr_t)&lbolt, PSOCK, "nfsdism", 0); 987 error = vflush(mp, vp, flags); 988 if (error) { 989 vput(vp); 990 nmp->nm_state &= ~NFSSTA_DISMINPROG; 991 return (error); 992 } 993 994 /* 995 * We are now committed to the unmount. 996 * For NQNFS, let the server daemon free the nfsmount structure. 997 */ 998 if (nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_KERB)) 999 nmp->nm_state |= NFSSTA_DISMNT; 1000 1001 /* 1002 * There are two reference counts and one lock to get rid of here. 1003 */ 1004 vput(vp); 1005 vrele(vp); 1006 vgone(vp); 1007 nfs_disconnect(nmp); 1008 FREE(nmp->nm_nam, M_SONAME); 1009 1010 if ((nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_KERB)) == 0) 1011 zfree(nfsmount_zone, nmp); 1012 return (0); 1013} 1014 1015/* 1016 * Return root of a filesystem 1017 */ 1018static int 1019nfs_root(mp, vpp) 1020 struct mount *mp; 1021 struct vnode **vpp; 1022{ 1023 register struct vnode *vp; 1024 struct nfsmount *nmp; 1025 struct nfsnode *np; 1026 int error; 1027 1028 nmp = VFSTONFS(mp); 1029 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np); 1030 if (error) 1031 return (error); 1032 vp = NFSTOV(np); 1033 if (vp->v_type == VNON) 1034 vp->v_type = VDIR; 1035 vp->v_flag = VROOT; 1036 *vpp = vp; 1037 return (0); 1038} 1039 1040extern int syncprt; 1041 1042/* 1043 * Flush out the buffer cache 1044 */ 1045/* ARGSUSED */ 1046static int 1047nfs_sync(mp, waitfor, cred, p) 1048 struct mount *mp; 1049 int waitfor; 1050 struct ucred *cred; 1051 struct proc *p; 1052{ 1053 register struct vnode *vp; 1054 int error, allerror = 0; 1055 1056 /* 1057 * Force stale buffer cache information to be flushed. 1058 */ 1059loop: 1060 for (vp = mp->mnt_vnodelist.lh_first; 1061 vp != NULL; 1062 vp = vp->v_mntvnodes.le_next) { 1063 /* 1064 * If the vnode that we are about to sync is no longer 1065 * associated with this mount point, start over. 1066 */ 1067 if (vp->v_mount != mp) 1068 goto loop;
|