svn commit: r274838 - user/marcel/libvdsk/libvdsk
Marcel Moolenaar
marcel at FreeBSD.org
Sat Nov 22 02:44:41 UTC 2014
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__ */
More information about the svn-src-user
mailing list