-static int ubd_check_remapped(int fd, unsigned long address, int is_write,
- __u64 offset)
-{
- __u64 bitmap_offset;
- unsigned long new_bitmap[2];
- int i, err, n;
-
- /* If it's not a write access, we can't do anything about it */
- if(!is_write)
- return(0);
-
- /* We have a write */
- for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
- struct ubd *dev = &ubd_dev[i];
-
- if((dev->fd != fd) && (dev->cow.fd != fd))
- continue;
-
- /* It's a write to a ubd device */
-
- if(!dev->openflags.w){
- /* It's a write access on a read-only device - probably
- * shouldn't happen. If the kernel is trying to change
- * something with no intention of writing it back out,
- * then this message will clue us in that this needs
- * fixing
- */
- printk("Write access to mapped page from readonly ubd "
- "device %d\n", i);
- return(0);
- }
-
- /* It's a write to a writeable ubd device - it must be COWed
- * because, otherwise, the page would have been mapped in
- * writeable
- */
-
- if(!dev->cow.file)
- panic("Write fault on writeable non-COW ubd device %d",
- i);
-
- /* It should also be an access to the backing file since the
- * COW pages should be mapped in read-write
- */
-
- if(fd == dev->fd)
- panic("Write fault on a backing page of ubd "
- "device %d\n", i);
-
- /* So, we do the write, copying the backing data to the COW
- * file...
- */
-
- err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
- if(err < 0)
- panic("Couldn't seek to %lld in COW file of ubd "
- "device %d, err = %d",
- offset + dev->cow.data_offset, i, -err);
-
- n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
- if(n != PAGE_SIZE)
- panic("Couldn't copy data to COW file of ubd "
- "device %d, err = %d", i, -n);
-
- /* ... updating the COW bitmap... */
-
- cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
- dev->cow.bitmap, dev->cow.bitmap_offset,
- new_bitmap, dev->cow.bitmap_len);
-
- err = os_seek_file(dev->fd, bitmap_offset);
- if(err < 0)
- panic("Couldn't seek to %lld in COW file of ubd "
- "device %d, err = %d", bitmap_offset, i, -err);
-
- n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
- if(n != sizeof(new_bitmap))
- panic("Couldn't update bitmap of ubd device %d, "
- "err = %d", i, -n);
-
- /* Maybe we can map the COW page in, and maybe we can't. If
- * it is a pre-V3 COW file, we can't, since the alignment will
- * be wrong. If it is a V3 or later COW file which has been
- * moved to a system with a larger page size, then maybe we
- * can't, depending on the exact location of the page.
- */
-
- offset += dev->cow.data_offset;
-
- /* Remove the remapping, putting the original anonymous page
- * back. If the COW file can be mapped in, that is done.
- * Otherwise, the COW page is read in.
- */
-
- if(!physmem_remove_mapping((void *) address))
- panic("Address 0x%lx not remapped by ubd device %d",
- address, i);
- if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
- physmem_subst_mapping((void *) address, dev->fd,
- offset, 1);
- else {
- err = os_seek_file(dev->fd, offset);
- if(err < 0)
- panic("Couldn't seek to %lld in COW file of "
- "ubd device %d, err = %d", offset, i,
- -err);
-
- n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
- if(n != PAGE_SIZE)
- panic("Failed to read page from offset %llx of "
- "COW file of ubd device %d, err = %d",
- offset, i, -n);
- }
-
- return(1);
- }
-
- /* It's not a write on a ubd device */
- return(0);
-}
-
-static struct remapper ubd_remapper = {
- .list = LIST_HEAD_INIT(ubd_remapper.list),
- .proc = ubd_check_remapped,
-};
-
-static int ubd_remapper_setup(void)
-{
- if(ubd_do_mmap)
- register_remapper(&ubd_remapper);
-
- return(0);
-}
-
-__initcall(ubd_remapper_setup);
-
-static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)