mm: document tree_lock->zone.lock lockorder
[pandora-kernel.git] / mm / filemap.c
index fb4c1c0..4fb1546 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/cpuset.h>
-#include "filemap.h"
+#include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
 #include "internal.h"
 
 /*
@@ -63,6 +63,7 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
  *    ->private_lock           (__free_pte->__set_page_dirty_buffers)
  *      ->swap_lock            (exclusive_swap_page, others)
  *        ->mapping->tree_lock
+ *          ->zone.lock
  *
  *  ->i_mutex
  *    ->i_mmap_lock            (truncate->unmap_mapping_range)
@@ -1635,8 +1636,7 @@ int remove_suid(struct dentry *dentry)
 }
 EXPORT_SYMBOL(remove_suid);
 
-size_t
-__filemap_copy_from_user_iovec_inatomic(char *vaddr,
+static size_t __iovec_copy_from_user_inatomic(char *vaddr,
                        const struct iovec *iov, size_t base, size_t bytes)
 {
        size_t copied = 0, left = 0;
@@ -1658,6 +1658,124 @@ __filemap_copy_from_user_iovec_inatomic(char *vaddr,
        return copied - left;
 }
 
+/*
+ * Copy as much as we can into the page and return the number of bytes which
+ * were sucessfully copied.  If a fault is encountered then return the number of
+ * bytes which were copied.
+ */
+size_t iov_iter_copy_from_user_atomic(struct page *page,
+               struct iov_iter *i, unsigned long offset, size_t bytes)
+{
+       char *kaddr;
+       size_t copied;
+
+       BUG_ON(!in_atomic());
+       kaddr = kmap_atomic(page, KM_USER0);
+       if (likely(i->nr_segs == 1)) {
+               int left;
+               char __user *buf = i->iov->iov_base + i->iov_offset;
+               left = __copy_from_user_inatomic_nocache(kaddr + offset,
+                                                       buf, bytes);
+               copied = bytes - left;
+       } else {
+               copied = __iovec_copy_from_user_inatomic(kaddr + offset,
+                                               i->iov, i->iov_offset, bytes);
+       }
+       kunmap_atomic(kaddr, KM_USER0);
+
+       return copied;
+}
+EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
+
+/*
+ * This has the same sideeffects and return value as
+ * iov_iter_copy_from_user_atomic().
+ * The difference is that it attempts to resolve faults.
+ * Page must not be locked.
+ */
+size_t iov_iter_copy_from_user(struct page *page,
+               struct iov_iter *i, unsigned long offset, size_t bytes)
+{
+       char *kaddr;
+       size_t copied;
+
+       kaddr = kmap(page);
+       if (likely(i->nr_segs == 1)) {
+               int left;
+               char __user *buf = i->iov->iov_base + i->iov_offset;
+               left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
+               copied = bytes - left;
+       } else {
+               copied = __iovec_copy_from_user_inatomic(kaddr + offset,
+                                               i->iov, i->iov_offset, bytes);
+       }
+       kunmap(page);
+       return copied;
+}
+EXPORT_SYMBOL(iov_iter_copy_from_user);
+
+static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
+{
+       if (likely(i->nr_segs == 1)) {
+               i->iov_offset += bytes;
+       } else {
+               const struct iovec *iov = i->iov;
+               size_t base = i->iov_offset;
+
+               while (bytes) {
+                       int copy = min(bytes, iov->iov_len - base);
+
+                       bytes -= copy;
+                       base += copy;
+                       if (iov->iov_len == base) {
+                               iov++;
+                               base = 0;
+                       }
+               }
+               i->iov = iov;
+               i->iov_offset = base;
+       }
+}
+
+void iov_iter_advance(struct iov_iter *i, size_t bytes)
+{
+       BUG_ON(i->count < bytes);
+
+       __iov_iter_advance_iov(i, bytes);
+       i->count -= bytes;
+}
+EXPORT_SYMBOL(iov_iter_advance);
+
+/*
+ * Fault in the first iovec of the given iov_iter, to a maximum length
+ * of bytes. Returns 0 on success, or non-zero if the memory could not be
+ * accessed (ie. because it is an invalid address).
+ *
+ * writev-intensive code may want this to prefault several iovecs -- that
+ * would be possible (callers must not rely on the fact that _only_ the
+ * first iovec will be faulted with the current implementation).
+ */
+int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
+{
+       char __user *buf = i->iov->iov_base + i->iov_offset;
+       bytes = min(bytes, i->iov->iov_len - i->iov_offset);
+       return fault_in_pages_readable(buf, bytes);
+}
+EXPORT_SYMBOL(iov_iter_fault_in_readable);
+
+/*
+ * Return the count of just the current iov_iter segment.
+ */
+size_t iov_iter_single_seg_count(struct iov_iter *i)
+{
+       const struct iovec *iov = i->iov;
+       if (i->nr_segs == 1)
+               return i->count;
+       else
+               return min(i->count, iov->iov_len - i->iov_offset);
+}
+EXPORT_SYMBOL(iov_iter_single_seg_count);
+
 /*
  * Performs necessary checks before doing a write
  *
@@ -1740,6 +1858,91 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
 }
 EXPORT_SYMBOL(generic_write_checks);
 
+int pagecache_write_begin(struct file *file, struct address_space *mapping,
+                               loff_t pos, unsigned len, unsigned flags,
+                               struct page **pagep, void **fsdata)
+{
+       const struct address_space_operations *aops = mapping->a_ops;
+
+       if (aops->write_begin) {
+               return aops->write_begin(file, mapping, pos, len, flags,
+                                                       pagep, fsdata);
+       } else {
+               int ret;
+               pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+               unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+               struct inode *inode = mapping->host;
+               struct page *page;
+again:
+               page = __grab_cache_page(mapping, index);
+               *pagep = page;
+               if (!page)
+                       return -ENOMEM;
+
+               if (flags & AOP_FLAG_UNINTERRUPTIBLE && !PageUptodate(page)) {
+                       /*
+                        * There is no way to resolve a short write situation
+                        * for a !Uptodate page (except by double copying in
+                        * the caller done by generic_perform_write_2copy).
+                        *
+                        * Instead, we have to bring it uptodate here.
+                        */
+                       ret = aops->readpage(file, page);
+                       page_cache_release(page);
+                       if (ret) {
+                               if (ret == AOP_TRUNCATED_PAGE)
+                                       goto again;
+                               return ret;
+                       }
+                       goto again;
+               }
+
+               ret = aops->prepare_write(file, page, offset, offset+len);
+               if (ret) {
+                       unlock_page(page);
+                       page_cache_release(page);
+                       if (pos + len > inode->i_size)
+                               vmtruncate(inode, inode->i_size);
+               }
+               return ret;
+       }
+}
+EXPORT_SYMBOL(pagecache_write_begin);
+
+int pagecache_write_end(struct file *file, struct address_space *mapping,
+                               loff_t pos, unsigned len, unsigned copied,
+                               struct page *page, void *fsdata)
+{
+       const struct address_space_operations *aops = mapping->a_ops;
+       int ret;
+
+       if (aops->write_end) {
+               mark_page_accessed(page);
+               ret = aops->write_end(file, mapping, pos, len, copied,
+                                                       page, fsdata);
+       } else {
+               unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+               struct inode *inode = mapping->host;
+
+               flush_dcache_page(page);
+               ret = aops->commit_write(file, page, offset, offset+len);
+               unlock_page(page);
+               mark_page_accessed(page);
+               page_cache_release(page);
+
+               if (ret < 0) {
+                       if (pos + len > inode->i_size)
+                               vmtruncate(inode, inode->i_size);
+               } else if (ret > 0)
+                       ret = min_t(size_t, copied, ret);
+               else
+                       ret = copied;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(pagecache_write_end);
+
 ssize_t
 generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
                unsigned long *nr_segs, loff_t pos, loff_t *ppos,
@@ -1783,8 +1986,7 @@ EXPORT_SYMBOL(generic_file_direct_write);
  * Find or create a page at the given pagecache position. Return the locked
  * page. This function is specifically for buffered writes.
  */
-static struct page *__grab_cache_page(struct address_space *mapping,
-                                                       pgoff_t index)
+struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index)
 {
        int status;
        struct page *page;
@@ -1805,59 +2007,50 @@ repeat:
        }
        return page;
 }
