vserver 1.9.5.x5
[linux-2.6.git] / arch / um / drivers / ubd_user.c
index 882d2f7..b94d2bc 100644 (file)
 #include <endian.h>
 #include <byteswap.h>
 
-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, &sectorsize, &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)