int argc;
char *argv[];
{
- int all = 0, i, v = 0, mountflags;
+ int all = 0, i, v = 0, mountflags, srvflags;
char **ap, *opt, *err, *type, *args, *device;
if (argc == 1) list(); /* just list /etc/mtab */
mountflags = 0;
+ srvflags = 0;
type = NULL;
args = NULL;
ap = argv+1;
if (argv[i][0] == '-') {
opt = argv[i]+1;
while (*opt != 0) switch (*opt++) {
- case 'r': mountflags |= MS_RDONLY; break;
+ case 'r': mountflags |= MNT_RDONLY; break;
case 't': if (++i == argc) usage();
type = argv[i];
break;
- case 'i': mountflags |= MS_REUSE; break;
- case 'e': mountflags |= MS_EXISTING; break;
+ case 'i': srvflags |= MS_REUSE; break;
+ case 'e': srvflags |= MS_EXISTING; break;
case 'n': write_mtab = 0; break;
case 'o': if (++i == argc) usage();
args = argv[i];
}
}
- if (mount(device, argv[2], mountflags, type, args) < 0) {
+ if (mount(device, argv[2], mountflags, srvflags, type, args) < 0) {
err = strerror(errno);
fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
argv[1], argv[2], err);
if (has_opt(fs->fs_mntops, "ro"))
ro = 1;
if (ro) {
- mountflags |= MS_RDONLY;
+ mountflags |= MNT_RDONLY;
}
device = fs->fs_spec;
if (!strcmp(device, "none"))
device = NULL;
- if (mount(device, mountpoint, mountflags, fs->fs_vfstype,
+ if (mount(device, mountpoint, mountflags, 0, fs->fs_vfstype,
fs->fs_mntops) != 0) {
err = strerror(errno);
fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
found = find_mtab_entry(name);
- if (umount2(name, umount_flags) < 0) {
+ if (umount(name, umount_flags) < 0) {
if (errno == EINVAL)
std_err("umount: Device not mounted\n");
else if (errno == ENOTBLK)
#define STATVFS_NAME m1_p1
#define STATVFS_BUF m1_p2
+/* Field names for the mount(2) call. */
+#define VFS_MOUNT_FLAGS m11_i1
+#define VFS_MOUNT_DEVLEN m11_s1
+#define VFS_MOUNT_PATHLEN m11_s2
+#define VFS_MOUNT_TYPELEN m11_s3
+#define VFS_MOUNT_LABELLEN m11_s4
+#define VFS_MOUNT_DEV m11_p1
+#define VFS_MOUNT_PATH m11_p2
+#define VFS_MOUNT_TYPE m11_p3
+#define VFS_MOUNT_LABEL m11_p4
+
+/* Field names for the umount(2) call. */
+#define VFS_UMOUNT_NAME m1_p1
+#define VFS_UMOUNT_NAMELEN m1_i1
+#define VFS_UMOUNT_LABEL m1_p2
+#define VFS_UMOUNT_LABELLEN m1_i2
+
/*===========================================================================*
* Messages for VM server *
*===========================================================================*/
short m9s1, m9s2, m9s3, m9s4; } mess_9;
typedef struct {int m10i1, m10i2, m10i3, m10i4;
long m10l1, m10l2, m10l3; } mess_10;
+typedef struct {int m11i1; short m11s1, m11s2, m11s3, m11s4;
+ char *m11p1, *m11p2, *m11p3, *m11p4; } mess_11;
typedef struct {
void *block;
mess_6 m_m6;
mess_9 m_m9;
mess_10 m_m10;
+ mess_11 m_m11;
mess_vmmcp m_vmmcp;
mess_vmmcp_reply m_vmmcp_reply;
mess_vm_vfs_mmap m_vm_vfs;
#define m10_l2 m_u.m_m10.m10l2
#define m10_l3 m_u.m_m10.m10l3
+#define m11_i1 m_u.m_m11.m11i1
+#define m11_s1 m_u.m_m11.m11s1
+#define m11_s2 m_u.m_m11.m11s2
+#define m11_s3 m_u.m_m11.m11s3
+#define m11_s4 m_u.m_m11.m11s4
+#define m11_p1 m_u.m_m11.m11p1
+#define m11_p2 m_u.m_m11.m11p2
+#define m11_p3 m_u.m_m11.m11p3
+#define m11_p4 m_u.m_m11.m11p4
+
/*==========================================================================*
* Minix run-time system (IPC). *
*==========================================================================*/
#ifndef _MOUNT_H
#define _MOUNT_H
-#define MS_RDONLY 0x001 /* Mount device read only */
-#define MS_REUSE 0x002 /* Tell RS to try reusing binary from memory */
-#define MS_LABEL16 0x004 /* Mount message points to 16-byte label */
-#define MS_EXISTING 0x008 /* Tell mount to use already running server */
+/* Service flags. These are not passed to VFS. */
+#define MS_REUSE 0x001 /* Tell RS to try reusing binary from memory */
+#define MS_EXISTING 0x002 /* Tell mount to use already running server */
+
+/* Legacy definitions. */
#define MNTNAMELEN 16 /* Length of fs type name including nul */
#define MNTFLAGLEN 64 /* Length of flags string including nul */
-int mount(char *_spec, char *_name, int _mountflags, char *type, char
- *args);
-int umount(const char *_name);
-int umount2(const char *_name, int flags);
+int mount(char *_spec, char *_name, int _mountflags, int srvflags, char *type,
+ char *args);
+int umount(const char *_name, int srvflags);
#endif /* _MOUNT_H */
#define stime _stime
#define umask _umask
#define umount _umount
-#define umount2 _umount2
#define unlink _unlink
#define vm_remap _vm_remap
#define vm_unmap _vm_unmap
#ifdef __weak_alias
__weak_alias(mount, _mount)
__weak_alias(umount, _umount)
-__weak_alias(umount2, _umount2)
#endif
#define FSDEFAULT "mfs"
}
char *find_rslabel(char *args_line);
-int mount(special, name, mountflags, type, args)
+int mount(special, name, mountflags, srvflags, type, args)
char *name, *special, *type, *args;
-int mountflags;
+int mountflags, srvflags;
{
int r;
message m;
reuse = 0;
memset(path, '\0', sizeof(path));
- /* Check mount flags */
- if(mountflags & MS_REUSE) {
+ /* Check service flags. */
+ if(srvflags & MS_REUSE)
reuse = 1;
- mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */
- }
- if(mountflags & MS_EXISTING) {
+ if(srvflags & MS_EXISTING)
use_existing = 1;
- mountflags &= ~MS_EXISTING; /* Temporary: turn off to not confuse VFS */
- }
/* Make a label for the file system process. This label must be unique and
* may currently not exceed 16 characters including terminating null. For
}
}
- /* Tell VFS that we are passing in a 16-byte label. */
- mountflags |= MS_LABEL16;
-
/* Sanity check on user input. */
if(strchr(args, '\'')) {
errno = EINVAL;
}
/* Now perform mount(). */
- m.m1_i1 = special ? strlen(special) + 1 : 0;
- m.m1_i2 = strlen(name) + 1;
- m.m1_i3 = mountflags;
- m.m1_p1 = special;
- m.m1_p2 = name;
- m.m1_p3 = label;
+ m.VFS_MOUNT_FLAGS = mountflags;
+ m.VFS_MOUNT_DEVLEN = special ? strlen(special) + 1 : 0;
+ m.VFS_MOUNT_PATHLEN = strlen(name) + 1;
+ m.VFS_MOUNT_TYPELEN = strlen(type) + 1;
+ m.VFS_MOUNT_LABELLEN = strlen(label) + 1;
+ m.VFS_MOUNT_DEV = special;
+ m.VFS_MOUNT_PATH = name;
+ m.VFS_MOUNT_TYPE = type;
+ m.VFS_MOUNT_LABEL = label;
r = _syscall(VFS_PROC_NR, MOUNT, &m);
if (r != OK && !use_existing) {
return r;
}
-int umount(name)
+int umount(name, srvflags)
const char *name;
+int srvflags;
{
- return umount2(name, 0);
-}
-
-int umount2(name, flags)
-const char *name;
-int flags;
-{
+ char label[16];
message m;
int r;
-
- _loadname(name, &m);
+ m.VFS_UMOUNT_NAME = __UNCONST(name);
+ m.VFS_UMOUNT_NAMELEN = strlen(name) + 1;
+ m.VFS_UMOUNT_LABEL = label;
+ m.VFS_UMOUNT_LABELLEN = sizeof(label);
r = _syscall(VFS_PROC_NR, UMOUNT, &m);
/* don't shut down the driver when exist flag is set */
- if (!(flags & MS_EXISTING)) {
+ if (!(srvflags & MS_EXISTING)) {
if (r == OK) {
- /* VFS returns the label of the unmounted file system in the reply.
- * As of writing, the size of the m3_ca1 field is 16 bytes.
- */
- rs_down(m.m3_ca1);
+ /* VFS returns the label of the unmounted file system to us. */
+ rs_down(label);
}
}
.nf
#include <sys/mount.h>
-int mount(char *\fIspecial\fP, char *\fIname\fP, int \fImountflags\fP, char *\fItype\fP, char *\fIargs\fP)
-int umount(char *\fIname\fP)
-int umount2(char *\fIname\fP, int \fIflags)
+int mount(char *\fIspecial\fP, char *\fIname\fP, int \fImountflags\fP, int \fIsrvflags\fP, char *\fItype\fP, char *\fIargs\fP)
+int umount(char *\fIname\fP, int \fIsrvflags)
.fi
.ft P
.SH DESCRIPTION
.I Mountflags
may be a bitwise combination of the following flags:
.TP 2
-.B MS_RDONLY
+.B MNT_RDONLY
Mount file system read-only, rather than read-write.
-.TP
+.PP
+.I Srvflags
+may be a bitwise combination of the following flags:
+.TP 2
.B MS_REUSE
Reuse the file system server image if possible.
.TP
same mount point then unmounting at the mount point removes the last mounted
device, unmounting a device removes precisely that device. The unmount will
only succeed if none of the files on the device are in use.
-.PP
-.B Umount2()
-Same as Umount(), but takes an additional
-.I flags
-parameter.
-.I Flags
+.I Srvflags
may be a bitwise combination of the following flags:
.TP 2
.B MS_EXISTING
* not be smaller than 16 or bigger than
* M3_LONG_STRING.
*/
+#define FSTYPE_MAX VFS_NAMELEN /* maximum file system type size */
/* Args to dev_io */
#define VFS_DEV_READ 2001
struct fproc *rfp;
struct job my_job;
int r;
+ char *mount_type = "mfs"; /* FIXME: use boot image process name instead */
char *mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */
my_job = *((struct job *) arg);
}
receive_from = MFS_PROC_NR;
- r = mount_fs(DEV_IMGRD, "bootramdisk", "/", MFS_PROC_NR, 0, mount_label);
+ r = mount_fs(DEV_IMGRD, "bootramdisk", "/", MFS_PROC_NR, 0, mount_type,
+ mount_label);
if (r != OK)
panic("Failed to initialize root");
receive_from = ANY;
{
/* Perform the mount(name, mfile, mount_flags) system call. */
endpoint_t fs_e;
- int r, slot, rdonly, nodev;
+ int r, slot, nodev;
char mount_path[PATH_MAX], mount_dev[PATH_MAX];
- char mount_label[LABEL_MAX];
+ char mount_label[LABEL_MAX], mount_type[FSTYPE_MAX];
dev_t dev;
int mflags;
- vir_bytes label, vname1, vname2;
- size_t vname1_length, vname2_length;
-
- mflags = job_m_in.mount_flags;
- label = (vir_bytes) job_m_in.fs_label;
- vname1 = (vir_bytes) job_m_in.name1;
- vname1_length = (size_t) job_m_in.name1_length;
- vname2 = (vir_bytes) job_m_in.name2;
- vname2_length = (size_t) job_m_in.name2_length;
+ vir_bytes label, type, vname1, vname2;
+ size_t vname1_length, vname2_length, label_len, type_len;
+
+ mflags = job_m_in.VFS_MOUNT_FLAGS;
+ label = (vir_bytes) job_m_in.VFS_MOUNT_LABEL;
+ label_len = (size_t) job_m_in.VFS_MOUNT_LABELLEN;
+ vname1 = (vir_bytes) job_m_in.VFS_MOUNT_DEV;
+ vname1_length = (size_t) job_m_in.VFS_MOUNT_DEVLEN;
+ vname2 = (vir_bytes) job_m_in.VFS_MOUNT_PATH;
+ vname2_length = (size_t) job_m_in.VFS_MOUNT_PATHLEN;
+ type = (vir_bytes) job_m_in.VFS_MOUNT_TYPE;
+ type_len = (size_t) job_m_in.VFS_MOUNT_TYPELEN;
/* Only the super-user may do MOUNT. */
if (!super_user) return(EPERM);
+ /* Get the label from the caller, and ask DS for the endpoint of the FS. */
+ if (label_len > sizeof(mount_label))
+ return EINVAL;
+ r = sys_datacopy(who_e, label, SELF, (vir_bytes) mount_label,
+ sizeof(mount_label));
+ if (r != OK) return(r);
- /* FS process' endpoint number */
- if (mflags & MS_LABEL16) {
- /* Get the label from the caller, and ask DS for the endpoint. */
- r = sys_datacopy(who_e, label, SELF, (vir_bytes) mount_label,
- sizeof(mount_label));
- if (r != OK) return(r);
+ mount_label[sizeof(mount_label)-1] = 0;
- mount_label[sizeof(mount_label)-1] = 0;
-
- r = ds_retrieve_label_endpt(mount_label, &fs_e);
- if (r != OK) return(r);
- } else {
- /* Legacy support: get the endpoint from the request itself. */
- fs_e = (endpoint_t) label;
- mount_label[0] = 0;
- }
+ r = ds_retrieve_label_endpt(mount_label, &fs_e);
+ if (r != OK) return(r);
/* Sanity check on process number. */
if (isokendpt(fs_e, &slot) != OK) return(EINVAL);
- /* Should the file system be mounted read-only? */
- rdonly = (mflags & MS_RDONLY);
-
/* A null string for block special device means don't use a device at all. */
nodev = (vname1_length == 0);
if (!nodev) {
/* Fetch the name of the mountpoint */
if (fetch_name(vname2, vname2_length, mount_path) != OK) return(err_code);
+ /* Fetch the type of the file system. */
+ if (type_len > sizeof(mount_type)) return(ENAMETOOLONG);
+ if (fetch_name(type, type_len, mount_type) != OK) return(err_code);
+
/* Do the actual job */
- return mount_fs(dev, mount_dev, mount_path, fs_e, rdonly, mount_label);
+ return mount_fs(dev, mount_dev, mount_path, fs_e, mflags, mount_type,
+ mount_label);
}
char mount_dev[PATH_MAX],
char mount_path[PATH_MAX],
endpoint_t fs_e,
-int rdonly,
+int flags,
+char mount_type[FSTYPE_MAX],
char mount_label[LABEL_MAX] )
{
int i, r = OK, found, isroot, mount_root, slot;
strlcpy(new_vmp->m_mount_path, mount_path, PATH_MAX);
strlcpy(new_vmp->m_mount_dev, mount_dev, PATH_MAX);
+ strlcpy(new_vmp->m_fstype, mount_type, sizeof(new_vmp->m_fstype));
isroot = (strcmp(mount_path, "/") == 0);
mount_root = (isroot && have_root < 2); /* Root can be mounted twice:
* 1: ramdisk
/* Store some essential vmnt data first */
new_vmp->m_fs_e = fs_e;
new_vmp->m_dev = dev;
- if (rdonly) new_vmp->m_flags |= VMNT_READONLY;
+ if (flags & MNT_RDONLY) new_vmp->m_flags |= VMNT_READONLY;
else new_vmp->m_flags &= ~VMNT_READONLY;
/* Tell FS which device to mount */
new_vmp->m_flags |= VMNT_MOUNTING;
- r = req_readsuper(new_vmp, label, dev, rdonly, isroot, &res);
+ r = req_readsuper(new_vmp, label, dev, !!(flags & MNT_RDONLY), isroot, &res);
new_vmp->m_flags &= ~VMNT_MOUNTING;
if(req_peek(fs_e, 1, 0, PAGE_SIZE) != OK ||
/*===========================================================================*
* do_umount *
*===========================================================================*/
-int do_umount(message *m_out)
+int do_umount(message *UNUSED(m_out))
{
-/* Perform the umount(name) system call.
- * syscall might provide 'name' embedded in the message.
+/* Perform the umount(name) system call. Return the label of the FS service.
*/
char label[LABEL_MAX];
dev_t dev;
int r;
char fullpath[PATH_MAX];
- vir_bytes vname;
- size_t vname_length;
+ vir_bytes vname, label_addr;
+ size_t vname_length, label_len;
- vname = (vir_bytes) job_m_in.name;
- vname_length = (size_t) job_m_in.name_length;
+ vname = (vir_bytes) job_m_in.VFS_UMOUNT_NAME;
+ vname_length = (size_t) job_m_in.VFS_UMOUNT_NAMELEN;
+ label_addr = (vir_bytes) job_m_in.VFS_UMOUNT_LABEL;
+ label_len = (size_t) job_m_in.VFS_UMOUNT_LABELLEN;
/* Only the super-user may do umount. */
if (!super_user) return(EPERM);
/* If 'name' is not for a block special file or mountpoint, return error. */
- if (copy_name(vname_length, fullpath) != OK) {
- /* Direct copy failed, try fetching from user space */
- if (fetch_name(vname, vname_length, fullpath) != OK)
- return(err_code);
- }
+ if (fetch_name(vname, vname_length, fullpath) != OK)
+ return(err_code);
if ((dev = name_to_dev(TRUE /*allow_mountpt*/, fullpath)) == NO_DEV)
return(err_code);
/* Return the label of the mounted file system, so that the caller
* can shut down the corresponding server process.
*/
- if (strlen(label) >= M3_LONG_STRING) /* should never evaluate to true */
- label[M3_LONG_STRING-1] = 0;
- strlcpy(m_out->umount_label, label, M3_LONG_STRING);
- return(OK);
+ if (strlen(label) >= label_len)
+ label[label_len-1] = 0;
+ return sys_datacopy(SELF, (vir_bytes) label, who_e, label_addr,
+ strlen(label) + 1);
}
#define offset_lo m2_l1
#define offset_high m2_l2
#define ctl_req m4_l1
-#define mount_flags m1_i3
#define pipe_flags m1_i3
#define request m1_i2
#define sig m1_i2
-#define endpt1 m1_i1
-#define fs_label m1_p3
-#define umount_label m3_ca1
#define tp m2_l1
#define utime_actime m2_l1
#define utime_modtime m2_l2
int is_nonedev(dev_t dev);
void mount_pfs(void);
int mount_fs(dev_t dev, char mount_dev[PATH_MAX], char mount_path[PATH_MAX],
- endpoint_t fs_e, int rdonly, char mount_label[LABEL_MAX]);
+ endpoint_t fs_e, int rdonly, char mount_type[FSTYPE_MAX],
+ char mount_label[LABEL_MAX]);
int unmount(dev_t dev, char label[LABEL_MAX]);
void unmount_all(int force);
buf.f_flag |= ST_RDONLY;
buf.f_fsid = vmp->m_dev;
+ buf.f_fsidx.__fsid_val[0] = 0;
+ buf.f_fsidx.__fsid_val[1] = vmp->m_dev;
- strlcpy(buf.f_fstypename, "", sizeof(buf.f_fstypename)); /* FIXME */
+ strlcpy(buf.f_fstypename, vmp->m_fstype, sizeof(buf.f_fstypename));
strlcpy(buf.f_mntonname, vmp->m_mount_path, sizeof(buf.f_mntonname));
strlcpy(buf.f_mntfromname, vmp->m_mount_dev, sizeof(buf.f_mntfromname));
struct vnode *m_root_node; /* root vnode */
char m_label[LABEL_MAX]; /* label of the file system process */
char m_mount_path[PATH_MAX]; /* path on which vmnt is mounted */
- char m_mount_dev[PATH_MAX]; /* path on which vmnt is mounted */
+ char m_mount_dev[PATH_MAX]; /* device from which vmnt is mounted */
+ char m_fstype[FSTYPE_MAX]; /* file system type */
int m_haspeek; /* supports REQ_PEEK, REQ_BPEEK */
} vmnt[NR_MNTS];