+EXPORT_SYMBOL(__grab_cache_page);
 
-ssize_t
-generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
-               unsigned long nr_segs, loff_t pos, loff_t *ppos,
-               size_t count, ssize_t written)
+static ssize_t generic_perform_write_2copy(struct file *file,
+                               struct iov_iter *i, loff_t pos)
 {
-       struct file *file = iocb->ki_filp;
        struct address_space *mapping = file->f_mapping;
        const struct address_space_operations *a_ops = mapping->a_ops;
-       struct inode    *inode = mapping->host;
-       long            status = 0;
-       const struct iovec *cur_iov = iov; /* current iovec */
-       size_t          iov_offset = 0;    /* offset in the current iovec */
-       char __user     *buf;
-
-       /*
-        * handle partial DIO write.  Adjust cur_iov if needed.
-        */
-       if (likely(nr_segs == 1))
-               buf = iov->iov_base + written;
-       else {
-               filemap_set_next_iovec(&cur_iov, &iov_offset, written);
-               buf = cur_iov->iov_base + iov_offset;
-       }
+       struct inode *inode = mapping->host;
+       long status = 0;
+       ssize_t written = 0;
 
        do {
+               struct page *src_page;
                struct page *page;
                pgoff_t index;          /* Pagecache index for current page */
                unsigned long offset;   /* Offset into pagecache page */
-               unsigned long maxlen;   /* Bytes remaining in current iovec */
-               size_t bytes;           /* Bytes to write to page */
+               unsigned long bytes;    /* Bytes to write to page */
                size_t copied;          /* Bytes copied from user */
 
                offset = (pos & (PAGE_CACHE_SIZE - 1));
                index = pos >> PAGE_CACHE_SHIFT;
-               bytes = PAGE_CACHE_SIZE - offset;
-               if (bytes > count)
-                       bytes = count;
+               bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
+                                               iov_iter_count(i));
 
-               maxlen = cur_iov->iov_len - iov_offset;
-               if (maxlen > bytes)
-                       maxlen = bytes;
+               /*
+                * a non-NULL src_page indicates that we're doing the
+                * copy via get_user_pages and kmap.
+                */
+               src_page = NULL;
 
-#ifndef CONFIG_DEBUG_VM
                /*
                 * Bring in the user page that we will copy from _first_.
                 * Otherwise there's a nasty deadlock on copying from the
                 * same page as we're writing to, without it being marked
                 * up-to-date.
+                *
+                * Not only is this an optimisation, but it is also required
+                * to check that the address is actually valid, when atomic
+                * usercopies are used, below.
                 */
-               fault_in_pages_readable(buf, maxlen);
-#endif
-
+               if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
+                       status = -EFAULT;
+                       break;
+               }
 
                page = __grab_cache_page(mapping, index);
                if (!page) {
@@ -1865,52 +2058,111 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                        break;
                }
 
