📄 nfs_ops.c
字号:
}/*-------------------------------------------------------------------------*//* * NFS needs the local filesystem, remote filesystem * remote hostname. * Local filesystem defaults to remote and vice-versa. */static char *nfs_match(fo)am_opts *fo;{ char *xmtab; if (fo->opt_fs && !fo->opt_rfs) fo->opt_rfs = fo->opt_fs; if (!fo->opt_rfs) { plog(XLOG_USER, "nfs: no remote filesystem specified"); return FALSE; } if (!fo->opt_rhost) { plog(XLOG_USER, "nfs: no remote host specified"); return FALSE; } /* * Determine magic cookie to put in mtab */ xmtab = (char *) xmalloc(strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2); sprintf(xmtab, "%s:%s", fo->opt_rhost, fo->opt_rfs);#ifdef DEBUG dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"", fo->opt_rhost, fo->opt_rfs, fo->opt_fs);#endif /* DEBUG */ return xmtab;}/* * Initialise am structure for nfs */static int nfs_init(mf)mntfs *mf;{ if (!mf->mf_private) { int error; struct fhstatus fhs; char *colon = strchr(mf->mf_info, ':'); if (colon == 0) return ENOENT; error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, &fhs, (voidp) mf); if (!error) { mf->mf_private = (voidp) ALLOC(fhstatus); mf->mf_prfree = (void (*)()) free; bcopy((voidp) &fhs, mf->mf_private, sizeof(fhs)); } return error; } return 0;}int mount_nfs_fh P((struct fhstatus *fhp, char *dir, char *fs_name, char *opts, mntfs *mf));int mount_nfs_fh(fhp, dir, fs_name, opts, mf)struct fhstatus *fhp;char *dir;char *fs_name;char *opts;mntfs *mf;{ struct nfs_args nfs_args; struct mntent mnt; int retry; char *colon; /*char *path;*/ char host[MAXHOSTNAMELEN + MAXPATHLEN + 2]; fserver *fs = mf->mf_server; int flags; char *xopts; int error;#ifdef notdef unsigned short port;#endif /* notdef */ MTYPE_TYPE type = MOUNT_TYPE_NFS; bzero((voidp) &nfs_args, sizeof(nfs_args)); /* Paranoid */ /* * Extract host name to give to kernel */ if (!(colon = strchr(fs_name, ':'))) return ENOENT;#ifndef NFS_ARGS_NEEDS_PATH *colon = '\0';#endif strncpy(host, fs_name, sizeof(host));#ifndef NFS_ARGS_NEEDS_PATH *colon = ':';#endif /* NFS_ARGS_NEEDS_PATH */ /*path = colon + 1;*/ if (mf->mf_remopts && *mf->mf_remopts && !islocalnet(fs->fs_ip->sin_addr.s_addr)) xopts = strdup(mf->mf_remopts); else xopts = strdup(opts); bzero((voidp) &nfs_args, sizeof(nfs_args)); mnt.mnt_dir = dir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MTAB_TYPE_NFS; mnt.mnt_opts = xopts; mnt.mnt_freq = 0; mnt.mnt_passno = 0; retry = hasmntval(&mnt, "retry"); if (retry <= 0) retry = 1; /* XXX *//*again:*/ /* * set mount args */ NFS_FH_DREF(nfs_args.fh, (NFS_FH_TYPE) fhp->fhstatus_u.fhs_fhandle);#ifdef ULTRIX_HACK nfs_args.optstr = mnt.mnt_opts;#endif /* ULTRIX_HACK */ nfs_args.hostname = host; nfs_args.flags |= NFSMNT_HOSTNAME;#ifdef HOSTNAMESZ /* * Most kernels have a name length restriction. */ if (strlen(host) >= HOSTNAMESZ) strcpy(host + HOSTNAMESZ - 3, "..");#endif /* HOSTNAMESZ */ if (nfs_args.rsize = hasmntval(&mnt, "rsize")) nfs_args.flags |= NFSMNT_RSIZE; if (nfs_args.wsize = hasmntval(&mnt, "wsize")) nfs_args.flags |= NFSMNT_WSIZE; if (nfs_args.timeo = hasmntval(&mnt, "timeo")) nfs_args.flags |= NFSMNT_TIMEO; if (nfs_args.retrans = hasmntval(&mnt, "retrans")) nfs_args.flags |= NFSMNT_RETRANS;#ifdef NFSMNT_BIODS if (nfs_args.biods = hasmntval(&mnt, "biods")) nfs_args.flags |= NFSMNT_BIODS;#endif /* NFSMNT_BIODS */#ifdef NFSMNT_MAXGRPS if (nfs_args.maxgrouplist = hasmntval(&mnt, "maxgroups")) nfs_args.flags |= NFSMNT_MAXGRPS;#endif /* NFSMNT_MAXGRPS */#ifdef notdef/* * This isn't supported by the ping algorithm yet. * In any case, it is all done in nfs_init(). */ if (port = hasmntval(&mnt, "port")) sin.sin_port = htons(port); else sin.sin_port = htons(NFS_PORT); /* XXX should use portmapper */#endif /* notdef */ if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL) nfs_args.flags |= NFSMNT_SOFT;#ifdef NFSMNT_SPONGY if (hasmntopt(&mnt, "spongy") != NULL) { nfs_args.flags |= NFSMNT_SPONGY; if (nfs_args.flags & NFSMNT_SOFT) { plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored"); nfs_args.flags &= ~NFSMNT_SOFT; } }#endif /* MNTOPT_SPONGY */#ifdef MNTOPT_INTR if (hasmntopt(&mnt, MNTOPT_INTR) != NULL) nfs_args.flags |= NFSMNT_INT;#endif /* MNTOPT_INTR */#ifdef MNTOPT_NODEVS if (hasmntopt(&mnt, MNTOPT_NODEVS) != NULL) nfs_args.flags |= NFSMNT_NODEVS;#endif /* MNTOPT_NODEVS */#ifdef MNTOPT_COMPRESS if (hasmntopt(&mnt, "compress") != NULL) nfs_args.flags |= NFSMNT_COMPRESS;#endif /* MNTOPT_COMPRESS */#ifdef MNTOPT_NOCONN if (hasmntopt(&mnt, "noconn") != NULL) nfs_args.flags |= NFSMNT_NOCONN;#endif /* MNTOPT_NOCONN */#ifdef NFSMNT_PGTHRESH if (nfs_args.pg_thresh = hasmntval(&mnt, "pgthresh")) nfs_args.flags |= NFSMNT_PGTHRESH;#endif /* NFSMNT_PGTHRESH */ NFS_SA_DREF(nfs_args, fs->fs_ip); flags = compute_mount_flags(&mnt);#ifdef NFSMNT_NOCTO if (hasmntopt(&mnt, "nocto") != NULL) nfs_args.flags |= NFSMNT_NOCTO;#endif /* NFSMNT_NOCTO */#ifdef HAS_TCP_NFS if (hasmntopt(&mnt, "tcp") != NULL) nfs_args.sotype = SOCK_STREAM;#endif /* HAS_TCP_NFS */#ifdef ULTRIX_HACK /* * Ultrix passes the flags argument as part of the * mount data structure, rather than using the * flags argument to the system call. This is * confusing... */ if (!(nfs_args.flags & NFSMNT_PGTHRESH)) { nfs_args.pg_thresh = 64; /* 64k - XXX */ nfs_args.flags |= NFSMNT_PGTHRESH; } nfs_args.gfs_flags = flags; flags &= M_RDONLY; if (flags & M_RDONLY) nfs_args.flags |= NFSMNT_RONLY;#endif /* ULTRIX_HACK */ error = mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type); free(xopts); return error;}static int mount_nfs(dir, fs_name, opts, mf)char *dir;char *fs_name;char *opts;mntfs *mf;{#ifdef notdef int error; struct fhstatus fhs; char *colon; if (!(colon = strchr(fs_name, ':'))) return ENOENT;#ifdef DEBUG dlog("locating fhandle for %s", fs_name);#endif /* DEBUG */ error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, &fhs, (voidp) 0); if (error) return error; return mount_nfs_fh(&fhs, dir, fs_name, opts, mf);#endif if (!mf->mf_private) { plog(XLOG_ERROR, "Missing filehandle for %s", fs_name); return EINVAL; } return mount_nfs_fh((struct fhstatus *) mf->mf_private, dir, fs_name, opts, mf);}static int nfs_fmount(mf)mntfs *mf;{ int error; error = mount_nfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, mf);#ifdef DEBUG if (error) { errno = error; dlog("mount_nfs: %m"); }#endif /* DEBUG */ return error;}static int nfs_fumount(mf)mntfs *mf;{ int error = UMOUNT_FS(mf->mf_mount); if (error) return error; return 0;}static void nfs_umounted(mp)am_node *mp;{#ifdef INFORM_MOUNTD /* * Don't bother to inform remote mountd * that we are finished. Until a full * track of filehandles is maintained * the mountd unmount callback cannot * be done correctly anyway... */ mntfs *mf = mp->am_mnt; fserver *fs; char *colon, *path; if (mf->mf_error || mf->mf_refc > 1) return; fs = mf->mf_server; /* * Call the mount daemon on the server to * announce that we are not using the fs any more. * * This is *wrong*. The mountd should be called * when the fhandle is flushed from the cache, and * a reference held to the cached entry while the * fs is mounted... */ colon = path = strchr(mf->mf_info, ':'); if (fs && colon) { fh_cache f;#ifdef DEBUG dlog("calling mountd for %s", mf->mf_info);#endif /* DEBUG */ *path++ = '\0'; f.fh_path = path; f.fh_sin = *fs->fs_ip; f.fh_sin.sin_port = (u_short) 0; f.fh_fs = fs; f.fh_id = 0; f.fh_error = 0; (void) prime_nfs_fhandle_cache(colon+1, mf->mf_server, (struct fhstatus *) 0, (voidp) mf); (void) call_mountd(&f, MOUNTPROC_UMNT, (fwd_fun) 0, (voidp) 0); *colon = ':'; }#endif /* INFORM_MOUNTD */#ifdef KICK_KERNEL /* This should go into the mainline code, not in nfs_ops... */ /* * Run lstat over the underlying directory in * case this was a direct mount. This will * get the kernel back in sync with reality. */ if (mp->am_parent && mp->am_parent->am_path && STREQ(mp->am_parent->am_mnt->mf_ops->fs_type, "direct")) { struct stat stb; int pid; if ((pid = background()) == 0) { if (lstat(mp->am_parent->am_path, &stb) < 0) { plog(XLOG_ERROR, "lstat(%s) after unmount: %m", mp->am_parent->am_path);#ifdef DEBUG } else { dlog("hack lstat(%s): ok", mp->am_parent->am_path);#endif /* DEBUG */ } _exit(0); } }#endif /* KICK_KERNEL */}/* * Network file system */am_ops nfs_ops = { "nfs", nfs_match, nfs_init, auto_fmount, nfs_fmount, auto_fumount, nfs_fumount, efs_lookuppn, efs_readdir, 0, /* nfs_readlink */ 0, /* nfs_mounted */ nfs_umounted, find_nfs_srvr, FS_MKMNT|FS_BACKGROUND|FS_AMQINFO};#endif /* HAS_NFS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -