diff options
author | Yan, Zheng <zyan@redhat.com> | 2017-10-10 05:06:25 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2017-11-13 06:11:29 -0500 |
commit | 933ad2c9c8bbb1623c2d3c5753ad340152e15d9d (patch) | |
tree | 2cb624291e7d4d97dea691b39e0d094fab3c94ee | |
parent | 7271efa79f8bc01694d1a9fce597088a97b3b160 (diff) |
ceph: disable cached readdir after dropping positive dentry
Ideally CEPH_CAP_FILE_SHARED should have been revoked before
postive dentry get dropped. But if something goes wrong, later
cached readdir may dereference the dropped dentry.
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r-- | fs/ceph/inode.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 6301bf299b7c..16d8b9dac649 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -1186,6 +1186,7 @@ retry_lookup: | |||
1186 | ceph_snap(d_inode(dn)) != tvino.snap)) { | 1186 | ceph_snap(d_inode(dn)) != tvino.snap)) { |
1187 | dout(" dn %p points to wrong inode %p\n", | 1187 | dout(" dn %p points to wrong inode %p\n", |
1188 | dn, d_inode(dn)); | 1188 | dn, d_inode(dn)); |
1189 | ceph_dir_clear_ordered(dir); | ||
1189 | d_delete(dn); | 1190 | d_delete(dn); |
1190 | dput(dn); | 1191 | dput(dn); |
1191 | goto retry_lookup; | 1192 | goto retry_lookup; |
@@ -1323,6 +1324,7 @@ retry_lookup: | |||
1323 | dout(" %p links to %p %llx.%llx, not %llx.%llx\n", | 1324 | dout(" %p links to %p %llx.%llx, not %llx.%llx\n", |
1324 | dn, d_inode(dn), ceph_vinop(d_inode(dn)), | 1325 | dn, d_inode(dn), ceph_vinop(d_inode(dn)), |
1325 | ceph_vinop(in)); | 1326 | ceph_vinop(in)); |
1327 | ceph_dir_clear_ordered(dir); | ||
1326 | d_invalidate(dn); | 1328 | d_invalidate(dn); |
1327 | have_lease = false; | 1329 | have_lease = false; |
1328 | } | 1330 | } |
@@ -1574,6 +1576,7 @@ retry_lookup: | |||
1574 | ceph_snap(d_inode(dn)) != tvino.snap)) { | 1576 | ceph_snap(d_inode(dn)) != tvino.snap)) { |
1575 | dout(" dn %p points to wrong inode %p\n", | 1577 | dout(" dn %p points to wrong inode %p\n", |
1576 | dn, d_inode(dn)); | 1578 | dn, d_inode(dn)); |
1579 | __ceph_dir_clear_ordered(ci); | ||
1577 | d_delete(dn); | 1580 | d_delete(dn); |
1578 | dput(dn); | 1581 | dput(dn); |
1579 | goto retry_lookup; | 1582 | goto retry_lookup; |
@@ -1598,7 +1601,9 @@ retry_lookup: | |||
1598 | &req->r_caps_reservation); | 1601 | &req->r_caps_reservation); |
1599 | if (ret < 0) { | 1602 | if (ret < 0) { |
1600 | pr_err("fill_inode badness on %p\n", in); | 1603 | pr_err("fill_inode badness on %p\n", in); |
1601 | if (d_really_is_negative(dn)) | 1604 | if (d_really_is_positive(dn)) |
1605 | __ceph_dir_clear_ordered(ci); | ||
1606 | else | ||
1602 | iput(in); | 1607 | iput(in); |
1603 | d_drop(dn); | 1608 | d_drop(dn); |
1604 | err = ret; | 1609 | err = ret; |