+               /*
+                * non-uptodate pages cannot cope with short copies, and we
+                * cannot take a pagefault with the destination page locked.
+                * So pin the source page to copy it.
+                */
+               if (!PageUptodate(page) && !segment_eq(get_fs(), KERNEL_DS)) {
+                       unlock_page(page);
+
+                       src_page = alloc_page(GFP_KERNEL);
+                       if (!src_page) {
+                               page_cache_release(page);
+                               status = -ENOMEM;
+                               break;
+                       }
+
+                       /*
+                        * Cannot get_user_pages with a page locked for the
+                        * same reason as we can't take a page fault with a
+                        * page locked (as explained below).
+                        */
+                       copied = iov_iter_copy_from_user(src_page, i,
+                                                               offset, bytes);
+                       if (unlikely(copied == 0)) {
+                               status = -EFAULT;
+                               page_cache_release(page);
+                               page_cache_release(src_page);
+                               break;
+                       }
+                       bytes = copied;
+
+                       lock_page(page);
+                       /*
+                        * Can't handle the page going uptodate here, because
+                        * that means we would use non-atomic usercopies, which
+                        * zero out the tail of the page, which can cause
+                        * zeroes to become transiently visible. We could just
+                        * use a non-zeroing copy, but the APIs aren't too
+                        * consistent.
+                        */
+                       if (unlikely(!page->mapping || PageUptodate(page))) {
+                               unlock_page(page);
+                               page_cache_release(page);
+                               page_cache_release(src_page);
+                               continue;
+                       }
+               }
+
                status = a_ops->prepare_write(file, page, offset, offset+bytes);
                if (unlikely(status))
                        goto fs_write_aop_error;
 
