ceph: make write_begin wait propagate ERESTARTSYS
authorSage Weil <sage@newdream.net>
Fri, 19 Mar 2010 20:27:53 +0000 (13:27 -0700)
committerSage Weil <sage@newdream.net>
Tue, 23 Mar 2010 14:47:03 +0000 (07:47 -0700)
Currently, if the wait_event_interruptible is interrupted, we
return EAGAIN unconditionally and loop, such that we aren't, in
fact, interruptible.  So, propagate ERESTARTSYS if we get it.

Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/addr.c

index 23bb0ce..ce8ef61 100644 (file)
@@ -919,6 +919,10 @@ static int context_is_writeable_or_written(struct inode *inode,
 /*
  * We are only allowed to write into/dirty the page if the page is
  * clean, or already dirty within the same snap context.
+ *
+ * called with page locked.
+ * return success with page locked,
+ * or any failure (incl -EAGAIN) with page unlocked.
  */
 static int ceph_update_writeable_page(struct file *file,
                            loff_t pos, unsigned len,
@@ -961,9 +965,11 @@ retry_locked:
                        snapc = ceph_get_snap_context((void *)page->private);
                        unlock_page(page);
                        ceph_queue_writeback(inode);
-                       wait_event_interruptible(ci->i_cap_wq,
+                       r = wait_event_interruptible(ci->i_cap_wq,
                               context_is_writeable_or_written(inode, snapc));
                        ceph_put_snap_context(snapc);
+                       if (r == -ERESTARTSYS)
+                               return r;
                        return -EAGAIN;
                }
 
@@ -1035,7 +1041,7 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
        int r;
 
        do {
-               /* get a page*/
+               /* get a page */
                page = grab_cache_page_write_begin(mapping, index, 0);
                if (!page)
                        return -ENOMEM;