ia64/linux-2.6.18-xen.hg

annotate mm/filemap.h @ 912:dd42cdb0ab89

[IA64] Build blktap2 driver by default in x86 builds.

add CONFIG_XEN_BLKDEV_TAP2=y to buildconfigs/linux-defconfig_xen_ia64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 12:09:16 2009 +0900 (2009-06-29)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * linux/mm/filemap.h
ian@0 3 *
ian@0 4 * Copyright (C) 1994-1999 Linus Torvalds
ian@0 5 */
ian@0 6
ian@0 7 #ifndef __FILEMAP_H
ian@0 8 #define __FILEMAP_H
ian@0 9
ian@0 10 #include <linux/types.h>
ian@0 11 #include <linux/fs.h>
ian@0 12 #include <linux/mm.h>
ian@0 13 #include <linux/highmem.h>
ian@0 14 #include <linux/uio.h>
ian@0 15 #include <linux/config.h>
ian@0 16 #include <linux/uaccess.h>
ian@0 17
ian@0 18 size_t
ian@0 19 __filemap_copy_from_user_iovec_inatomic(char *vaddr,
ian@0 20 const struct iovec *iov,
ian@0 21 size_t base,
ian@0 22 size_t bytes);
ian@0 23
ian@0 24 /*
ian@0 25 * Copy as much as we can into the page and return the number of bytes which
ian@0 26 * were sucessfully copied. If a fault is encountered then clear the page
ian@0 27 * out to (offset+bytes) and return the number of bytes which were copied.
ian@0 28 *
ian@0 29 * NOTE: For this to work reliably we really want copy_from_user_inatomic_nocache
ian@0 30 * to *NOT* zero any tail of the buffer that it failed to copy. If it does,
ian@0 31 * and if the following non-atomic copy succeeds, then there is a small window
ian@0 32 * where the target page contains neither the data before the write, nor the
ian@0 33 * data after the write (it contains zero). A read at this time will see
ian@0 34 * data that is inconsistent with any ordering of the read and the write.
ian@0 35 * (This has been detected in practice).
ian@0 36 */
ian@0 37 static inline size_t
ian@0 38 filemap_copy_from_user(struct page *page, unsigned long offset,
ian@0 39 const char __user *buf, unsigned bytes)
ian@0 40 {
ian@0 41 char *kaddr;
ian@0 42 int left;
ian@0 43
ian@0 44 kaddr = kmap_atomic(page, KM_USER0);
ian@0 45 left = __copy_from_user_inatomic_nocache(kaddr + offset, buf, bytes);
ian@0 46 kunmap_atomic(kaddr, KM_USER0);
ian@0 47
ian@0 48 if (left != 0) {
ian@0 49 /* Do it the slow way */
ian@0 50 kaddr = kmap(page);
ian@0 51 left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
ian@0 52 kunmap(page);
ian@0 53 }
ian@0 54 return bytes - left;
ian@0 55 }
ian@0 56
ian@0 57 /*
ian@0 58 * This has the same sideeffects and return value as filemap_copy_from_user().
ian@0 59 * The difference is that on a fault we need to memset the remainder of the
ian@0 60 * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
ian@0 61 * single-segment behaviour.
ian@0 62 */
ian@0 63 static inline size_t
ian@0 64 filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
ian@0 65 const struct iovec *iov, size_t base, size_t bytes)
ian@0 66 {
ian@0 67 char *kaddr;
ian@0 68 size_t copied;
ian@0 69
ian@0 70 kaddr = kmap_atomic(page, KM_USER0);
ian@0 71 copied = __filemap_copy_from_user_iovec_inatomic(kaddr + offset, iov,
ian@0 72 base, bytes);
ian@0 73 kunmap_atomic(kaddr, KM_USER0);
ian@0 74 if (copied != bytes) {
ian@0 75 kaddr = kmap(page);
ian@0 76 copied = __filemap_copy_from_user_iovec_inatomic(kaddr + offset, iov,
ian@0 77 base, bytes);
ian@0 78 if (bytes - copied)
ian@0 79 memset(kaddr + offset + copied, 0, bytes - copied);
ian@0 80 kunmap(page);
ian@0 81 }
ian@0 82 return copied;
ian@0 83 }
ian@0 84
ian@0 85 static inline void
ian@0 86 filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
ian@0 87 {
ian@0 88 const struct iovec *iov = *iovp;
ian@0 89 size_t base = *basep;
ian@0 90
ian@0 91 do {
ian@0 92 int copy = min(bytes, iov->iov_len - base);
ian@0 93
ian@0 94 bytes -= copy;
ian@0 95 base += copy;
ian@0 96 if (iov->iov_len == base) {
ian@0 97 iov++;
ian@0 98 base = 0;
ian@0 99 }
ian@0 100 } while (bytes);
ian@0 101 *iovp = iov;
ian@0 102 *basep = base;
ian@0 103 }
ian@0 104 #endif