ext4: fix the deadlock in mpage_da_map_and_submit()
authorKazuya Mio <k-mio@sx.jp.nec.com>
Thu, 20 Oct 2011 23:23:08 +0000 (19:23 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 20 Oct 2011 23:23:08 +0000 (19:23 -0400)
If ext4_jbd2_file_inode() in mpage_da_map_and_submit() fails due to
journal abort, this function returns to caller without unlocking the
page.  It leads to the deadlock, and the patch fixes this issue by
calling mpage_da_submit_io().

Signed-off-by: Kazuya Mio <k-mio@sx.jp.nec.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/inode.c

index ecb5725..ff6aace 100644 (file)
@@ -1552,9 +1552,11 @@ static void mpage_da_map_and_submit(struct mpage_da_data *mpd)
 
                if (ext4_should_order_data(mpd->inode)) {
                        err = ext4_jbd2_file_inode(handle, mpd->inode);
-                       if (err)
+                       if (err) {
                                /* Only if the journal is aborted */
-                               return;
+                               mpd->retval = err;
+                               goto submit_io;
+                       }
                }
        }
 
@@ -2294,11 +2296,12 @@ retry:
                        ret = 0;
                } else if (ret == MPAGE_DA_EXTENT_TAIL) {
                        /*
-                        * got one extent now try with
-                        * rest of the pages
+                        * Got one extent now try with rest of the pages.
+                        * If mpd.retval is set -EIO, journal is aborted.
+                        * So we don't need to write any more.
                         */
                        pages_written += mpd.pages_written;
-                       ret = 0;
+                       ret = mpd.retval;
                        io_done = 1;
                } else if (wbc->nr_to_write)
                        /*