Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Nov 2014 02:44:40 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r274838 - user/marcel/libvdsk/libvdsk
Message-ID:  <201411220244.sAM2iex0019702@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Sat Nov 22 02:44:39 2014
New Revision: 274838
URL: https://svnweb.freebsd.org/changeset/base/274838

Log:
  Strengthen vdsk_open:
  1.  Save the realpath(3) result in the vdsk structure.
  2.  Save the stat(2) result in the vdsk structure.
  3.  Take an exclusive or shared lock depending on the open flags.

Modified:
  user/marcel/libvdsk/libvdsk/vdsk.c
  user/marcel/libvdsk/libvdsk/vdsk_int.h

Modified: user/marcel/libvdsk/libvdsk/vdsk.c
==============================================================================
--- user/marcel/libvdsk/libvdsk/vdsk.c	Sat Nov 22 01:27:45 2014	(r274837)
+++ user/marcel/libvdsk/libvdsk/vdsk.c	Sat Nov 22 02:44:39 2014	(r274838)
@@ -51,9 +51,9 @@ vdsk_deref(vdskctx ctx)
 vdskctx
 vdsk_open(const char *path, int flags, size_t size)
 {
-	struct stat sb;
 	vdskctx ctx;
 	struct vdsk *vdsk;
+	int lck;
 
 	ctx = NULL;
 
@@ -63,14 +63,25 @@ vdsk_open(const char *path, int flags, s
 		if (vdsk == NULL)
 			break;
 
-		vdsk->fd = open(path, flags);
+		vdsk->fflags = flags + 1;
+		if ((vdsk->fflags & ~(O_ACCMODE | O_DIRECT | O_SYNC)) != 0) {
+			errno = EINVAL;
+			break;
+		}
+
+		vdsk->filename = realpath(path, NULL);
+		if (vdsk->filename == NULL)
+			break;
+
+		flags = (flags & O_ACCMODE) | O_CLOEXEC;
+		vdsk->fd = open(vdsk->filename, flags);
 		if (vdsk->fd == -1)
 			break;
 
-		if (fstat(vdsk->fd, &sb) == -1)
+		if (fstat(vdsk->fd, &vdsk->fsbuf) == -1)
 			break;
 
-		if (S_ISCHR(sb.st_mode)) {
+		if (S_ISCHR(vdsk->fsbuf.st_mode)) {
 			if (ioctl(vdsk->fd, DIOCGMEDIASIZE,
 			    &vdsk->capacity) < 0)
 				break;
@@ -78,10 +89,14 @@ vdsk_open(const char *path, int flags, s
 			    &vdsk->sectorsize) < 0)
 				break;
 		} else {
-			vdsk->capacity = sb.st_size;
+			vdsk->capacity = vdsk->fsbuf.st_size;
 			vdsk->sectorsize = DEV_BSIZE;
 		}
 
+		lck = (vdsk->fflags & FWRITE) ? LOCK_EX : LOCK_SH;
+		if (flock(vdsk->fd, lck | LOCK_NB) == -1)
+			break;
+
 		/* Complete... */
 		ctx = vdsk + 1;
 	} while (0);
@@ -90,8 +105,9 @@ vdsk_open(const char *path, int flags, s
 		if (vdsk != NULL) {
 			if (vdsk->fd != -1)
 				close(vdsk->fd);
+			if (vdsk->filename != NULL)
+				free(vdsk->filename);
 			free(vdsk);
-			vdsk = NULL;
 		}
 	}
 
@@ -103,7 +119,9 @@ vdsk_close(vdskctx ctx)
 {
 	struct vdsk *vdsk = vdsk_deref(ctx);
 
+	flock(vdsk->fd, LOCK_UN);
 	close(vdsk->fd);
+	free(vdsk->filename);
 	free(vdsk);
 	return (0);
 }

Modified: user/marcel/libvdsk/libvdsk/vdsk_int.h
==============================================================================
--- user/marcel/libvdsk/libvdsk/vdsk_int.h	Sat Nov 22 01:27:45 2014	(r274837)
+++ user/marcel/libvdsk/libvdsk/vdsk_int.h	Sat Nov 22 02:44:39 2014	(r274838)
@@ -31,8 +31,11 @@
 
 struct vdsk {
 	int	fd;
-	int	sectorsize;
+	int	fflags;
+	char	*filename;
+	struct stat fsbuf;
 	off_t	capacity;
+	int	sectorsize;
 } __attribute__((align(16)));
 
 #endif /* __VDSK_INT_H__ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411220244.sAM2iex0019702>