2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
4 * Licensed under the GPL
13 #include <netinet/in.h>
16 #include <sys/fcntl.h>
17 #include <sys/socket.h>
20 #include <sys/param.h>
21 #include "asm/types.h"
22 #include "user_util.h"
23 #include "kern_util.h"
30 #if __BYTE_ORDER == __BIG_ENDIAN
31 # define ntohll(x) (x)
32 # define htonll(x) (x)
33 #elif __BYTE_ORDER == __LITTLE_ENDIAN
34 # define ntohll(x) bswap_64(x)
35 # define htonll(x) bswap_64(x)
37 #error "__BYTE_ORDER not defined"
40 #define PATH_LEN_V1 256
42 struct cow_header_v1 {
45 char backing_file[PATH_LEN_V1];
51 #define PATH_LEN_V2 MAXPATHLEN
53 struct cow_header_v2 {
55 unsigned long version;
56 char backing_file[PATH_LEN_V2];
63 struct cow_header_v1 v1;
64 struct cow_header_v2 v2;
67 #define COW_MAGIC 0x4f4f4f4d /* MOOO */
70 static void sizes(__u64 size, int sectorsize, int bitmap_offset,
71 unsigned long *bitmap_len_out, int *data_offset_out)
73 *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
75 *data_offset_out = bitmap_offset + *bitmap_len_out;
76 *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
77 *data_offset_out *= sectorsize;
80 static int read_cow_header(int fd, int *magic_out, char **backing_file_out,
81 time_t *mtime_out, __u64 *size_out,
82 int *sectorsize_out, int *bitmap_offset_out)
84 union cow_header *header;
87 unsigned long version, magic;
89 header = um_kmalloc(sizeof(*header));
91 printk("read_cow_header - Failed to allocate header\n");
95 n = read(fd, header, sizeof(*header));
96 if(n < offsetof(typeof(header->v1), backing_file)){
97 printk("read_cow_header - short header\n");
101 magic = header->v1.magic;
102 if(magic == COW_MAGIC) {
103 version = header->v1.version;
105 else if(magic == ntohl(COW_MAGIC)){
106 version = ntohl(header->v1.version);
110 *magic_out = COW_MAGIC;
113 if(n < sizeof(header->v1)){
114 printk("read_cow_header - failed to read V1 header\n");
117 *mtime_out = header->v1.mtime;
118 *size_out = header->v1.size;
119 *sectorsize_out = header->v1.sectorsize;
120 *bitmap_offset_out = sizeof(header->v1);
121 file = header->v1.backing_file;
123 else if(version == 2){
124 if(n < sizeof(header->v2)){
125 printk("read_cow_header - failed to read V2 header\n");
128 *mtime_out = ntohl(header->v2.mtime);
129 *size_out = ntohll(header->v2.size);
130 *sectorsize_out = ntohl(header->v2.sectorsize);
131 *bitmap_offset_out = sizeof(header->v2);
132 file = header->v2.backing_file;
135 printk("read_cow_header - invalid COW version\n");
139 *backing_file_out = uml_strdup(file);
140 if(*backing_file_out == NULL){
141 printk("read_cow_header - failed to allocate backing file\n");
150 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
152 struct stat buf1, buf2;
154 if(from_cmdline == NULL) return(1);
155 if(!strcmp(from_cmdline, from_cow)) return(1);
157 if(stat(from_cmdline, &buf1) < 0){
158 printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
162 if(stat(from_cow, &buf2) < 0){
163 printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
166 if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
169 printk("Backing file mismatch - \"%s\" requested,\n"
170 "\"%s\" specified in COW header of \"%s\"\n",
171 from_cmdline, from_cow, cow);
175 static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
181 if(stat64(file, &buf) < 0){
182 printk("Failed to stat backing file \"%s\", errno = %d\n",
187 err = os_file_size(file, &actual);
189 printk("Failed to get size of backing file \"%s\", "
190 "errno = %d\n", file, -err);
195 printk("Size mismatch (%ld vs %ld) of COW header vs backing "
196 "file\n", size, actual);
199 if(buf.st_mtime != mtime){
200 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
201 "file\n", mtime, buf.st_mtime);
207 int read_cow_bitmap(int fd, void *buf, int offset, int len)
211 err = os_seek_file(fd, offset);
212 if(err != 0) return(-errno);
213 err = read(fd, buf, len);
214 if(err < 0) return(-errno);
218 static int absolutize(char *to, int size, char *from)
220 char save_cwd[256], *slash;
223 if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
224 printk("absolutize : unable to get cwd - errno = %d\n", errno);
227 slash = strrchr(from, '/');
232 printk("absolutize : Can't cd to '%s' - errno = %d\n",
237 if(getcwd(to, size) == NULL){
238 printk("absolutize : unable to get cwd of '%s' - "
239 "errno = %d\n", from, errno);
242 remaining = size - strlen(to);
243 if(strlen(slash) + 1 > remaining){
244 printk("absolutize : unable to fit '%s' into %d "
245 "chars\n", from, size);
251 if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
252 printk("absolutize : unable to fit '%s' into %d "
253 "chars\n", from, size);
256 strcpy(to, save_cwd);
264 static int write_cow_header(char *cow_file, int fd, char *backing_file,
265 int sectorsize, long long *size)
267 struct cow_header_v2 *header;
271 err = os_seek_file(fd, 0);
273 printk("write_cow_header - lseek failed, errno = %d\n", errno);
278 header = um_kmalloc(sizeof(*header));
280 printk("Failed to allocate COW V2 header\n");
283 header->magic = htonl(COW_MAGIC);
284 header->version = htonl(COW_VERSION);
287 if(strlen(backing_file) > sizeof(header->backing_file) - 1){
288 printk("Backing file name \"%s\" is too long - names are "
289 "limited to %d characters\n", backing_file,
290 sizeof(header->backing_file) - 1);
294 if(absolutize(header->backing_file, sizeof(header->backing_file),
298 err = stat64(header->backing_file, &buf);
300 printk("Stat of backing file '%s' failed, errno = %d\n",
301 header->backing_file, errno);
306 err = os_file_size(header->backing_file, size);
308 printk("Couldn't get size of backing file '%s', errno = %d\n",
309 header->backing_file, -*size);
313 header->mtime = htonl(buf.st_mtime);
314 header->size = htonll(*size);
315 header->sectorsize = htonl(sectorsize);
317 err = write(fd, header, sizeof(*header));
318 if(err != sizeof(*header)){
319 printk("Write of header to new COW file '%s' failed, "
320 "errno = %d\n", cow_file, errno);
330 int open_ubd_file(char *file, struct openflags *openflags,
331 char **backing_file_out, int *bitmap_offset_out,
332 unsigned long *bitmap_len_out, int *data_offset_out,
338 int fd, err, sectorsize, magic, same, mode = 0644;
340 if((fd = os_open_file(file, *openflags, mode)) < 0){
341 if((fd == -ENOENT) && (create_cow_out != NULL))
344 ((errno != EROFS) && (errno != EACCES))) return(-errno);
346 if((fd = os_open_file(file, *openflags, mode)) < 0)
349 if(backing_file_out == NULL) return(fd);
351 err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
352 §orsize, bitmap_offset_out);
353 if(err && (*backing_file_out != NULL)){
354 printk("Failed to read COW header from COW file \"%s\", "
355 "errno = %d\n", file, err);
360 if(backing_file_out == NULL) return(fd);
362 same = same_backing_files(*backing_file_out, backing_file, file);
364 if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
365 printk("Switching backing file to '%s'\n", *backing_file_out);
366 err = write_cow_header(file, fd, *backing_file_out,
369 printk("Switch failed, errno = %d\n", err);
374 *backing_file_out = backing_file;
375 err = backing_file_mismatch(*backing_file_out, size, mtime);
379 sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
388 int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
389 int sectorsize, int *bitmap_offset_out,
390 unsigned long *bitmap_len_out, int *data_offset_out)
398 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
401 printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
406 err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
407 if(err) goto out_close;
409 blocks = (size + sectorsize - 1) / sectorsize;
410 blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
412 for(i = 0; i < blocks; i++){
413 err = write(fd, &zero, sizeof(zero));
414 if(err != sizeof(zero)){
415 printk("Write of bitmap to new COW file '%s' failed, "
416 "errno = %d\n", cow_file, errno);
421 sizes(size, sectorsize, sizeof(struct cow_header_v2),
422 bitmap_len_out, data_offset_out);
423 *bitmap_offset_out = sizeof(struct cow_header_v2);
433 int read_ubd_fs(int fd, void *buffer, int len)
437 n = read(fd, buffer, len);
438 if(n < 0) return(-errno);
442 int write_ubd_fs(int fd, char *buffer, int len)
446 n = write(fd, buffer, len);
447 if(n < 0) return(-errno);
451 int ubd_is_dir(char *file)
455 if(stat64(file, &buf) < 0) return(0);
456 return(S_ISDIR(buf.st_mode));
459 void do_io(struct io_thread_req *req)
463 int n, nsectors, start, end, bit;
466 nsectors = req->length / req->sectorsize;
469 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
471 while((end < nsectors) &&
472 (ubd_test_bit(end, (unsigned char *)
473 &req->sector_mask) == bit))
477 printk("end != nsectors\n");
478 off = req->offset + req->offsets[bit] +
479 start * req->sectorsize;
480 len = (end - start) * req->sectorsize;
481 buf = &req->buffer[start * req->sectorsize];
483 if(os_seek_file(req->fds[bit], off) != 0){
484 printk("do_io - lseek failed : errno = %d\n", errno);
488 if(req->op == UBD_READ){
493 n = read(req->fds[bit], buf, len);
495 printk("do_io - read returned %d : "
496 "errno = %d fd = %d\n", n,
497 errno, req->fds[bit]);
501 } while((n < len) && (n != 0));
502 if (n < len) memset(&buf[n], 0, len - n);
505 n = write(req->fds[bit], buf, len);
507 printk("do_io - write returned %d : "
508 "errno = %d fd = %d\n", n,
509 errno, req->fds[bit]);
516 } while(start < nsectors);
518 if(req->cow_offset != -1){
519 if(os_seek_file(req->fds[1], req->cow_offset) != 0){
520 printk("do_io - bitmap lseek failed : errno = %d\n",
525 n = write(req->fds[1], &req->bitmap_words,
526 sizeof(req->bitmap_words));
527 if(n != sizeof(req->bitmap_words)){
528 printk("do_io - bitmap update returned %d : "
529 "errno = %d fd = %d\n", n, errno, req->fds[1]);
538 /* Changed in start_io_thread, which is serialized by being called only
539 * from ubd_init, which is an initcall.
543 /* Only changed by the io thread */
546 int io_thread(void *arg)
548 struct io_thread_req req;
551 signal(SIGWINCH, SIG_IGN);
553 n = read(kernel_fd, &req, sizeof(req));
554 if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
556 else if(n < sizeof(req)){
557 printk("io_thread - short read : length = %d\n", n);
562 n = write(kernel_fd, &req, sizeof(req));
564 printk("io_thread - write failed, errno = %d\n",
569 int start_io_thread(unsigned long sp, int *fd_out)
571 int pid, fds[2], err;
573 err = os_pipe(fds, 1, 1);
575 printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
581 pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
584 printk("start_io_thread - clone failed : errno = %d\n", errno);
591 int start_io_thread(unsigned long sp, int *fd_out)
595 if((kernel_fd = get_pty()) < 0) return(-1);
597 if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
598 printk("Couldn't open tty for IO\n");
602 pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
605 printk("start_io_thread - clone failed : errno = %d\n", errno);
613 * Overrides for Emacs so that we follow Linus's tabbing style.
614 * Emacs will notice this stuff at the end of the file and automatically
615 * adjust the settings for this buffer only. This must remain at the end
617 * ---------------------------------------------------------------------------
619 * c-file-style: "linux"