Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libukfs Use range locking (fnctl(F_SETLK)) instead of fi...
details: https://anonhg.NetBSD.org/src/rev/19df9a9fc677
branches: trunk
changeset: 749878:19df9a9fc677
user: pooka <pooka%NetBSD.org@localhost>
date: Fri Dec 11 21:20:52 2009 +0000
description:
Use range locking (fnctl(F_SETLK)) instead of file locking (flock()).
This allows to mount multiple (non-overlapping) partitions from the
same disk image.
diffstat:
lib/libukfs/Makefile | 7 +++--
lib/libukfs/ukfs.c | 54 ++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 48 insertions(+), 13 deletions(-)
diffs (156 lines):
diff -r fa4e58ec85ba -r 19df9a9fc677 lib/libukfs/Makefile
--- a/lib/libukfs/Makefile Fri Dec 11 20:00:49 2009 +0000
+++ b/lib/libukfs/Makefile Fri Dec 11 21:20:52 2009 +0000
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.3 2009/10/07 20:51:00 pooka Exp $
+# $NetBSD: Makefile,v 1.4 2009/12/11 21:20:52 pooka Exp $
#
LIB= ukfs
-LIBDPLIBS+= rump ${.CURDIR}/../librump \
- rumpvfs ${.CURDIR}/../librumpvfs
+#LIBDPLIBS+= rump ${.CURDIR}/../librump \
+# rumpvfs ${.CURDIR}/../librumpvfs
CPPFLAGS+= -I${.CURDIR}
INCS= ukfs.h
@@ -11,5 +11,6 @@
SRCS= ukfs.c ukfs_disklabel.c
MAN= ukfs.3
+DBG= -g
.include <bsd.lib.mk>
diff -r fa4e58ec85ba -r 19df9a9fc677 lib/libukfs/ukfs.c
--- a/lib/libukfs/ukfs.c Fri Dec 11 20:00:49 2009 +0000
+++ b/lib/libukfs/ukfs.c Fri Dec 11 21:20:52 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ukfs.c,v 1.44 2009/12/11 16:47:33 pooka Exp $ */
+/* $NetBSD: ukfs.c,v 1.45 2009/12/11 21:20:52 pooka Exp $ */
/*
* Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved.
@@ -79,6 +79,7 @@
int ukfs_devfd;
char *ukfs_devpath;
char *ukfs_mountpath;
+ struct ukfs_part *ukfs_part;
};
static int builddirs(const char *, mode_t,
@@ -180,6 +181,8 @@
struct ukfs_part *ukfs_part_none = &ukfs__part_none;
struct ukfs_part *ukfs_part_na = &ukfs__part_na;
+#define PART2LOCKSIZE(len) ((len) == RUMP_ETFS_SIZE_ENDOFF ? 0 : (len))
+
int
_ukfs_init(int version)
{
@@ -387,6 +390,20 @@
return rv;
}
+static void
+unlockdev(int fd, struct ukfs_part *part)
+{
+ struct flock flarg;
+
+ memset(&flarg, 0, sizeof(flarg));
+ flarg.l_type = F_UNLCK;
+ flarg.l_whence = SEEK_SET;
+ flarg.l_start = part->part_devoff;
+ flarg.l_len = PART2LOCKSIZE(part->part_devsize);
+ if (fcntl(fd, F_SETLK, &flarg) == -1)
+ warn("ukfs: cannot unlock device file");
+}
+
/*
* Open the disk file and flock it. Also, if we are operation on
* an embedded partition, find the partition offset and size from
@@ -395,12 +412,12 @@
* 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,
+ * 2) we failed to flock the source device (i.e. fcntl() 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...
+ * soft-fail before flock and mount does succeed...
*
* Returns: -1 error (errno reports error code)
* 0 success
@@ -435,10 +452,25 @@
* 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;
+ struct flock flarg;
+
+ memset(&flarg, 0, sizeof(flarg));
+ flarg.l_type = rdonly ? F_RDLCK : F_WRLCK;
+ flarg.l_whence = SEEK_SET;
+ flarg.l_start = part->part_devoff;
+ flarg.l_len = PART2LOCKSIZE(part->part_devsize);
+ if (fcntl(devfd, F_SETLK, &flarg) == -1) {
+ pid_t holder;
+ int sverrno;
+
+ sverrno = errno;
+ if (fcntl(devfd, F_GETLK, &flarg) != 1)
+ holder = flarg.l_pid;
+ else
+ holder = -1;
+ warnx("ukfs_mount: cannot lock device. held by pid %d",
+ holder);
+ rv = sverrno;
goto out;
}
} else {
@@ -518,10 +550,10 @@
fs->ukfs_cdir = ukfs_getrvp(fs);
pthread_spin_init(&fs->ukfs_spin, PTHREAD_PROCESS_SHARED);
fs->ukfs_devfd = devfd;
+ fs->ukfs_part = part;
assert(rv == 0);
out:
- ukfs_part_release(part);
if (rv) {
if (fs) {
if (fs->ukfs_rvp)
@@ -534,9 +566,10 @@
if (regged)
rump_pub_etfs_remove(devpath);
if (devfd != -1) {
- flock(devfd, LOCK_UN);
+ unlockdev(fs->ukfs_devfd, fs->ukfs_part);
close(devfd);
}
+ ukfs_part_release(part);
errno = rv;
}
@@ -588,6 +621,7 @@
rump_pub_lwp_release(rump_pub_lwp_curlwp());
}
+ ukfs_part_release(fs->ukfs_part);
if (fs->ukfs_devpath) {
rump_pub_etfs_remove(fs->ukfs_devpath);
free(fs->ukfs_devpath);
@@ -596,7 +630,7 @@
pthread_spin_destroy(&fs->ukfs_spin);
if (fs->ukfs_devfd != -1) {
- flock(fs->ukfs_devfd, LOCK_UN);
+ unlockdev(fs->ukfs_devfd, fs->ukfs_part);
close(fs->ukfs_devfd);
}
free(fs);
Home |
Main Index |
Thread Index |
Old Index