⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs_ops.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
}/*-------------------------------------------------------------------------*//* * 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 + -