コード例 #1
0
ファイル: msdosfs_vfsops.c プロジェクト: hmatyschok/MeshBSD
static int
msdosfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
	struct msdosfs_args args;
	struct export_args exp;
	int error;

	if (data == NULL)
		return (EINVAL);
	error = copyin(data, &args, sizeof args);
	if (error)
		return (error);
	vfs_oexport_conv(&args.export, &exp);

	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
	ma = mount_arg(ma, "export", &exp, sizeof(exp));
	ma = mount_argf(ma, "uid", "%d", args.uid);
	ma = mount_argf(ma, "gid", "%d", args.gid);
	ma = mount_argf(ma, "mask", "%d", args.mask);
	ma = mount_argf(ma, "dirmask", "%d", args.dirmask);

	ma = mount_argb(ma, args.flags & MSDOSFSMNT_SHORTNAME, "noshortname");
	ma = mount_argb(ma, args.flags & MSDOSFSMNT_LONGNAME, "nolongname");
	ma = mount_argb(ma, !(args.flags & MSDOSFSMNT_NOWIN95), "nowin95");
	ma = mount_argb(ma, args.flags & MSDOSFSMNT_KICONV, "nokiconv");

	ma = mount_argsu(ma, "cs_win", args.cs_win, MAXCSLEN);
	ma = mount_argsu(ma, "cs_dos", args.cs_dos, MAXCSLEN);
	ma = mount_argsu(ma, "cs_local", args.cs_local, MAXCSLEN);

	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #2
0
static int
cd9660_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
{
	struct iso_args args;
	int error;

	error = copyin(data, &args, sizeof args);
	if (error)
		return (error);

	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
	ma = mount_arg(ma, "export", &args.export, sizeof args.export);
	ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64);
	ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
	ma = mount_argf(ma, "ssector", "%u", args.ssector);
	ma = mount_argb(ma, !(args.flags & ISOFSMNT_NORRIP), "norrip");
	ma = mount_argb(ma, args.flags & ISOFSMNT_GENS, "nogens");
	ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "noextatt");
	ma = mount_argb(ma, !(args.flags & ISOFSMNT_NOJOLIET), "nojoliet");
	ma = mount_argb(ma,
	    args.flags & ISOFSMNT_BROKENJOLIET, "nobrokenjoliet");
	ma = mount_argb(ma, args.flags & ISOFSMNT_KICONV, "nokiconv");

	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #3