-               if (likely(nr_segs == 1))
-                       copied = filemap_copy_from_user(page, offset,
-                                                       buf, bytes);
-               else
-                       copied = filemap_copy_from_user_iovec(page, offset,
-                                               cur_iov, iov_offset, bytes);
+               if (!src_page) {
+                       /*
+                        * Must not enter the pagefault handler here, because
+                        * we hold the page lock, so we might recursively
+                        * deadlock on the same lock, or get an ABBA deadlock
+                        * against a different lock, or against the mmap_sem
+                        * (which nests outside the page lock).  So increment
+                        * preempt count, and use _atomic usercopies.
+                        *
+                        * The page is uptodate so we are OK to encounter a
+                        * short copy: if unmodified parts of the page are
+                        * marked dirty and written out to disk, it doesn't
+                        * really matter.
+                        */
+                       pagefault_disable();
+                       copied = iov_iter_copy_from_user_atomic(page, i,
+                                                               offset, bytes);
+                       pagefault_enable();
+               } else {
+                       void *src, *dst;
+                       src = kmap_atomic(src_page, KM_USER0);
+                       dst = kmap_atomic(page, KM_USER1);
+                       memcpy(dst + offset, src + offset, bytes);
+                       kunmap_atomic(dst, KM_USER1);
+                       kunmap_atomic(src, KM_USER0);
+                       copied = bytes;
+               }
                flush_dcache_page(page);
+
                status = a_ops->commit_write(file, page, offset, offset+bytes);
-               if (unlikely(status < 0 || status == AOP_TRUNCATED_PAGE))
-                       goto fs_write_aop_error;
-               if (unlikely(copied != bytes)) {
-                       status = -EFAULT;
+               if (unlikely(status < 0))
                        goto fs_write_aop_error;
-               }
                if (unlikely(status > 0)) /* filesystem did partial write */
-                       copied = status;
-
-               if (likely(copied > 0)) {
-                       written += copied;
-                       count -= copied;
-                       pos += copied;
-                       buf += copied;
-                       if (unlikely(nr_segs > 1)) {
-                               filemap_set_next_iovec(&cur_iov,
-                                               &iov_offset, copied);
-                               if (count)
-                                       buf = cur_iov->iov_base + iov_offset;
-                       } else {
-                               iov_offset += copied;
-                       }
-               }
+                       copied = min_t(size_t, copied, status);
+
                unlock_page(page);
                mark_page_accessed(page);
                page_cache_release(page);
+               if (src_page)
+                       page_cache_release(src_page);
+
+               iov_iter_advance(i, copied);
+               pos += copied;
+               written += copied;
+
                balance_dirty_pages_ratelimited(mapping);
                cond_resched();
                continue;
 
 fs_write_aop_error:
-               if (status != AOP_TRUNCATED_PAGE)
-                       unlock_page(page);
+               unlock_page(page);
                page_cache_release(page);
+               if (src_page)
+                       page_cache_release(src_page);
 
                /*
                 * prepare_write() may have instantiated a few blocks
@@ -1919,18 +2171,125 @@ fs_write_aop_error:
                 */
                if (pos + bytes > inode->i_size)
                        vmtruncate(inode, inode->i_size);
