xfs: improve mapping type check in xfs_vm_writepage
authorChristoph Hellwig <hch@infradead.org>
Fri, 10 Dec 2010 08:42:16 +0000 (08:42 +0000)
committerAlex Elder <aelder@sgi.com>
Thu, 16 Dec 2010 22:05:34 +0000 (16:05 -0600)
Currently we only refuse a "read-only" mapping for writing out
unwritten and delayed buffers, and refuse any other for overwrites.
Improve the checks to require delalloc mappings for delayed buffers,
and unwritten extent mappings for unwritten extents.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
fs/xfs/linux-2.6/xfs_aops.c

index 691f61223ed628137bfeb2ed2856a3ccbcf71894..23a7668e07dacafbb799a1fad94f807acf534963 100644 (file)
@@ -1082,17 +1082,17 @@ xfs_vm_writepage(
                if (buffer_unwritten(bh) || buffer_delay(bh)) {
                        int new_ioend = 0;
 
-                       /*
-                        * Make sure we don't use a read-only iomap
-                        */
-                       if (flags == BMAPI_READ)
-                               imap_valid = 0;
-
                        if (buffer_unwritten(bh)) {
-                               type = IO_UNWRITTEN;
+                               if (type != IO_UNWRITTEN) {
+                                       type = IO_UNWRITTEN;
+                                       imap_valid = 0;
+                               }
                                flags = BMAPI_WRITE | BMAPI_IGNSTATE;
                        } else if (buffer_delay(bh)) {
-                               type = IO_DELAY;
+                               if (type != IO_DELAY) {
+                                       type = IO_DELAY;
+                                       imap_valid = 0;
+                               }
                                flags = BMAPI_ALLOCATE;
 
                                if (wbc->sync_mode == WB_SYNC_NONE)
@@ -1128,8 +1128,11 @@ xfs_vm_writepage(
                         * That means it must already have extents allocated
                         * underneath it. Map the extent by reading it.
                         */
-                       if (!imap_valid || flags != BMAPI_READ) {
+                       if (flags != BMAPI_READ) {
                                flags = BMAPI_READ;
+                               imap_valid = 0;
+                       }
+                       if (!imap_valid) {
                                size = xfs_probe_cluster(inode, page, bh, head);
                                err = xfs_map_blocks(inode, offset, size,
                                                &imap, flags);