Redo mount(2)/umount(2) ABI

- pass in file system type through mount(2), and return this type in
  statvfs structures as generated by [f]statvfs(2);
- align mount flags field with NetBSD's, splitting out service flags
  which are not to be passed to VFS;
- remove limitation of mount ABI to 16-byte labels, so that labels
  can be made larger in the future;
- introduce new m11 message union type for mount(2) as side effect.

Change-Id: I88b7710e297e00a5e4582ada5243d3d5c2801fd9
This commit is contained in:
David van Moolenbroek 2013-08-20 01:37:18 +02:00 committed by Lionel Sambuc
parent 61ed526374
commit 7113bcb896
15 changed files with 137 additions and 118 deletions

View file

@ -24,11 +24,12 @@ int main(argc, argv)
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;
@ -36,12 +37,12 @@ char *argv[];
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];
@ -75,7 +76,7 @@ char *argv[];
}
}
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);
@ -141,7 +142,7 @@ mount_all()
if (has_opt(fs->fs_mntops, "ro"))
ro = 1;
if (ro) {
mountflags |= MS_RDONLY;
mountflags |= MNT_RDONLY;
}
device = fs->fs_spec;
@ -152,7 +153,7 @@ mount_all()
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",

View file

@ -47,7 +47,7 @@ char *argv[];
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)

View file

@ -911,6 +911,23 @@
#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 *
*===========================================================================*/

View file

@ -29,6 +29,8 @@ typedef struct {long m9l1, m9l2, m9l3, m9l4, m9l5;
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;
@ -68,6 +70,7 @@ typedef struct {
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;
@ -154,6 +157,16 @@ typedef struct {
#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). *
*==========================================================================*/

View file

@ -5,16 +5,16 @@
#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 */

View file

@ -920,7 +920,6 @@
#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

View file

@ -16,7 +16,6 @@
#ifdef __weak_alias
__weak_alias(mount, _mount)
__weak_alias(umount, _umount)
__weak_alias(umount2, _umount2)
#endif
#define FSDEFAULT "mfs"
@ -33,9 +32,9 @@ static int rs_down(char *label)
}
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;
@ -54,16 +53,12 @@ int mountflags;
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
@ -104,9 +99,6 @@ int mountflags;
}
}
/* Tell VFS that we are passing in a 16-byte label. */
mountflags |= MS_LABEL16;
/* Sanity check on user input. */
if(strchr(args, '\'')) {
errno = EINVAL;
@ -156,12 +148,15 @@ int mountflags;
}
/* 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) {
@ -174,30 +169,25 @@ int mountflags;
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);
}
}

View file

@ -6,9 +6,8 @@ mount, umount \- mount or umount a file system
.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
@ -34,9 +33,12 @@ mounted without a block device.
.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
@ -60,12 +62,7 @@ may refer to either of them. If more than one device is mounted on the
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

View file

@ -42,6 +42,7 @@
* 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

View file

@ -609,6 +609,7 @@ static void *do_init_root(void *arg)
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);
@ -626,7 +627,8 @@ static void *do_init_root(void *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;

View file

@ -99,28 +99,30 @@ int do_mount(message *UNUSED(m_out))
{
/* 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;
vir_bytes label, type, vname1, vname2;
size_t vname1_length, vname2_length, label_len, type_len;
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;
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);
/* FS process' endpoint number */
if (mflags & MS_LABEL16) {
/* Get the label from the caller, and ask DS for the endpoint. */
/* 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);
@ -129,18 +131,10 @@ int do_mount(message *UNUSED(m_out))
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;
}
/* 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) {
@ -159,8 +153,13 @@ int do_mount(message *UNUSED(m_out))
/* 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);
}
@ -172,7 +171,8 @@ dev_t dev,
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;
@ -212,6 +212,7 @@ char mount_label[LABEL_MAX] )
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
@ -274,12 +275,12 @@ char mount_label[LABEL_MAX] )
/* 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 ||
@ -424,30 +425,28 @@ void mount_pfs(void)
/*===========================================================================*
* 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 ((dev = name_to_dev(TRUE /*allow_mountpt*/, fullpath)) == NO_DEV)
return(err_code);
@ -456,10 +455,10 @@ int do_umount(message *m_out)
/* 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);
}

View file

@ -30,13 +30,9 @@
#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

View file

@ -156,7 +156,8 @@ int do_umount(message *m_out);
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);

View file

@ -231,8 +231,10 @@ static int fill_statvfs(struct vnode *vp, endpoint_t endpt, vir_bytes buf_addr)
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));

View file

@ -15,7 +15,8 @@ EXTERN struct vmnt {
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];