aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r--fs/ceph/inode.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 66edef12c6f2..8b136dc0bc13 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1389,7 +1389,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
1389 struct qstr dname; 1389 struct qstr dname;
1390 struct dentry *dn; 1390 struct dentry *dn;
1391 struct inode *in; 1391 struct inode *in;
1392 int err = 0, ret, i; 1392 int err = 0, skipped = 0, ret, i;
1393 struct inode *snapdir = NULL; 1393 struct inode *snapdir = NULL;
1394 struct ceph_mds_request_head *rhead = req->r_request->front.iov_base; 1394 struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
1395 struct ceph_dentry_info *di; 1395 struct ceph_dentry_info *di;
@@ -1501,7 +1501,17 @@ retry_lookup:
1501 } 1501 }
1502 1502
1503 if (d_really_is_negative(dn)) { 1503 if (d_really_is_negative(dn)) {
1504 struct dentry *realdn = splice_dentry(dn, in); 1504 struct dentry *realdn;
1505
1506 if (ceph_security_xattr_deadlock(in)) {
1507 dout(" skip splicing dn %p to inode %p"
1508 " (security xattr deadlock)\n", dn, in);
1509 iput(in);
1510 skipped++;
1511 goto next_item;
1512 }
1513
1514 realdn = splice_dentry(dn, in);
1505 if (IS_ERR(realdn)) { 1515 if (IS_ERR(realdn)) {
1506 err = PTR_ERR(realdn); 1516 err = PTR_ERR(realdn);
1507 d_drop(dn); 1517 d_drop(dn);
@@ -1518,7 +1528,7 @@ retry_lookup:
1518 req->r_session, 1528 req->r_session,
1519 req->r_request_started); 1529 req->r_request_started);
1520 1530
1521 if (err == 0 && cache_ctl.index >= 0) { 1531 if (err == 0 && skipped == 0 && cache_ctl.index >= 0) {
1522 ret = fill_readdir_cache(d_inode(parent), dn, 1532 ret = fill_readdir_cache(d_inode(parent), dn,
1523 &cache_ctl, req); 1533 &cache_ctl, req);
1524 if (ret < 0) 1534 if (ret < 0)
@@ -1529,7 +1539,7 @@ next_item:
1529 dput(dn); 1539 dput(dn);
1530 } 1540 }
1531out: 1541out:
1532 if (err == 0) { 1542 if (err == 0 && skipped == 0) {
1533 req->r_did_prepopulate = true; 1543 req->r_did_prepopulate = true;
1534 req->r_readdir_cache_idx = cache_ctl.index; 1544 req->r_readdir_cache_idx = cache_ctl.index;
1535 } 1545 }