-               if (status == AOP_TRUNCATED_PAGE)
-                       continue;
-               else
-                       break;
+               break;
+       } while (iov_iter_count(i));
 
-       } while (count);
-       *ppos = pos;
+       return written ? written : status;
+}
+
+static ssize_t generic_perform_write(struct file *file,
+                               struct iov_iter *i, loff_t pos)
+{
+       struct address_space *mapping = file->f_mapping;
+       const struct address_space_operations *a_ops = mapping->a_ops;
+       long status = 0;
+       ssize_t written = 0;
+       unsigned int flags = 0;
 
        /*
-        * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
+        * Copies from kernel address space cannot fail (NFSD is a big user).
         */
+       if (segment_eq(get_fs(), KERNEL_DS))
+               flags |= AOP_FLAG_UNINTERRUPTIBLE;
+
+       do {
+               struct page *page;
+               pgoff_t index;          /* Pagecache index for current page */
+               unsigned long offset;   /* Offset into pagecache page */
+               unsigned long bytes;    /* Bytes to write to page */
+               size_t copied;          /* Bytes copied from user */
+               void *fsdata;
+
+               offset = (pos & (PAGE_CACHE_SIZE - 1));
+               index = pos >> PAGE_CACHE_SHIFT;
+               bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
+                                               iov_iter_count(i));
+
+again:
+
+               /*
+                * Bring in the user page that we will copy from _first_.
+                * Otherwise there's a nasty deadlock on copying from the
+                * same page as we're writing to, without it being marked
+                * up-to-date.
+                *
+                * Not only is this an optimisation, but it is also required
+                * to check that the address is actually valid, when atomic
+                * usercopies are used, below.
+                */
+               if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
+                       status = -EFAULT;
+                       break;
+               }
+
+               status = a_ops->write_begin(file, mapping, pos, bytes, flags,
+                                               &page, &fsdata);
+               if (unlikely(status))
+                       break;
+
+               pagefault_disable();
+               copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
+               pagefault_enable();
+               flush_dcache_page(page);
+
+               status = a_ops->write_end(file, mapping, pos, bytes, copied,
+                                               page, fsdata);
+               if (unlikely(status < 0))
+                       break;
+               copied = status;
+
+               cond_resched();
+
+               if (unlikely(copied == 0)) {
+                       /*
+                        * If we were unable to copy any data at all, we must
+                        * fall back to a single segment length write.
+                        *
+                        * If we didn't fallback here, we could livelock
+                        * because not all segments in the iov can be copied at
+                        * once without a pagefault.
+                        */
+                       bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
+                                               iov_iter_single_seg_count(i));
+                       goto again;
+               }
+               iov_iter_advance(i, copied);
+               pos += copied;
+               written += copied;
+
+               balance_dirty_pages_ratelimited(mapping);
+
+       } while (iov_iter_count(i));
+
+       return written ? written : status;
+}
+
+ssize_t
+generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
+               unsigned long nr_segs, loff_t pos, loff_t *ppos,
+               size_t count, ssize_t written)
+{
+       struct file *file = iocb->ki_filp;
+       struct address_space *mapping = file->f_mapping;
+       const struct address_space_operations *a_ops = mapping->a_ops;
+       struct inode *inode = mapping->host;
+       ssize_t status;
+       struct iov_iter i;
+
+       iov_iter_init(&i, iov, nr_segs, count, written);
+       if (a_ops->write_begin)
+               status = generic_perform_write(file, &i, pos);
+       else
+               status = generic_perform_write_2copy(file, &i, pos);
+
        if (likely(status >= 0)) {
+               written += status;
+               *ppos = pos + status;
+
+               /*
+                * For now, when the user asks for O_SYNC, we'll actually give
+                * O_DSYNC
+                */
                if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
                        if (!a_ops->writepage || !is_sync_kiocb(iocb))
                                status = generic_osync_inode(inode, mapping,