ceph: fetch inline data when getting Fcr cap refs
we can't use getattr to fetch inline data after getting Fcr caps, because it can cause deadlock. The solution is try bringing inline data to page cache when not holding any cap, and hope the inline data page is still there after getting the Fcr caps. If the page is still there, pin it in page cache for later IO. Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
@@ -1207,6 +1207,7 @@ static int ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
struct inode *inode = file_inode(vma->vm_file);
|
||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||
struct ceph_file_info *fi = vma->vm_file->private_data;
|
||||
struct page *pinned_page = NULL;
|
||||
loff_t off = vmf->pgoff << PAGE_CACHE_SHIFT;
|
||||
int want, got, ret;
|
||||
|
||||
@@ -1218,7 +1219,8 @@ static int ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
want = CEPH_CAP_FILE_CACHE;
|
||||
while (1) {
|
||||
got = 0;
|
||||
ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, &got, -1);
|
||||
ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, -1,
|
||||
&got, &pinned_page);
|
||||
if (ret == 0)
|
||||
break;
|
||||
if (ret != -ERESTARTSYS) {
|
||||
@@ -1233,6 +1235,8 @@ static int ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
|
||||
dout("filemap_fault %p %llu~%zd dropping cap refs on %s ret %d\n",
|
||||
inode, off, (size_t)PAGE_CACHE_SIZE, ceph_cap_string(got), ret);
|
||||
if (pinned_page)
|
||||
page_cache_release(pinned_page);
|
||||
ceph_put_cap_refs(ci, got);
|
||||
|
||||
return ret;
|
||||
@@ -1266,7 +1270,8 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
want = CEPH_CAP_FILE_BUFFER;
|
||||
while (1) {
|
||||
got = 0;
|
||||
ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, off + len);
|
||||
ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, off + len,
|
||||
&got, NULL);
|
||||
if (ret == 0)
|
||||
break;
|
||||
if (ret != -ERESTARTSYS) {
|
||||
|
||||
Reference in New Issue
Block a user