📄 nfs_subr.c
字号:
else { print = 0; } } } if (print) { printf("NFS server: fs(%d,%d) not mounted,", major(fh->fh_fsid), minor(fh->fh_fsid)); printf(" %s, client address = %u.%u.%u.%u\n", rfsnames[which], xprt->xp_raddr.sin_addr.s_net, xprt->xp_raddr.sin_addr.s_host, xprt->xp_raddr.sin_addr.s_lh, xprt->xp_raddr.sin_addr.s_impno); } goto stale; } /* * verify that the filesystem is exported */ if (!(xpd->x_flags & M_EXPORTED)) { /* * See comment above for `not mounted ' messages. * A similar algorithm is used here. */ if (nfs_noexport_thresh) { ++NFS_N_NOEXPORT(mp); if (NFS_N_NOEXPORT(mp) == nfs_noexport_thresh) { NFS_LAST_NOEXPORT(mp) = (u_long)timepick->tv_sec; } else if (NFS_N_NOEXPORT(mp) > nfs_noexport_thresh) { if (nfs_noexport_timeout && (u_long)timepick->tv_sec > NFS_LAST_NOEXPORT(mp) + nfs_noexport_timeout) { NFS_N_NOEXPORT(mp) = 1; } else { print = 0; } } } if (print) { printf("NFS server: unexported fs(%d, %d) file %d,", major(fh->fh_fsid), minor(fh->fh_fsid), fh->fh_fno); printf(" %s, client address = %u.%u.%u.%u\n", rfsnames[which], xprt->xp_raddr.sin_addr.s_net, xprt->xp_raddr.sin_addr.s_host, xprt->xp_raddr.sin_addr.s_lh, xprt->xp_raddr.sin_addr.s_impno); } grele(rgp); goto stale; } gp = (struct gnode *) gget(mp, fh->fh_fno, NOMOUNT, NULL); if (gp == NULL) { printf("NFS server: couldn't get fs(%d, %d) file %d,", major(fh->fh_fsid), minor(fh->fh_fsid), fh->fh_fno); grele(rgp); goto stale; } /* * Release ref on file system */ grele(rgp); if (gp->g_gennum != fh->fh_fgen || gp->g_nlink <=0) { /* * See comment above for `not mounted ' messages. * A similar algorithm is used here. */ if (nfs_stale_thresh) { ++NFS_N_STALE(mp); if (NFS_N_STALE(mp) == nfs_stale_thresh) { NFS_LAST_STALE(mp) = (u_long)timepick->tv_sec; } else if (NFS_N_STALE(mp) > nfs_stale_thresh) { if (nfs_stale_timeout && (u_long) timepick->tv_sec > NFS_LAST_STALE(mp) + nfs_stale_timeout) { NFS_N_STALE(mp) = 1; } else { print = 0; } } } if (print) { printf("NFS server: stale file handle fs(%d,%d) file %d gen %d\n", major(fh->fh_fsid), minor(fh->fh_fsid), fh->fh_fno, fh->fh_fgen); printf(" local gen %d nlink %d,", gp->g_gennum, gp->g_nlink); printf(" %s, client address = %u.%u.%u.%u\n", rfsnames[which], xprt->xp_raddr.sin_addr.s_net, xprt->xp_raddr.sin_addr.s_host, xprt->xp_raddr.sin_addr.s_lh, xprt->xp_raddr.sin_addr.s_impno); } if (gp->g_count == 1) { gp->g_init = RECLAIM_GNODE; gfs_unlock(gp); grele(gp); } else gput(gp); goto stale; } /* * set root mapping */ if (u.u_uid == 0) { u.u_uid = u.u_ruid = xpd->x_rootmap; /* * HACK: * If mapping root to nobody (-2), then zap * all of the client's root group IDs. * This fills a security hole while we decide * what (if anything) to do about UID and GID * mappings. */ if (u.u_uid == -2) { u.u_rgid = u.u_gid = -2; u.u_cred->cr_groups[0] = -2; for (grp = &u.u_cred->cr_groups[1]; grp < &u.u_cred->cr_groups[NGROUPS]; grp++) { *grp = NOGROUP; } } } return ((struct vnode *)gp);stale: /* NULL return means fhandle not converted */ stalefh_count++; return (NULL);}struct export *exported;/* * Exportfs system call */exportfs(){ register struct a { short option; /* 1=create, 2=delete, 3=read */ u_int *cookie; struct exportfsdata *buf; } *uap; register struct gnode *gp=NULL; register int error; register struct nameidata *ndp = &u.u_nd; struct export *ep, **tail, *tmp, *tmp2; struct exportfsdata *e; int cookie, i; uap = (struct a *)u.u_ap; if (!suser()) return; KM_ALLOC(e, struct exportfsdata *, sizeof(struct exportfsdata), KM_NFS, KM_CLEAR); if (e == NULL) { u.u_error = EIO; return; } if (uap->option != EXPORTFS_READ) { if (uap->buf != NULL) { u.u_error = copyin((caddr_t)uap->buf, (caddr_t)e, sizeof (struct exportfsdata)); } else { KM_FREE(e, KM_NFS); u.u_error = EINVAL; return; } } switch (uap->option) { case EXPORTFS_CREATE: KM_ALLOC(ndp->ni_dirp, char *, MAXPATHLEN, KM_NFS, KM_NOARG); if (ndp->ni_dirp == NULL) { KM_FREE(e, KM_NFS); u.u_error = EIO; return; } bcopy(e->e_path, ndp->ni_dirp, MAXPATHLEN); ndp->ni_nameiop = LOOKUP | FOLLOW; gp = GNAMEI(ndp); KM_FREE(ndp->ni_dirp, KM_NFS); if (gp == NULL) { printf("exportfs: namei returned null gp - errno= %d\n", u.u_error); KM_FREE(e, KM_NFS); return; } if (u.u_error) { KM_FREE(e, KM_NFS); return; } KM_ALLOC(ep, struct export *, sizeof(struct export), KM_NFS, KM_CLEAR); if (ep == NULL) { gput(gp); KM_FREE(e, KM_NFS); u.u_error = EIO; return; } ep->e_pathlen = strlen(e->e_path)+1; KM_ALLOC(ep->e_path, char *, ep->e_pathlen, KM_NFS, KM_CLEAR); if (ep->e_path == NULL) { gput(gp); KM_FREE(e, KM_NFS); KM_FREE(ep, KM_NFS); u.u_error = EIO; return; } bcopy(e->e_path, ep->e_path, ep->e_pathlen); ep->e_fsid = gp->g_dev; ep->e_gnum = gp->g_number; ep->e_gen = gp->g_gennum; /* Set root uid mapping */ ep->e_rootmap = e->e_rootmap; ep->e_flags = e->e_flags; KM_FREE(e, KM_NFS); /* * Commit the new information to the export list, making * sure to delete the old entry for the fs, if one exists. */ smp_lock(&lk_gnode, LK_RETRY); tail = &exported; tmp=NULL; while (*tail != NULL) { if (((*tail)->e_fsid == gp->g_dev) && ((*tail)->e_gnum == gp->g_number) && ((*tail)->e_gen == gp->g_gennum)) { (*tail)->e_rootmap = ep->e_rootmap; (*tail)->e_flags = ep->e_flags; smp_unlock(&lk_gnode); KM_FREE(ep->e_path, KM_NFS); KM_FREE(ep, KM_NFS); gput(gp); return; } else { tmp=(*tail); tail = &(*tail)->e_next; } } ep->e_next = exported; exported = ep; smp_unlock(&lk_gnode); gput(gp); return; case EXPORTFS_REMOVE: smp_lock(&lk_gnode, LK_RETRY); tail = &exported; tmp=NULL; while (*tail != NULL) { if (strcmp((*tail)->e_path,e->e_path) == 0) { if (tmp != NULL) { tmp2 = *tail; tmp->e_next = (*tail)->e_next; smp_unlock(&lk_gnode); KM_FREE(e, KM_NFS); exportfree(tmp2); return (0); } else { tmp = *tail; exported = (*tail)->e_next; smp_unlock(&lk_gnode); KM_FREE(e, KM_NFS); exportfree(tmp); return (0); } } else { tmp=(*tail); tail = &(*tail)->e_next; } } smp_unlock(&lk_gnode); KM_FREE(e, KM_NFS); u.u_error = ENOENT; return; case EXPORTFS_READ: if (u.u_error = copyin(uap->cookie, &cookie, sizeof(cookie))) break; if (exported == NULL) { u.u_error = ENOENT; KM_FREE(e, KM_NFS); return; } if (cookie < 0) { u.u_error = EINVAL; KM_FREE(e, KM_NFS); return; } i=0; smp_lock(&lk_gnode, LK_RETRY); ep = exported; while (ep != NULL) { if (i++ == cookie) { e->e_flags = ep->e_flags; e->e_fsid = ep->e_fsid; e->e_gnum = ep->e_gnum; e->e_gen = ep->e_gen; e->e_rootmap = ep->e_rootmap; bcopy(ep->e_path, e->e_path, ep->e_pathlen); if (ep->e_next == NULL) e->e_more = 0; else e->e_more = 1; break; } else { ep = ep->e_next; } } smp_unlock(&lk_gnode); cookie=i; copyout(&cookie, uap->cookie, sizeof(cookie)); copyout((caddr_t)e, (caddr_t) uap->buf, sizeof(struct exportfsdata)); KM_FREE(e, KM_NFS); }}/* * Free an entire export list node */exportfree(exi) struct export *exi;{ KM_FREE(exi->e_path, KM_NFS); KM_FREE(exi, KM_NFS);}/* * General utilities *//* * Returns the prefered transfer size in bytes based on * what network interfaces are available. */nfstsize(){ return (8192);}nfs_hardpause(chan) caddr_t chan;{ wakeup((caddr_t)chan);}/* Routine to initialize NFS SMP locks */nfsinit(){ lockinit(&lk_nfschtable, &lock_nfschtable_d); lockinit(&lk_nfsbiod, &lock_nfs_biod_d); lockinit(&lk_nfsdnlc, &lock_nfsdnlc_d); lockinit(&lk_nfsstat, &lock_nfsstat_d); lockinit(&lk_nfsrrok, &lock_udpdata_d); lockinit(&lk_nfsargs, &lock_nfsargs_d);}#define NFS_SMALL 1#define NFS_MEDIUM 2#define NFS_LARGE 3#define NFS_XLARGE 4nfs_system_size(){ extern int maxusers; if (maxusers < 32) return (NFS_SMALL); if (maxusers < 128) return (NFS_MEDIUM); if (maxusers < 256) return (NFS_LARGE); return (NFS_XLARGE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -