diff options
| -rw-r--r-- | fs/ceph/inode.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 2d61ddda9bf5..c2feb310ac1e 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
| @@ -1163,6 +1163,19 @@ static int splice_dentry(struct dentry **pdn, struct inode *in) | |||
| 1163 | return 0; | 1163 | return 0; |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| 1166 | static int d_name_cmp(struct dentry *dentry, const char *name, size_t len) | ||
| 1167 | { | ||
| 1168 | int ret; | ||
| 1169 | |||
| 1170 | /* take d_lock to ensure dentry->d_name stability */ | ||
| 1171 | spin_lock(&dentry->d_lock); | ||
| 1172 | ret = dentry->d_name.len - len; | ||
| 1173 | if (!ret) | ||
| 1174 | ret = memcmp(dentry->d_name.name, name, len); | ||
| 1175 | spin_unlock(&dentry->d_lock); | ||
| 1176 | return ret; | ||
| 1177 | } | ||
| 1178 | |||
| 1166 | /* | 1179 | /* |
| 1167 | * Incorporate results into the local cache. This is either just | 1180 | * Incorporate results into the local cache. This is either just |
| 1168 | * one inode, or a directory, dentry, and possibly linked-to inode (e.g., | 1181 | * one inode, or a directory, dentry, and possibly linked-to inode (e.g., |
| @@ -1412,7 +1425,8 @@ retry_lookup: | |||
| 1412 | err = splice_dentry(&req->r_dentry, in); | 1425 | err = splice_dentry(&req->r_dentry, in); |
| 1413 | if (err < 0) | 1426 | if (err < 0) |
| 1414 | goto done; | 1427 | goto done; |
| 1415 | } else if (rinfo->head->is_dentry) { | 1428 | } else if (rinfo->head->is_dentry && |
| 1429 | !d_name_cmp(req->r_dentry, rinfo->dname, rinfo->dname_len)) { | ||
| 1416 | struct ceph_vino *ptvino = NULL; | 1430 | struct ceph_vino *ptvino = NULL; |
| 1417 | 1431 | ||
| 1418 | if ((le32_to_cpu(rinfo->diri.in->cap.caps) & CEPH_CAP_FILE_SHARED) || | 1432 | if ((le32_to_cpu(rinfo->diri.in->cap.caps) & CEPH_CAP_FILE_SHARED) || |
