ceph: handle -EAGAIN returned by ceph_update_writeable_page()
authorYan, Zheng <zyan@redhat.com>
Tue, 10 May 2016 11:09:06 +0000 (19:09 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 25 May 2016 23:15:40 +0000 (01:15 +0200)
when ceph_update_writeable_page() return -EAGAIN, caller should
lock the page and call ceph_update_writeable_page() again.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/addr.c

index d128bb65746d7cf784af46646531fb9881829c25..97ee5d1fbb61fc67433d2338f1041622d0e75d8d 100644 (file)
@@ -1475,21 +1475,23 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        /* Update time before taking page lock */
        file_update_time(vma->vm_file);
 
-       lock_page(page);
+       do {
+               lock_page(page);
 
-       if ((off > size) || (page->mapping != inode->i_mapping)) {
-               unlock_page(page);
-               ret = VM_FAULT_NOPAGE;
-               goto out;
-       }
+               if ((off > size) || (page->mapping != inode->i_mapping)) {
+                       unlock_page(page);
+                       ret = VM_FAULT_NOPAGE;
+                       break;
+               }
+
+               ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
+               if (ret >= 0) {
+                       /* success.  we'll keep the page locked. */
+                       set_page_dirty(page);
+                       ret = VM_FAULT_LOCKED;
+               }
+       } while (ret == -EAGAIN);
 
-       ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
-       if (ret >= 0) {
-               /* success.  we'll keep the page locked. */
-               set_page_dirty(page);
-               ret = VM_FAULT_LOCKED;
-       }
-out:
        if (ret == VM_FAULT_LOCKED ||
            ci->i_inline_version != CEPH_INLINE_NONE) {
                int dirty;