Merge tag 'v5.4-rc8' into WIP.x86/mm, to pick up fixes
[linux-2.6-microblaze.git] / fs / ceph / addr.c
index b3c8b88..7ab6166 100644 (file)
@@ -189,8 +189,7 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
 {
        struct inode *inode = file_inode(filp);
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_osd_client *osdc =
-               &ceph_inode_to_client(inode)->client->osdc;
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        int err = 0;
        u64 off = page_offset(page);
        u64 len = PAGE_SIZE;
@@ -219,8 +218,8 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
 
        dout("readpage inode %p file %p page %p index %lu\n",
             inode, filp, page, page->index);
-       err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
-                                 off, &len,
+       err = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode),
+                                 &ci->i_layout, off, &len,
                                  ci->i_truncate_seq, ci->i_truncate_size,
                                  &page, 1, 0);
        if (err == -ENOENT)
@@ -228,6 +227,8 @@ static int ceph_do_readpage(struct file *filp, struct page *page)
        if (err < 0) {
                SetPageError(page);
                ceph_fscache_readpage_cancel(inode, page);
+               if (err == -EBLACKLISTED)
+                       fsc->blacklisted = true;
                goto out;
        }
        if (err < PAGE_SIZE)
@@ -266,6 +267,8 @@ static void finish_read(struct ceph_osd_request *req)
        int i;
 
        dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes);
+       if (rc == -EBLACKLISTED)
+               ceph_inode_to_client(inode)->blacklisted = true;
 
        /* unlock all pages, zeroing any data we didn't read */
        osd_data = osd_req_op_extent_osd_data(req, 0);
@@ -323,7 +326,8 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
                /* caller of readpages does not hold buffer and read caps
                 * (fadvise, madvise and readahead cases) */
                int want = CEPH_CAP_FILE_CACHE;
-               ret = ceph_try_get_caps(ci, CEPH_CAP_FILE_RD, want, true, &got);
+               ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want,
+                                       true, &got);
                if (ret < 0) {
                        dout("start_read %p, error getting cap\n", inode);
                } else if (!(got & want)) {
@@ -569,7 +573,7 @@ static u64 get_writepages_data_length(struct inode *inode,
 /*
  * Write a single page, but leave the page locked.
  *
- * If we get a write error, set the page error bit, but still adjust the
+ * If we get a write error, mark the mapping for error, but still adjust the
  * dirty page accounting (i.e., page is no longer dirty).
  */
 static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
@@ -640,9 +644,10 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
                        end_page_writeback(page);
                        return err;
                }
+               if (err == -EBLACKLISTED)
+                       fsc->blacklisted = true;
                dout("writepage setting page/mapping error %d %p\n",
                     err, page);
-               SetPageError(page);
                mapping_set_error(&inode->i_data, err);
                wbc->pages_skipped++;
        } else {
@@ -679,23 +684,6 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc)
        return err;
 }
 
-/*
- * lame release_pages helper.  release_pages() isn't exported to
- * modules.
- */
-static void ceph_release_pages(struct page **pages, int num)
-{
-       struct pagevec pvec;
-       int i;
-
-       pagevec_init(&pvec);
-       for (i = 0; i < num; i++) {
-               if (pagevec_add(&pvec, pages[i]) == 0)
-                       pagevec_release(&pvec);
-       }
-       pagevec_release(&pvec);
-}
-
 /*
  * async writeback completion handler.
  *
@@ -720,6 +708,8 @@ static void writepages_finish(struct ceph_osd_request *req)
        if (rc < 0) {
                mapping_set_error(mapping, rc);
                ceph_set_error_write(ci);
+               if (rc == -EBLACKLISTED)
+                       fsc->blacklisted = true;
        } else {
                ceph_clear_error_write(ci);
        }
@@ -769,7 +759,7 @@ static void writepages_finish(struct ceph_osd_request *req)
                dout("writepages_finish %p wrote %llu bytes cleaned %d pages\n",
                     inode, osd_data->length, rc >= 0 ? num_pages : 0);
 
-               ceph_release_pages(osd_data->pages, num_pages);
+               release_pages(osd_data->pages, num_pages);
        }
 
        ceph_put_wrbuffer_cap_refs(ci, total_pages, snapc);
@@ -1452,7 +1442,8 @@ static vm_fault_t ceph_filemap_fault(struct vm_fault *vmf)
                want = CEPH_CAP_FILE_CACHE;
 
        got = 0;
-       err = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, -1, &got, &pinned_page);
+       err = ceph_get_caps(vma->vm_file, CEPH_CAP_FILE_RD, want, -1,
+                           &got, &pinned_page);
        if (err < 0)
                goto out_restore;
 
@@ -1540,6 +1531,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
        if (!prealloc_cf)
                return VM_FAULT_OOM;
 
+       sb_start_pagefault(inode->i_sb);
        ceph_block_sigs(&oldset);
 
        if (ci->i_inline_version != CEPH_INLINE_NONE) {
@@ -1568,7 +1560,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
                want = CEPH_CAP_FILE_BUFFER;
 
        got = 0;
-       err = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, off + len,
+       err = ceph_get_caps(vma->vm_file, CEPH_CAP_FILE_WR, want, off + len,
                            &got, NULL);
        if (err < 0)
                goto out_free;
@@ -1614,6 +1606,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
        ceph_put_cap_refs(ci, got);
 out_free:
        ceph_restore_sigs(&oldset);
+       sb_end_pagefault(inode->i_sb);
        ceph_free_cap_flush(prealloc_cf);
        if (err < 0)
                ret = vmf_error(err);
@@ -1946,12 +1939,17 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci,
 
        if (err >= 0 || err == -ENOENT)
                have |= POOL_READ;
-       else if (err != -EPERM)
+       else if (err != -EPERM) {
+               if (err == -EBLACKLISTED)
+                       fsc->blacklisted = true;
                goto out_unlock;
+       }
 
        if (err2 == 0 || err2 == -EEXIST)
                have |= POOL_WRITE;
        else if (err2 != -EPERM) {
+               if (err2 == -EBLACKLISTED)
+                       fsc->blacklisted = true;
                err = err2;
                goto out_unlock;
        }
@@ -1989,10 +1987,11 @@ out:
        return err;
 }
 
-int ceph_pool_perm_check(struct ceph_inode_info *ci, int need)
+int ceph_pool_perm_check(struct inode *inode, int need)
 {
-       s64 pool;
+       struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_string *pool_ns;
+       s64 pool;
        int ret, flags;
 
        if (ci->i_vino.snap != CEPH_NOSNAP) {
@@ -2004,7 +2003,7 @@ int ceph_pool_perm_check(struct ceph_inode_info *ci, int need)
                return 0;
        }
 
-       if (ceph_test_mount_opt(ceph_inode_to_client(&ci->vfs_inode),
+       if (ceph_test_mount_opt(ceph_inode_to_client(inode),
                                NOPOOLPERM))
                return 0;