From: NeilBrown Date: Sun, 13 Mar 2011 22:46:17 +0000 (+1100) Subject: Split open_device out of mkfs.lafs X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=56413dacedaa09debe4f6ea754f7467ed95a0b08;p=lafs-utils.git Split open_device out of mkfs.lafs 'lafs' will need this, so make it a separate file. Not in liblafs as it isn't really that generic. Signed-off-by: NeilBrown --- diff --git a/tools/Makefile b/tools/Makefile index 98ebab9..fb9e830 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -24,10 +24,18 @@ CPPFLAGS = -I../include CFLAGS = -Wall -Werror -g LDFLAGS = -L../lib -LDLIBS = -llafs -ltalloc -lreadline -luuid +LDLIBS = libinternal.a -llafs -ltalloc -lreadline -luuid -all : mkfs.lafs lafs +# 'internal' library +LIBSRC = open_device.c +LIBOBJ = $(patsubst %.c,%.o,$(LIBSRC)) -mkfs.lafs : mkfs.lafs.o ../lib/liblafs.a +all : mkfs.lafs lafs libinternal.a -lafs : lafs.o ../lib/liblafs.a +mkfs.lafs : mkfs.lafs.o ../lib/liblafs.a libinternal.a + +lafs : lafs.o ../lib/liblafs.a libinternal.a + +libinternal.a : $(LIBOBJ) internal.h + ar cr libinternal.a $(LIBOBJ) + ranlib libinternal.a diff --git a/tools/internal.h b/tools/internal.h new file mode 100644 index 0000000..436fc73 --- /dev/null +++ b/tools/internal.h @@ -0,0 +1,3 @@ + +int open_device(char *devname, long long *device_bytes, int regular_file, + char **error); diff --git a/tools/mkfs.lafs.c b/tools/mkfs.lafs.c index 5609321..24cd154 100644 --- a/tools/mkfs.lafs.c +++ b/tools/mkfs.lafs.c @@ -27,15 +27,11 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include +#include "internal.h" + /* * A new filesystem must contain: * inode 0 - TypeInodeFile with all the files listed here @@ -165,51 +161,6 @@ void get_num(int *valp, char *arg, char *name) *valp = val; } -int open_device(char *devname, long long *device_bytes, int regular_file) -{ - /* must be able to get an exclusive open on the device and its size - * must be non-trivial - * If 'regular_file', then expect a regular file to be used instead. - */ - int fd; - struct stat stb; - unsigned long long size = 0; - - fd = open(devname, O_RDWR|O_EXCL); - if (fd < 0 || fstat(fd, &stb) < 0) { - fprintf(stderr, "mkfs.lafs: cannot open device %s: %s\n", - devname, strerror(errno)); - exit(2); - } - - if (regular_file) { - if ((stb.st_mode & S_IFMT) != S_IFREG) - fprintf(stderr, "mkfs.lafs: %s is not a regular file\n", - devname); - else - size = stb.st_size; - } else { - if ((stb.st_mode & S_IFMT) != S_IFBLK) - fprintf(stderr, "mkfs.lafs: %s is not a block device\n", - devname); - else if (ioctl(fd, BLKGETSIZE64, &size) != 0) - fprintf(stderr, "mkfs.lafs: Cannot get size of %s\n", - devname); - else if (size == 0) - size = 1;/*ensure we get an error */ - } - if (size == 0) - ; - else if (size < 64*1024) - fprintf(stderr, "mkfs.lafs: %s is too small for a LAFS filesystem\n", - devname); - else { - *device_bytes = size; - return fd; - } - exit(2); -} - int main(int argc, char *argv[]) { int verbose = 0; @@ -285,7 +236,12 @@ int main(int argc, char *argv[]) } /* Validate device */ - dev_fd = open_device(devname, &device_bytes, regular_file); + dev_fd = open_device(devname, &device_bytes, regular_file, &error); + if (dev_fd < 0) { + fprintf(stderr, "mkfs.lafs: %s\n", error); + free(error); + exit(2); + } /* Validate parameters */ error = lafs_validate_geometry(&block_bytes, &segment_bytes, diff --git a/tools/open_device.c b/tools/open_device.c new file mode 100644 index 0000000..ba06941 --- /dev/null +++ b/tools/open_device.c @@ -0,0 +1,77 @@ + +/* support routine to open device or file for lafs tools. */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +int open_device(char *devname, long long *device_bytes, int regular_file, + char **error) +{ + /* must be able to get an exclusive open on the device and its size + * must be non-trivial + * If 'regular_file', then expect a regular file to be used instead. + * If device_bytes is already non-zero then it is OK to create + * a regular file. + */ + int fd; + struct stat stb; + unsigned long long size = 0; + + *error = NULL; + + if (!regular_file) + fd = open(devname, O_RDWR|O_EXCL); + else if (*device_bytes) + fd = open(devname, O_RDWR|O_CREAT, 0666); + else + fd = open(devname, O_RDWR); + if (fd < 0 || fstat(fd, &stb) < 0) { + asprintf(error, "cannot open %s %s:%s", + regular_file? "file" : "device", + devname, strerror(errno)); + return -1; + } + + if (regular_file) { + if ((stb.st_mode & S_IFMT) != S_IFREG) + asprintf(error, "%s is not a regular file", + devname); + else { + if (*device_bytes) { + char zero = 0; + lseek64(fd, *device_bytes-1, 0); + write(fd, &zero, 1); + fstat(fd, &stb); + } + size = stb.st_size; + } + } else { + if ((stb.st_mode & S_IFMT) != S_IFBLK) + asprintf(error, "%s is not a block device", + devname); + else if (ioctl(fd, BLKGETSIZE64, &size) != 0) + asprintf(error, "Cannot get size of %s", + devname); + } + + if (!error && size < 64*1024) + asprintf(error, "%s is too small for a LAFS filesystem", + devname); + + if (*error) { + close(fd); + return -1; + } + *device_bytes = size; + lseek64(fd, 0, 0); + return fd; +}