0
ファイル: ntfs_vfsops.c プロジェクト: vkhromov/freebsd
static int
ntfs_cmount ( 
	struct mntarg *ma,
	void *data,
	uint64_t flags)
{
	struct ntfs_args args;
	struct export_args exp;
	int error;

	error = copyin(data, &args, sizeof(args));
	if (error)
		return (error);
	vfs_oexport_conv(&args.export, &exp);
	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
	ma = mount_arg(ma, "export", &exp, sizeof(exp));
	ma = mount_argf(ma, "uid", "%d", args.uid);
	ma = mount_argf(ma, "gid", "%d", args.gid);
	ma = mount_argf(ma, "mode", "%d", args.mode);
	ma = mount_argb(ma, args.flag & NTFS_MFLAG_CASEINS, "nocaseins");
	ma = mount_argb(ma, args.flag & NTFS_MFLAG_ALLNAMES, "noallnames");
	if (args.flag & NTFS_MFLAG_KICONV) {
		ma = mount_argsu(ma, "cs_ntfs", args.cs_ntfs, 64);
		ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
	}

	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #4
0
ファイル: smbfs_vfsops.c プロジェクト: derekmarcotte/freebsd
static int
smbfs_cmount(struct mntarg *ma, void * data, uint64_t flags)
{
	struct smbfs_args args;
	int error;

	error = copyin(data, &args, sizeof(struct smbfs_args));
	if (error)
		return error;

	if (args.version != SMBFS_VERSION) {
		printf("mount version mismatch: kernel=%d, mount=%d\n",
		    SMBFS_VERSION, args.version);
		return EINVAL;
	}
	ma = mount_argf(ma, "dev", "%d", args.dev);
	ma = mount_argb(ma, args.flags & SMBFS_MOUNT_SOFT, "nosoft");
	ma = mount_argb(ma, args.flags & SMBFS_MOUNT_INTR, "nointr");
	ma = mount_argb(ma, args.flags & SMBFS_MOUNT_STRONG, "nostrong");
	ma = mount_argb(ma, args.flags & SMBFS_MOUNT_HAVE_NLS, "nohave_nls");
	ma = mount_argb(ma, !(args.flags & SMBFS_MOUNT_NO_LONG), "nolong");
	ma = mount_arg(ma, "rootpath", args.root_path, -1);
	ma = mount_argf(ma, "uid", "%d", args.uid);
	ma = mount_argf(ma, "gid", "%d", args.gid);
	ma = mount_argf(ma, "file_mode", "%d", args.file_mode);
	ma = mount_argf(ma, "dir_mode", "%d", args.dir_mode);
	ma = mount_argf(ma, "caseopt", "%d", args.caseopt);

	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #5
0
ファイル: pseudofs.c プロジェクト: edgar-pek/PerspicuOS
/*
 * Compatibility shim for old mount(2) system call
 */
int
pfs_cmount(struct mntarg *ma, void *data, int flags)
{
	int error;

	error = kernel_mount(ma, flags);
	return (error);
}
コード例 #6
0
static int
portal_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
	struct portal_args args;
	int error;

	if (data == NULL)
		return (EINVAL);
	error = copyin(data, &args, sizeof args);
	if (error)
		return (error);

	ma = mount_argf(ma, "socket", "%d", args.pa_socket);
	ma = mount_argsu(ma, "config", args.pa_config, MAXPATHLEN);
	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #7
0
static int
reiserfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
	struct reiserfs_args args;
	struct export_args exp;
	int error;

	error = copyin(data, &args, sizeof(args));
	if (error)
		return (error);
	vfs_oexport_conv(&args.export, &exp);

	ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
	ma = mount_arg(ma, "export", &exp, sizeof(exp));

	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #8
0
static int nwfs_cmount(struct mntarg *ma, void *data, int flags)
{
	struct nwfs_args args; 	  /* will hold data from mount request */
	int error;

	error = copyin(data, &args, sizeof(struct nwfs_args));
	if (error)
		return (error);

	/*
	 * XXX: cheap cop-out here, args contains a structure I don't
	 * XXX: know how we should handle, and I don't see any immediate
	 * XXX: prospect of avoiding a mount_nwfs(8) binary anyway.
	 */
	ma = mount_arg(ma, "nwfs_args", &args, sizeof args);

	error = kernel_mount(ma, flags);

	return (error);
}
コード例 #9
0
static int vboxvfs_cmount(struct mntarg *ma, void * data, int flags, struct thread *td)
{
    struct vboxvfs_mount_info args;
    int rc = 0;

    printf("%s: Enter\n", __FUNCTION__);

    rc = copyin(data, &args, sizeof(struct vboxvfs_mount_info));
    if (rc)
        return rc;

    ma = mount_argf(ma, "uid", "%d", args.uid);
    ma = mount_argf(ma, "gid", "%d", args.gid);
    ma = mount_arg(ma, "from", args.name, -1);

    rc = kernel_mount(ma, flags);

    printf("%s: Leave rc=%d\n", __FUNCTION__, rc);

    return rc;
}
コード例 #10
0
ファイル: osi_vfsops.c プロジェクト: maxendpoint/openafs_cvs
static int
afs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
{
    return kernel_mount(ma, flags);
}
コード例 #11
0
ファイル: vfs_mountroot.c プロジェクト: ChristosKa/freebsd
static int
parse_mount(char **conf)
{
	char *errmsg;
	struct mntarg *ma;
	char *dev, *fs, *opts, *tok;
	int delay, error, timeout;

	error = parse_token(conf, &tok);
	if (error)
		return (error);
	fs = tok;
	error = parse_skipto(&tok, ':');
	if (error) {
		free(fs, M_TEMP);
		return (error);
	}
	parse_poke(&tok, '\0');
	parse_advance(&tok);
	dev = tok;

	if (root_mount_mddev != -1) {
		/* Handle substitution for the md unit number. */
		tok = strstr(dev, "md#");
		if (tok != NULL)
			tok[2] = '0' + root_mount_mddev;
	}

	/* Parse options. */
	error = parse_token(conf, &tok);
	opts = (error == 0) ? tok : NULL;

	printf("Trying to mount root from %s:%s [%s]...\n", fs, dev,
	    (opts != NULL) ? opts : "");

	errmsg = malloc(ERRMSGL, M_TEMP, M_WAITOK | M_ZERO);

	if (vfs_byname(fs) == NULL) {
		strlcpy(errmsg, "unknown file system", ERRMSGL);
		error = ENOENT;
		goto out;
	}

	if (strcmp(fs, "zfs") != 0 && strstr(fs, "nfs") == NULL && 
	    dev[0] != '\0' && !parse_mount_dev_present(dev)) {
		printf("mountroot: waiting for device %s ...\n", dev);
		delay = hz / 10;
		timeout = root_mount_timeout * hz;
		do {
			pause("rmdev", delay);
			timeout -= delay;
		} while (timeout > 0 && !parse_mount_dev_present(dev));
		if (timeout <= 0) {
			error = ENODEV;
			goto out;
		}
	}

	ma = NULL;
	ma = mount_arg(ma, "fstype", fs, -1);
	ma = mount_arg(ma, "fspath", "/", -1);
	ma = mount_arg(ma, "from", dev, -1);
	ma = mount_arg(ma, "errmsg", errmsg, ERRMSGL);
	ma = mount_arg(ma, "ro", NULL, 0);
	ma = parse_mountroot_options(ma, opts);
	error = kernel_mount(ma, MNT_ROOTFS);

 out:
	if (error) {
		printf("Mounting from %s:%s failed with error %d",
		    fs, dev, error);
		if (errmsg[0] != '\0')
			printf(": %s", errmsg);
		printf(".\n");
	}
	free(fs, M_TEMP);
	free(errmsg, M_TEMP);
	if (opts != NULL)
		free(opts, M_TEMP);
	/* kernel_mount can return -1 on error. */
	return ((error < 0) ? EDOOFUS : error);
}
コード例 #12
0
ファイル: nfs_vfsops.c プロジェクト: vkhromov/freebsd
/* ARGSUSED */
static int
nfs_mount(struct mount *mp)
{
	struct nfs_args args = {
	    .version = NFS_ARGSVERSION,
	    .addr = NULL,
	    .addrlen = sizeof (struct sockaddr_in),
	    .sotype = SOCK_STREAM,
	    .proto = 0,
	    .fh = NULL,
	    .fhsize = 0,
	    .flags = NFSMNT_RESVPORT,
	    .wsize = NFS_WSIZE,
	    .rsize = NFS_RSIZE,
	    .readdirsize = NFS_READDIRSIZE,
	    .timeo = 10,
	    .retrans = NFS_RETRANS,
	    .maxgrouplist = NFS_MAXGRPS,
	    .readahead = NFS_DEFRAHEAD,
	    .wcommitsize = 0,			/* was: NQ_DEFLEASE */
	    .deadthresh = NFS_MAXDEADTHRESH,	/* was: NQ_DEADTHRESH */
	    .hostname = NULL,
	    /* args version 4 */
	    .acregmin = NFS_MINATTRTIMO,
	    .acregmax = NFS_MAXATTRTIMO,
	    .acdirmin = NFS_MINDIRATTRTIMO,
	    .acdirmax = NFS_MAXDIRATTRTIMO,
	};
	int error, ret, has_nfs_args_opt;
	int has_addr_opt, has_fh_opt, has_hostname_opt;
	struct sockaddr *nam;
	struct vnode *vp;
	char hst[MNAMELEN];
	size_t len;
	u_char nfh[NFSX_V3FHMAX];
	char *opt;
	int nametimeo = NFS_DEFAULT_NAMETIMEO;
	int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;

	has_nfs_args_opt = 0;
	has_addr_opt = 0;
	has_fh_opt = 0;
	has_hostname_opt = 0;

	if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
		error = EINVAL;
		goto out;
	}

	if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
		error = nfs_mountroot(mp);
		goto out;
	}

	/*
	 * The old mount_nfs program passed the struct nfs_args
	 * from userspace to kernel.  The new mount_nfs program
	 * passes string options via nmount() from userspace to kernel
	 * and we populate the struct nfs_args in the kernel.
	 */
	if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
		error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
		    sizeof args);
		if (error)
			goto out;

		if (args.version != NFS_ARGSVERSION) {
			error = EPROGMISMATCH;
			goto out;
		}
		has_nfs_args_opt = 1;
	}

	if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
		args.flags |= NFSMNT_DUMBTIMR;
	if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
		args.flags |= NFSMNT_NOCONN;
	if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
		args.flags |= NFSMNT_NOCONN;
	if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
		args.flags |= NFSMNT_NOLOCKD;
	if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
		args.flags &= ~NFSMNT_NOLOCKD;
	if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
		args.flags |= NFSMNT_INT;
	if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
		args.flags |= NFSMNT_RDIRPLUS;
	if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
		args.flags |= NFSMNT_RESVPORT;
	if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
		args.flags &= ~NFSMNT_RESVPORT;
	if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
		args.flags |= NFSMNT_SOFT;
	if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
		args.flags &= ~NFSMNT_SOFT;
	if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
		args.sotype = SOCK_DGRAM;
	if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
		args.sotype = SOCK_DGRAM;
	if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
		args.sotype = SOCK_STREAM;
	if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
		args.flags |= NFSMNT_NFSV3;
	if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
		args.flags |= NFSMNT_NOCTO;
	if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
		if (opt == NULL) { 
			vfs_mount_error(mp, "illegal readdirsize");
			error = EINVAL;
			goto out;
		}
		ret = sscanf(opt, "%d", &args.readdirsize);
		if (ret != 1 || args.readdirsize <= 0) {
			vfs_mount_error(mp, "illegal readdirsize: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_READDIRSIZE;
	}
	if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
		if (opt == NULL) { 
			vfs_mount_error(mp, "illegal readahead");
			error = EINVAL;
			goto out;
		}
		ret = sscanf(opt, "%d", &args.readahead);
		if (ret != 1 || args.readahead <= 0) {
			vfs_mount_error(mp, "illegal readahead: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_READAHEAD;
	}
	if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
		if (opt == NULL) { 
			vfs_mount_error(mp, "illegal wsize");
			error = EINVAL;
			goto out;
		}
		ret = sscanf(opt, "%d", &args.wsize);
		if (ret != 1 || args.wsize <= 0) {
			vfs_mount_error(mp, "illegal wsize: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_WSIZE;
	}
	if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
		if (opt == NULL) { 
			vfs_mount_error(mp, "illegal rsize");
			error = EINVAL;
			goto out;
		}
		ret = sscanf(opt, "%d", &args.rsize);
		if (ret != 1 || args.rsize <= 0) {
			vfs_mount_error(mp, "illegal wsize: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_RSIZE;
	}
	if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
		if (opt == NULL) { 
			vfs_mount_error(mp, "illegal retrans");
			error = EINVAL;
			goto out;
		}
		ret = sscanf(opt, "%d", &args.retrans);
		if (ret != 1 || args.retrans <= 0) {
			vfs_mount_error(mp, "illegal retrans: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_RETRANS;
	}
	if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.acregmin);
		if (ret != 1 || args.acregmin < 0) {
			vfs_mount_error(mp, "illegal acregmin: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_ACREGMIN;
	}
	if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.acregmax);
		if (ret != 1 || args.acregmax < 0) {
			vfs_mount_error(mp, "illegal acregmax: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_ACREGMAX;
	}
	if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.acdirmin);
		if (ret != 1 || args.acdirmin < 0) {
			vfs_mount_error(mp, "illegal acdirmin: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_ACDIRMIN;
	}
	if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.acdirmax);
		if (ret != 1 || args.acdirmax < 0) {
			vfs_mount_error(mp, "illegal acdirmax: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_ACDIRMAX;
	}
	if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.wcommitsize);
		if (ret != 1 || args.wcommitsize < 0) {
			vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_WCOMMITSIZE;
	}
	if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.deadthresh);
		if (ret != 1 || args.deadthresh <= 0) {
			vfs_mount_error(mp, "illegal deadthresh: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_DEADTHRESH;
	}
	if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.timeo);
		if (ret != 1 || args.timeo <= 0) {
			vfs_mount_error(mp, "illegal timeout: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_TIMEO;
	}
	if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &args.maxgrouplist);
		if (ret != 1 || args.maxgrouplist <= 0) {
			vfs_mount_error(mp, "illegal maxgroups: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
		args.flags |= NFSMNT_MAXGRPS;
	}
	if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
		ret = sscanf(opt, "%d", &nametimeo);
		if (ret != 1 || nametimeo < 0) {
			vfs_mount_error(mp, "illegal nametimeo: %s", opt);
			error = EINVAL;
			goto out;
		}
	}
	if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
	    == 0) {
		ret = sscanf(opt, "%d", &negnametimeo);
		if (ret != 1 || negnametimeo < 0) {
			vfs_mount_error(mp, "illegal negnametimeo: %s",
			    opt);
			error = EINVAL;
			goto out;
		}
	}
	if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
		&args.addrlen) == 0) {
		has_addr_opt = 1;
		if (args.addrlen > SOCK_MAXADDRLEN) {
			error = ENAMETOOLONG;
			goto out;
		}
		nam = malloc(args.addrlen, M_SONAME,
		    M_WAITOK);
		bcopy(args.addr, nam, args.addrlen);
		nam->sa_len = args.addrlen;
	}
	if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
		&args.fhsize) == 0) {
		has_fh_opt = 1;
	}
	if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
		NULL) == 0) {
		has_hostname_opt = 1;
	}
	if (args.hostname == NULL) {
		vfs_mount_error(mp, "Invalid hostname");
		error = EINVAL;
		goto out;
	}
	if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
		vfs_mount_error(mp, "Bad file handle");
		error = EINVAL;
		goto out;
	}

	if (mp->mnt_flag & MNT_UPDATE) {
		struct nfsmount *nmp = VFSTONFS(mp);

		if (nmp == NULL) {
			error = EIO;
			goto out;
		}

		/*
		 * If a change from TCP->UDP is done and there are thread(s)
		 * that have I/O RPC(s) in progress with a tranfer size
		 * greater than NFS_MAXDGRAMDATA, those thread(s) will be
		 * hung, retrying the RPC(s) forever. Usually these threads
		 * will be seen doing an uninterruptible sleep on wait channel
		 * "newnfsreq" (truncated to "newnfsre" by procstat).
		 */
		if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
			tprintf(curthread->td_proc, LOG_WARNING,
	"Warning: mount -u that changes TCP->UDP can result in hung threads\n");

		/*
		 * When doing an update, we can't change from or to
		 * v3, switch lockd strategies or change cookie translation
		 */
		args.flags = (args.flags &
		    ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
		    (nmp->nm_flag &
			(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
		nfs_decode_args(mp, nmp, &args, NULL);
		goto out;
	}

	/*
	 * Make the nfs_ip_paranoia sysctl serve as the default connection
	 * or no-connection mode for those protocols that support 
	 * no-connection mode (the flag will be cleared later for protocols
	 * that do not support no-connection mode).  This will allow a client
	 * to receive replies from a different IP then the request was
	 * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
	 * not 0.
	 */
	if (nfs_ip_paranoia == 0)
		args.flags |= NFSMNT_NOCONN;

	if (has_nfs_args_opt) {
		/*
		 * In the 'nfs_args' case, the pointers in the args
		 * structure are in userland - we copy them in here.
		 */
		if (!has_fh_opt) {
			error = copyin((caddr_t)args.fh, (caddr_t)nfh,
			    args.fhsize);
			if (error) {
				goto out;
			}
			args.fh = nfh;
		}
		if (!has_hostname_opt) {
			error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
			if (error) {
				goto out;
			}
			bzero(&hst[len], MNAMELEN - len);
			args.hostname = hst;
		}
		if (!has_addr_opt) {
			/* sockargs() call must be after above copyin() calls */
			error = getsockaddr(&nam, (caddr_t)args.addr,
			    args.addrlen);
			if (error) {
				goto out;
			}
		}
	} else if (has_addr_opt == 0) {
		vfs_mount_error(mp, "No server address");
		error = EINVAL;
		goto out;
	}
	error = mountnfs(&args, mp, nam, args.hostname, &vp,
	    curthread->td_ucred, nametimeo, negnametimeo);
out:
	if (!error) {
		MNT_ILOCK(mp);
		mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
		MNT_IUNLOCK(mp);
	}
	return (error);
}


/*
 * VFS Operations.
 *
 * mount system call
 * It seems a bit dumb to copyinstr() the host and path here and then
 * bcopy() them in mountnfs(), but I wanted to detect errors before
 * doing the sockargs() call because sockargs() allocates an mbuf and
 * an error after that means that I have to release the mbuf.
 */
/* ARGSUSED */
static int
nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
	int error;
	struct nfs_args args;

	error = copyin(data, &args, sizeof (struct nfs_args));
	if (error)
		return error;

	ma = mount_arg(ma, "nfs_args", &args, sizeof args);

	error = kernel_mount(ma, flags);
	return (error);
}
コード例 #13
0
/*
 * Compatibility shim for old mount(2) system call.
 */
int
fdesc_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
	return kernel_mount(ma, flags);
}