#include <stddef.h>
#include <string.h>
#include <errno.h>
+/* _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines
+ * that.
+ */
#include <unistd.h>
#include <byteswap.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/user.h>
-#include <netinet/in.h>
#include "os.h"
int sectorsize;
};
-/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
+/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
* case other systems have different values for MAXPATHLEN
*/
#define PATH_LEN_V3 4096
-/* Changes from V2 -
+/* Changes from V2 -
* PATH_LEN_V3 as described above
* Explicitly specify field bit lengths for systems with different
* lengths for the usual C types. Not sure whether char or
#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
-void cow_sizes(int version, __u64 size, int sectorsize, int align,
- int bitmap_offset, unsigned long *bitmap_len_out,
+void cow_sizes(int version, __u64 size, int sectorsize, int align,
+ int bitmap_offset, unsigned long *bitmap_len_out,
int *data_offset_out)
{
if(version < 3){
*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
*data_offset_out = bitmap_offset + *bitmap_len_out;
- *data_offset_out = (*data_offset_out + sectorsize - 1) /
+ *data_offset_out = (*data_offset_out + sectorsize - 1) /
sectorsize;
*data_offset_out *= sectorsize;
}
int remaining;
if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
- cow_printf("absolutize : unable to get cwd - errno = %d\n",
+ cow_printf("absolutize : unable to get cwd - errno = %d\n",
errno);
return(-1);
}
*slash = '\0';
if(chdir(from)){
*slash = '/';
- cow_printf("absolutize : Can't cd to '%s' - "
+ cow_printf("absolutize : Can't cd to '%s' - "
"errno = %d\n", from, errno);
return(-1);
}
return(0);
}
-int write_cow_header(char *cow_file, int fd, char *backing_file,
- int sectorsize, int alignment, long long *size)
+int write_cow_header(char *cow_file, int fd, char *backing_file,
+ int sectorsize, int alignment, unsigned long long *size)
{
struct cow_header_v3 *header;
unsigned long modtime;
err = -ENOMEM;
header = cow_malloc(sizeof(*header));
if(header == NULL){
- cow_printf("Failed to allocate COW V3 header\n");
+ cow_printf("write_cow_header - failed to allocate COW V3 header\n");
goto out;
}
header->magic = htonl(COW_MAGIC);
err = -EINVAL;
if(strlen(backing_file) > sizeof(header->backing_file) - 1){
cow_printf("Backing file name \"%s\" is too long - names are "
- "limited to %d characters\n", backing_file,
+ "limited to %d characters\n", backing_file,
sizeof(header->backing_file) - 1);
goto out_free;
}
- if(absolutize(header->backing_file, sizeof(header->backing_file),
+ if(absolutize(header->backing_file, sizeof(header->backing_file),
backing_file))
goto out_free;
err = os_file_modtime(header->backing_file, &modtime);
if(err < 0){
- cow_printf("Backing file '%s' mtime request failed, "
- "err = %d\n", header->backing_file, -err);
+ cow_printf("write_cow_header - backing file '%s' mtime "
+ "request failed, err = %d\n", header->backing_file,
+ -err);
goto out_free;
}
err = cow_file_size(header->backing_file, size);
if(err < 0){
- cow_printf("Couldn't get size of backing file '%s', "
- "err = %d\n", header->backing_file, -err);
+ cow_printf("write_cow_header - couldn't get size of "
+ "backing file '%s', err = %d\n",
+ header->backing_file, -err);
goto out_free;
}
header->alignment = htonl(alignment);
header->cow_format = COW_BITMAP;
- err = os_write_file(fd, header, sizeof(*header));
+ err = cow_write_file(fd, header, sizeof(*header));
if(err != sizeof(*header)){
- cow_printf("Write of header to new COW file '%s' failed, "
- "err = %d\n", cow_file, -err);
+ cow_printf("write_cow_header - write of header to "
+ "new COW file '%s' failed, err = %d\n", cow_file,
+ -err);
goto out_free;
}
err = 0;
/* XXX Need to sanity-check the values read from the header */
-int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
- __u32 *version_out, char **backing_file_out,
- time_t *mtime_out, __u64 *size_out,
- int *sectorsize_out, __u32 *align_out,
+int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
+ __u32 *version_out, char **backing_file_out,
+ time_t *mtime_out, unsigned long long *size_out,
+ int *sectorsize_out, __u32 *align_out,
int *bitmap_offset_out)
{
union cow_header *header;
}
else if(version == 3){
if(n < sizeof(header->v3)){
- cow_printf("read_cow_header - failed to read V2 "
+ cow_printf("read_cow_header - failed to read V3 "
"header\n");
goto out;
}
}
else {
cow_printf("read_cow_header - invalid COW version\n");
- goto out;
+ goto out;
}
err = -ENOMEM;
*backing_file_out = cow_strdup(file);
}
int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
- int alignment, int *bitmap_offset_out,
+ int alignment, int *bitmap_offset_out,
unsigned long *bitmap_len_out, int *data_offset_out)
{
- __u64 size, offset;
+ unsigned long long size, offset;
char zero = 0;
int err;
- err = write_cow_header(cow_file, fd, backing_file, sectorsize,
+ err = write_cow_header(cow_file, fd, backing_file, sectorsize,
alignment, &size);
- if(err)
+ if(err)
goto out;
-
+
*bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
bitmap_len_out, data_offset_out);
goto out;
}
- /* does not really matter how much we write it is just to set EOF
+ /* does not really matter how much we write it is just to set EOF
* this also sets the entire COW bitmap
- * to zero without having to allocate it
+ * to zero without having to allocate it
*/
err = cow_write_file(fd, &zero, sizeof(zero));
if(err != sizeof(zero)){
cow_printf("Write of bitmap to new COW file '%s' failed, "
"err = %d\n", cow_file, -err);
- err = -EINVAL;
+ if (err >= 0)
+ err = -EINVAL;
goto out;
}