]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/filemap.c
Merge branch 'akpm-current/current'
[karo-tx-linux.git] / mm / filemap.c
index 03485327fca9c3487830e3111202560170660aca..6414803972f7a1cc04a9eba7d9b8b995379fc39d 100644 (file)
@@ -176,8 +176,7 @@ static void page_cache_tree_delete(struct address_space *mapping,
 /*
  * Delete a page from the page cache and free it. Caller has to make
  * sure the page is locked and that nobody else uses it - or that usage
- * is safe.  The caller must hold the mapping's tree_lock and
- * lock_page_memcg().
+ * is safe.  The caller must hold the mapping's tree_lock.
  */
 void __delete_from_page_cache(struct page *page, void *shadow)
 {
@@ -237,11 +236,9 @@ void delete_from_page_cache(struct page *page)
 
        freepage = mapping->a_ops->freepage;
 
-       lock_page_memcg(page);
        spin_lock_irqsave(&mapping->tree_lock, flags);
        __delete_from_page_cache(page, NULL);
        spin_unlock_irqrestore(&mapping->tree_lock, flags);
-       unlock_page_memcg(page);
 
        if (freepage)
                freepage(page);
@@ -538,7 +535,6 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
                new->mapping = mapping;
                new->index = offset;
 
-               lock_page_memcg(old);
                spin_lock_irqsave(&mapping->tree_lock, flags);
                __delete_from_page_cache(old, NULL);
                error = radix_tree_insert(&mapping->page_tree, offset, new);
@@ -553,7 +549,6 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
                if (PageSwapBacked(new))
                        __inc_zone_page_state(new, NR_SHMEM);
                spin_unlock_irqrestore(&mapping->tree_lock, flags);
-               unlock_page_memcg(old);
                mem_cgroup_migrate(old, new);
                radix_tree_preload_end();
                if (freepage)
@@ -572,7 +567,7 @@ static int page_cache_tree_insert(struct address_space *mapping,
        void **slot;
        int error;
 
-       error = __radix_tree_create(&mapping->page_tree, page->index,
+       error = __radix_tree_create(&mapping->page_tree, page->index, 0,
                                    &node, &slot);
        if (error)
                return error;
@@ -1241,7 +1236,6 @@ unsigned find_get_entries(struct address_space *mapping,
                return 0;
 
        rcu_read_lock();
-restart:
        radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
                struct page *page;
 repeat:
@@ -1249,8 +1243,10 @@ repeat:
                if (unlikely(!page))
                        continue;
                if (radix_tree_exception(page)) {
-                       if (radix_tree_deref_retry(page))
-                               goto restart;
+                       if (radix_tree_deref_retry(page)) {
+                               slot = radix_tree_iter_retry(&iter);
+                               continue;
+                       }
                        /*
                         * A shadow entry of a recently evicted page, a swap
                         * entry from shmem/tmpfs or a DAX entry.  Return it
@@ -1303,7 +1299,6 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
                return 0;
 
        rcu_read_lock();
-restart:
        radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
                struct page *page;
 repeat:
@@ -1313,13 +1308,8 @@ repeat:
 
                if (radix_tree_exception(page)) {
                        if (radix_tree_deref_retry(page)) {
-                               /*
-                                * Transient condition which can only trigger
-                                * when entry at index 0 moves out of or back
-                                * to root: none yet gotten, safe to restart.
-                                */
-                               WARN_ON(iter.index);
-                               goto restart;
+                               slot = radix_tree_iter_retry(&iter);
+                               continue;
                        }
                        /*
                         * A shadow entry of a recently evicted page,
@@ -1370,7 +1360,6 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
                return 0;
 
        rcu_read_lock();
-restart:
        radix_tree_for_each_contig(slot, &mapping->page_tree, &iter, index) {
                struct page *page;
 repeat:
@@ -1381,12 +1370,8 @@ repeat:
 
                if (radix_tree_exception(page)) {
                        if (radix_tree_deref_retry(page)) {
-                               /*
-                                * Transient condition which can only trigger
-                                * when entry at index 0 moves out of or back
-                                * to root: none yet gotten, safe to restart.
-                                */
-                               goto restart;
+                               slot = radix_tree_iter_retry(&iter);
+                               continue;
                        }
                        /*
                         * A shadow entry of a recently evicted page,
@@ -1446,7 +1431,6 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
                return 0;
 
        rcu_read_lock();
-restart:
        radix_tree_for_each_tagged(slot, &mapping->page_tree,
                                   &iter, *index, tag) {
                struct page *page;
@@ -1457,12 +1441,8 @@ repeat:
 
                if (radix_tree_exception(page)) {
                        if (radix_tree_deref_retry(page)) {
-                               /*
-                                * Transient condition which can only trigger
-                                * when entry at index 0 moves out of or back
-                                * to root: none yet gotten, safe to restart.
-                                */
-                               goto restart;
+                               slot = radix_tree_iter_retry(&iter);
+                               continue;
                        }
                        /*
                         * A shadow entry of a recently evicted page.
@@ -1525,7 +1505,6 @@ unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
                return 0;
 
        rcu_read_lock();
-restart:
        radix_tree_for_each_tagged(slot, &mapping->page_tree,
                                   &iter, start, tag) {
                struct page *page;
@@ -1535,12 +1514,8 @@ repeat:
                        continue;
                if (radix_tree_exception(page)) {
                        if (radix_tree_deref_retry(page)) {
-                               /*
-                                * Transient condition which can only trigger
-                                * when entry at index 0 moves out of or back
-                                * to root: none yet gotten, safe to restart.
-                                */
-                               goto restart;
+                               slot = radix_tree_iter_retry(&iter);
+                               continue;
                        }
 
                        /*
@@ -2157,10 +2132,11 @@ repeat:
                if (unlikely(!page))
                        goto next;
                if (radix_tree_exception(page)) {
-                       if (radix_tree_deref_retry(page))
-                               break;
-                       else
-                               goto next;
+                       if (radix_tree_deref_retry(page)) {
+                               slot = radix_tree_iter_retry(&iter);
+                               continue;
+                       }
+                       goto next;
                }
 
                if (!page_cache_get_speculative(page))
@@ -2451,7 +2427,7 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from)
 
        if (limit != RLIM_INFINITY) {
                if (iocb->ki_pos >= limit) {
-                       send_sig(SIGXFSZ, current, 0);
+                       io_send_sig(SIGXFSZ);
                        return -EFBIG;
                }
                iov_iter_truncate(from, limit - (unsigned long)pos);
@@ -2462,8 +2438,10 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from)
         */
        if (unlikely(pos + iov_iter_count(from) > MAX_NON_LFS &&
                                !(file->f_flags & O_LARGEFILE))) {
-               if (pos >= MAX_NON_LFS)
+               if (pos >= MAX_NON_LFS) {
+                       io_send_sig(SIGXFSZ);
                        return -EFBIG;
+               }
                iov_iter_truncate(from, MAX_NON_LFS - (unsigned long)pos);
        }