X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fdrivers%2Fubd_user.c;h=b94d2bc4fe06658777e8dcc632c7217814a7e27b;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=882d2f7c1ee72a175d26c5d182ec80efb7d89f0c;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index 882d2f7c1..b94d2bc4f 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -26,311 +26,9 @@ #include #include -static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) +void ignore_sigwinch_sig(void) { - struct uml_stat buf1, buf2; - int err; - - if(from_cmdline == NULL) return(1); - if(!strcmp(from_cmdline, from_cow)) return(1); - - err = os_stat_file(from_cmdline, &buf1); - if(err < 0){ - printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err); - return(1); - } - err = os_stat_file(from_cow, &buf2); - if(err < 0){ - printk("Couldn't stat '%s', err = %d\n", from_cow, -err); - return(1); - } - if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino)) - return(1); - - printk("Backing file mismatch - \"%s\" requested,\n" - "\"%s\" specified in COW header of \"%s\"\n", - from_cmdline, from_cow, cow); - return(0); -} - -static int backing_file_mismatch(char *file, __u64 size, time_t mtime) -{ - unsigned long modtime; - long long actual; - int err; - - err = os_file_modtime(file, &modtime); - if(err < 0){ - printk("Failed to get modification time of backing file " - "\"%s\", err = %d\n", file, -err); - return(err); - } - - err = os_file_size(file, &actual); - if(err < 0){ - printk("Failed to get size of backing file \"%s\", " - "err = %d\n", file, -err); - return(err); - } - - if(actual != size){ - printk("Size mismatch (%ld vs %ld) of COW header vs backing " - "file\n", size, actual); - return(-EINVAL); - } - if(modtime != mtime){ - printk("mtime mismatch (%ld vs %ld) of COW header vs backing " - "file\n", mtime, modtime); - return(-EINVAL); - } - return(0); -} - -int read_cow_bitmap(int fd, void *buf, int offset, int len) -{ - int err; - - err = os_seek_file(fd, offset); - if(err < 0) - return(err); - - err = os_read_file(fd, buf, len); - if(err < 0) - return(err); - - return(0); -} - -int open_ubd_file(char *file, struct openflags *openflags, - char **backing_file_out, int *bitmap_offset_out, - unsigned long *bitmap_len_out, int *data_offset_out, - int *create_cow_out) -{ - time_t mtime; - __u64 size; - __u32 version, align; - char *backing_file; - int fd, err, sectorsize, same, mode = 0644; - - fd = os_open_file(file, *openflags, mode); - if(fd < 0){ - if((fd == -ENOENT) && (create_cow_out != NULL)) - *create_cow_out = 1; - if(!openflags->w || - ((errno != EROFS) && (errno != EACCES))) return(-errno); - openflags->w = 0; - fd = os_open_file(file, *openflags, mode); - if(fd < 0) - return(fd); - } - - err = os_lock_file(fd, openflags->w); - if(err < 0){ - printk("Failed to lock '%s', err = %d\n", file, -err); - goto out_close; - } - - if(backing_file_out == NULL) return(fd); - - err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, - &size, §orsize, &align, bitmap_offset_out); - if(err && (*backing_file_out != NULL)){ - printk("Failed to read COW header from COW file \"%s\", " - "errno = %d\n", file, -err); - goto out_close; - } - if(err) return(fd); - - if(backing_file_out == NULL) return(fd); - - same = same_backing_files(*backing_file_out, backing_file, file); - - if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){ - printk("Switching backing file to '%s'\n", *backing_file_out); - err = write_cow_header(file, fd, *backing_file_out, - sectorsize, align, &size); - if(err){ - printk("Switch failed, errno = %d\n", -err); - return(err); - } - } - else { - *backing_file_out = backing_file; - err = backing_file_mismatch(*backing_file_out, size, mtime); - if(err) goto out_close; - } - - cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, - bitmap_len_out, data_offset_out); - - return(fd); - out_close: - os_close_file(fd); - return(err); -} - -int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, - int sectorsize, int alignment, int *bitmap_offset_out, - unsigned long *bitmap_len_out, int *data_offset_out) -{ - int err, fd; - - flags.c = 1; - fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); - if(fd < 0){ - err = fd; - printk("Open of COW file '%s' failed, errno = %d\n", cow_file, - -err); - goto out; - } - - err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment, - bitmap_offset_out, bitmap_len_out, - data_offset_out); - if(!err) - return(fd); - os_close_file(fd); - out: - return(err); -} - -/* XXX Just trivial wrappers around os_read_file and os_write_file */ -int read_ubd_fs(int fd, void *buffer, int len) -{ - return(os_read_file(fd, buffer, len)); -} - -int write_ubd_fs(int fd, char *buffer, int len) -{ - return(os_write_file(fd, buffer, len)); -} - -static int update_bitmap(struct io_thread_req *req) -{ - int n; - - if(req->cow_offset == -1) - return(0); - - n = os_seek_file(req->fds[1], req->cow_offset); - if(n < 0){ - printk("do_io - bitmap lseek failed : err = %d\n", -n); - return(1); - } - - n = os_write_file(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words)); - if(n != sizeof(req->bitmap_words)){ - printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, - req->fds[1]); - return(1); - } - - return(0); -} - -void do_io(struct io_thread_req *req) -{ - char *buf; - unsigned long len; - int n, nsectors, start, end, bit; - int err; - __u64 off; - - if(req->op == UBD_MMAP){ - /* Touch the page to force the host to do any necessary IO to - * get it into memory - */ - n = *((volatile int *) req->buffer); - req->error = update_bitmap(req); - return; - } - - nsectors = req->length / req->sectorsize; - start = 0; - do { - bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask); - end = start; - while((end < nsectors) && - (ubd_test_bit(end, (unsigned char *) - &req->sector_mask) == bit)) - end++; - - off = req->offset + req->offsets[bit] + - start * req->sectorsize; - len = (end - start) * req->sectorsize; - buf = &req->buffer[start * req->sectorsize]; - - err = os_seek_file(req->fds[bit], off); - if(err < 0){ - printk("do_io - lseek failed : err = %d\n", -err); - req->error = 1; - return; - } - if(req->op == UBD_READ){ - n = 0; - do { - buf = &buf[n]; - len -= n; - n = os_read_file(req->fds[bit], buf, len); - if (n < 0) { - printk("do_io - read failed, err = %d " - "fd = %d\n", -n, req->fds[bit]); - req->error = 1; - return; - } - } while((n < len) && (n != 0)); - if (n < len) memset(&buf[n], 0, len - n); - } - else { - n = os_write_file(req->fds[bit], buf, len); - if(n != len){ - printk("do_io - write failed err = %d " - "fd = %d\n", -n, req->fds[bit]); - req->error = 1; - return; - } - } - - start = end; - } while(start < nsectors); - - req->error = update_bitmap(req); -} - -/* Changed in start_io_thread, which is serialized by being called only - * from ubd_init, which is an initcall. - */ -int kernel_fd = -1; - -/* Only changed by the io thread */ -int io_count = 0; - -int io_thread(void *arg) -{ - struct io_thread_req req; - int n; - signal(SIGWINCH, SIG_IGN); - while(1){ - n = os_read_file(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)){ - if(n < 0) - printk("io_thread - read failed, fd = %d, " - "err = %d\n", kernel_fd, -n); - else { - printk("io_thread - short read, fd = %d, " - "length = %d\n", kernel_fd, n); - } - continue; - } - io_count++; - do_io(&req); - n = os_write_file(kernel_fd, &req, sizeof(req)); - if(n != sizeof(req)) - printk("io_thread - write failed, fd = %d, err = %d\n", - kernel_fd, -n); - } } int start_io_thread(unsigned long sp, int *fd_out)