Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libukfs Add what is essentially disklabel support. All ...
details: https://anonhg.NetBSD.org/src/rev/c9af44aa6489
branches: trunk
changeset: 747980:c9af44aa6489
user: pooka <pooka%NetBSD.org@localhost>
date: Wed Oct 07 20:51:00 2009 +0000
description:
Add what is essentially disklabel support. All disk-based file
systems should be mounted with ukfs_mount_disk() from now on. The
partition argument specifies which label is being mounted (or the
entire image). E.g. partition 4 should be label 'e'.
diffstat:
lib/libukfs/Makefile | 5 +-
lib/libukfs/ukfs.c | 206 +++++++++++++++++++++++++++++---------
lib/libukfs/ukfs.h | 24 +++-
lib/libukfs/ukfs_disklabel.c | 124 +++++++++++++++++++++++
lib/libukfs/ukfs_int_disklabel.h | 157 +++++++++++++++++++++++++++++
5 files changed, 462 insertions(+), 54 deletions(-)
diffs (truncated from 617 to 300 lines):
diff -r f302194a3df5 -r c9af44aa6489 lib/libukfs/Makefile
--- a/lib/libukfs/Makefile Wed Oct 07 20:42:09 2009 +0000
+++ b/lib/libukfs/Makefile Wed Oct 07 20:51:00 2009 +0000
@@ -1,14 +1,15 @@
-# $NetBSD: Makefile,v 1.2 2008/11/27 16:14:46 pooka Exp $
+# $NetBSD: Makefile,v 1.3 2009/10/07 20:51:00 pooka Exp $
#
LIB= ukfs
LIBDPLIBS+= rump ${.CURDIR}/../librump \
rumpvfs ${.CURDIR}/../librumpvfs
+CPPFLAGS+= -I${.CURDIR}
INCS= ukfs.h
INCSDIR= /usr/include/rump
-SRCS= ukfs.c
+SRCS= ukfs.c ukfs_disklabel.c
MAN= ukfs.3
.include <bsd.lib.mk>
diff -r f302194a3df5 -r c9af44aa6489 lib/libukfs/ukfs.c
--- a/lib/libukfs/ukfs.c Wed Oct 07 20:42:09 2009 +0000
+++ b/lib/libukfs/ukfs.c Wed Oct 07 20:51:00 2009 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: ukfs.c,v 1.37 2009/10/02 09:32:01 pooka Exp $ */
+/* $NetBSD: ukfs.c,v 1.38 2009/10/07 20:51:00 pooka Exp $ */
/*
- * Copyright (c) 2007, 2008 Antti Kantee. All Rights Reserved.
+ * Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by the
* Finnish Cultural Foundation.
@@ -63,6 +63,8 @@
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
+#include "ukfs_int_disklabel.h"
+
#define UKFS_MODE_DEFAULT 0555
struct ukfs {
@@ -187,63 +189,149 @@
return rump_sys_mkdir(path, mode);
}
-struct ukfs *
-ukfs_mount(const char *vfsname, const char *devpath, const char *mountpath,
- int mntflags, void *arg, size_t alen)
+int
+ukfs_partition_probe(char *devpath, int *partition)
{
- struct stat sb;
- struct ukfs *fs = NULL;
- int rv = 0, devfd = -1, rdonly;
- int mounted = 0;
- int regged = 0;
- int doreg = 0;
+ char *p;
+ int rv = 0;
/*
- * Try open and lock the device. if we can't open it, assume
- * it's a file system which doesn't use a real device and let
- * it slide. The mount will fail anyway if the fs requires a
- * device.
- *
- * XXX: strictly speaking this is not 100% correct, as virtual
- * file systems can use a device path which does exist and can
- * be opened. E.g. tmpfs should be mountable multiple times
- * with "device" path "/swap", but now isn't. But I think the
- * chances are so low that it's currently acceptable to let
- * this one slip.
+ * Check for disklabel magic in pathname:
+ * /regularpath%PART:<char>%\0
*/
- rdonly = mntflags & MNT_RDONLY;
+#define MAGICADJ(p, n) (p+sizeof(UKFS_PARTITION_SCANMAGIC)-1+n)
+ if ((p = strstr(devpath, UKFS_PARTITION_SCANMAGIC)) != NULL
+ && strlen(p) == UKFS_PARTITION_MAGICLEN
+ && *(MAGICADJ(p,1)) == '%') {
+ if (*(MAGICADJ(p,0)) >= 'a' &&
+ *(MAGICADJ(p,0)) < 'a' + UKFS_MAXPARTITIONS) {
+ *partition = *(MAGICADJ(p,0)) - 'a';
+ *p = '\0';
+ } else {
+ rv = EINVAL;
+ }
+ } else {
+ *partition = UKFS_PARTITION_NONE;
+ }
+
+ return rv;
+}
+
+/*
+ * Open the disk file and flock it. Also, if we are operation on
+ * an embedded partition, find the partition offset and size from
+ * the disklabel.
+ *
+ * We hard-fail only in two cases:
+ * 1) we failed to get the partition info out (don't know what offset
+ * to mount from)
+ * 2) we failed to flock the source device (i.e. flock() fails,
+ * not e.g. open() before it)
+ *
+ * Otherwise we let the code proceed to mount and let the file system
+ * throw the proper error. The only questionable bit is that if we
+ * soft-fail before flock() and mount does succeed...
+ *
+ * Returns: -1 error (errno reports error code)
+ * 0 success
+ *
+ * dfdp: -1 device is not open
+ * n device is open
+ */
+static int
+process_diskdevice(const char *devpath, int partition, int rdonly,
+ int *dfdp, uint64_t *devoff, uint64_t *devsize)
+{
+ char buf[65536];
+ struct stat sb;
+ struct ukfs_disklabel dl;
+ struct ukfs_partition *pp;
+ int rv = 0, devfd;
+
+ /* defaults */
+ *devoff = 0;
+ *devsize = RUMP_ETFS_SIZE_ENDOFF;
+ *dfdp = -1;
+
devfd = open(devpath, rdonly ? O_RDONLY : O_RDWR);
- if (devfd != -1) {
- if (fstat(devfd, &sb) == -1) {
- close(devfd);
- devfd = -1;
+ if (devfd == -1) {
+ if (UKFS_USEPARTITION(partition))
+ rv = errno;
+ goto out;
+ }
+
+ /*
+ * Locate the disklabel and find the partition in question.
+ */
+ if (UKFS_USEPARTITION(partition)) {
+ if (pread(devfd, buf, sizeof(buf), 0) == -1) {
rv = errno;
goto out;
}
- /*
- * We do this only for non-block device since the
- * (NetBSD) kernel allows block device open only once.
- */
- if (!S_ISBLK(sb.st_mode)) {
- if (flock(devfd, LOCK_NB | (rdonly ? LOCK_SH:LOCK_EX))
- == -1) {
- warnx("ukfs_mount: cannot get %s lock on "
- "device", rdonly ? "shared" : "exclusive");
- close(devfd);
- devfd = -1;
- rv = errno;
- goto out;
- }
- } else {
+ if (ukfs_disklabel_scan(&dl, buf, sizeof(buf)) != 0) {
+ rv = ENOENT;
+ goto out;
+ }
+
+ if (dl.d_npartitions < partition) {
+ rv = ENOENT;
+ goto out;
+ }
+
+ pp = &dl.d_partitions[partition];
+ *devoff = pp->p_offset << DEV_BSHIFT;
+ *devsize = pp->p_size << DEV_BSHIFT;
+ }
+
+ if (fstat(devfd, &sb) == -1) {
+ rv = errno;
+ goto out;
+ }
+
+ /*
+ * We do this only for non-block device since the
+ * (NetBSD) kernel allows block device open only once.
+ * We also need to close the device for fairly obvious reasons.
+ */
+ if (!S_ISBLK(sb.st_mode)) {
+ if (flock(devfd, LOCK_NB | (rdonly ? LOCK_SH:LOCK_EX)) == -1) {
+ warnx("ukfs_mount: cannot get %s lock on "
+ "device", rdonly ? "shared" : "exclusive");
+ rv = errno;
+ goto out;
+ }
+ } else {
+ close(devfd);
+ devfd = -1;
+ }
+ *dfdp = devfd;
+
+ out:
+ if (rv) {
+ if (devfd != -1)
close(devfd);
- devfd = -1;
- }
- doreg = 1;
- } else if (errno != ENOENT) {
- doreg = 1;
+ errno = rv;
+ rv = -1;
}
+ return rv;
+}
+
+static struct ukfs *
+doukfsmount(const char *vfsname, const char *devpath, int partition,
+ const char *mountpath, int mntflags, void *arg, size_t alen)
+{
+ struct ukfs *fs = NULL;
+ int rv = 0, devfd;
+ uint64_t devoff, devsize;
+ int mounted = 0;
+ int regged = 0;
+
+ if (partition != UKFS_PARTITION_NA)
+ process_diskdevice(devpath, partition, mntflags & MNT_RDONLY,
+ &devfd, &devoff, &devsize);
+
fs = malloc(sizeof(struct ukfs));
if (fs == NULL) {
rv = ENOMEM;
@@ -259,13 +347,15 @@
}
}
- if (doreg) {
- rv = rump_etfs_register(devpath, devpath, RUMP_ETFS_BLK);
+ if (partition != UKFS_PARTITION_NA) {
+ rv = rump_etfs_register_withsize(devpath, devpath,
+ RUMP_ETFS_BLK, devoff, devsize);
if (rv) {
goto out;
}
regged = 1;
}
+
rv = rump_sys_mount(vfsname, mountpath, mntflags, arg, alen);
if (rv) {
rv = errno;
@@ -312,6 +402,24 @@
return fs;
}
+struct ukfs *
+ukfs_mount(const char *vfsname, const char *devpath,
+ const char *mountpath, int mntflags, void *arg, size_t alen)
+{
+
+ return doukfsmount(vfsname, devpath, UKFS_PARTITION_NA,
+ mountpath, mntflags, arg, alen);
+}
+
+struct ukfs *
+ukfs_mount_disk(const char *vfsname, const char *devpath, int partition,
+ const char *mountpath, int mntflags, void *arg, size_t alen)
+{
+
+ return doukfsmount(vfsname, devpath, partition,
+ mountpath, mntflags, arg, alen);
+}
+
int
ukfs_release(struct ukfs *fs, int flags)
{
diff -r f302194a3df5 -r c9af44aa6489 lib/libukfs/ukfs.h
--- a/lib/libukfs/ukfs.h Wed Oct 07 20:42:09 2009 +0000
+++ b/lib/libukfs/ukfs.h Wed Oct 07 20:51:00 2009 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: ukfs.h,v 1.10 2009/10/02 09:32:01 pooka Exp $ */
+/* $NetBSD: ukfs.h,v 1.11 2009/10/07 20:51:00 pooka Exp $ */
/*
- * Copyright (c) 2007, 2008 Antti Kantee. All Rights Reserved.
+ * Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by the
* Finnish Cultural Foundation.
@@ -55,7 +55,9 @@
int _ukfs_init(int);
struct ukfs *ukfs_mount(const char *, const char *, const char *,
- int, void *, size_t);
+ int, void *, size_t);
Home |
Main Index |
Thread Index |
Old Index