]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
mm: remove optimizations based on i_size in mapping writeback waits
authorJeff Layton <jlayton@redhat.com>
Mon, 31 Jul 2017 14:29:38 +0000 (10:29 -0400)
committerJeff Layton <jlayton@redhat.com>
Tue, 1 Aug 2017 12:39:29 +0000 (08:39 -0400)
Marcelo added this i_size based optimization with a patch in 2004
(commitid is from the linux-history tree):

    commit 765dad09b4ac101a32d87af2bb793c3060497d3c
    Author: Marcelo Tosatti <marcelo.tosatti@cyclades.com>
    Date:   Tue Sep 7 17:51:17 2004 -0700

small wait_on_page_writeback_range() optimization

filemap_fdatawait() calls wait_on_page_writeback_range() with -1
as "end" parameter.  This is not needed since we know the EOF
from the inode.  Use that instead.

There may be races here, particularly with clustered or network
filesystems. It also seems like a bit of a layering violation since
we're operating on an address_space here, not an inode.

Finally, it's also questionable whether this optimization really helps
on workloads that we care about. Should we be optimizing for writeback
vs. truncate races in a codepath where we expect to wait anyway? It
doesn't seem worth the risk.

Remove this optimization from the filemap_fdatawait codepaths. This
means that filemap_fdatawait becomes a trivial wrapper around
filemap_fdatawait_range.

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
include/linux/fs.h
mm/filemap.c

index af592ca3d509654f1fe559f8198ad43e7290704d..909210bd63665a0ac2e71dee09d8495184072c08 100644 (file)
@@ -2538,10 +2538,15 @@ extern int invalidate_inode_pages2_range(struct address_space *mapping,
 extern int write_inode_now(struct inode *, int);
 extern int filemap_fdatawrite(struct address_space *);
 extern int filemap_flush(struct address_space *);
-extern int filemap_fdatawait(struct address_space *);
 extern int filemap_fdatawait_keep_errors(struct address_space *mapping);
 extern int filemap_fdatawait_range(struct address_space *, loff_t lstart,
                                   loff_t lend);
+
+static inline int filemap_fdatawait(struct address_space *mapping)
+{
+       return filemap_fdatawait_range(mapping, 0, LLONG_MAX);
+}
+
 extern bool filemap_range_has_page(struct address_space *, loff_t lstart,
                                  loff_t lend);
 extern int __must_check file_fdatawait_range(struct file *file, loff_t lstart,
index 394bb5e96f87eb091437b5ce6d3e2315d529cc1d..85dfe3bee324a6c89c1d60b28bab5e7f11662935 100644 (file)
@@ -512,39 +512,11 @@ EXPORT_SYMBOL(file_fdatawait_range);
  */
 int filemap_fdatawait_keep_errors(struct address_space *mapping)
 {
-       loff_t i_size = i_size_read(mapping->host);
-
-       if (i_size == 0)
-               return 0;
-
-       __filemap_fdatawait_range(mapping, 0, i_size - 1);
+       __filemap_fdatawait_range(mapping, 0, LLONG_MAX);
        return filemap_check_and_keep_errors(mapping);
 }
 EXPORT_SYMBOL(filemap_fdatawait_keep_errors);
 
-/**
- * filemap_fdatawait - wait for all under-writeback pages to complete
- * @mapping: address space structure to wait for
- *
- * Walk the list of under-writeback pages of the given address space
- * and wait for all of them.  Check error status of the address space
- * and return it.
- *
- * Since the error status of the address space is cleared by this function,
- * callers are responsible for checking the return value and handling and/or
- * reporting the error.
- */
-int filemap_fdatawait(struct address_space *mapping)
-{
-       loff_t i_size = i_size_read(mapping->host);
-
-       if (i_size == 0)
-               return 0;
-
-       return filemap_fdatawait_range(mapping, 0, i_size - 1);
-}
-EXPORT_SYMBOL(filemap_fdatawait);
-
 static bool mapping_needs_writeback(struct address_space *mapping)
 {
        return (!dax_mapping(mapping) && mapping->nrpages) ||