diff options
author | Yan, Zheng <zyan@redhat.com> | 2019-05-22 22:45:24 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-07-08 08:01:42 -0400 |
commit | 8f2a98ef3c1adf815ce38d5cc2f4e2a8759e98c5 (patch) | |
tree | 3503675c14c828cd02b30c399a3399405dd333d0 /fs/ceph | |
parent | 41883ba8ee91af979f4a02b5b0c78647ae82a80b (diff) |
ceph: ensure d_name/d_parent stability in ceph_mdsc_lease_send_msg()
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/dir.c | 7 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 24 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 1 |
3 files changed, 16 insertions, 16 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 1271024a3797..72efad28857c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1433,8 +1433,7 @@ static bool __dentry_lease_is_valid(struct ceph_dentry_info *di) | |||
1433 | return false; | 1433 | return false; |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | static int dentry_lease_is_valid(struct dentry *dentry, unsigned int flags, | 1436 | static int dentry_lease_is_valid(struct dentry *dentry, unsigned int flags) |
1437 | struct inode *dir) | ||
1438 | { | 1437 | { |
1439 | struct ceph_dentry_info *di; | 1438 | struct ceph_dentry_info *di; |
1440 | struct ceph_mds_session *session = NULL; | 1439 | struct ceph_mds_session *session = NULL; |
@@ -1466,7 +1465,7 @@ static int dentry_lease_is_valid(struct dentry *dentry, unsigned int flags, | |||
1466 | spin_unlock(&dentry->d_lock); | 1465 | spin_unlock(&dentry->d_lock); |
1467 | 1466 | ||
1468 | if (session) { | 1467 | if (session) { |
1469 | ceph_mdsc_lease_send_msg(session, dir, dentry, | 1468 | ceph_mdsc_lease_send_msg(session, dentry, |
1470 | CEPH_MDS_LEASE_RENEW, seq); | 1469 | CEPH_MDS_LEASE_RENEW, seq); |
1471 | ceph_put_mds_session(session); | 1470 | ceph_put_mds_session(session); |
1472 | } | 1471 | } |
@@ -1566,7 +1565,7 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
1566 | ceph_snap(d_inode(dentry)) == CEPH_SNAPDIR) { | 1565 | ceph_snap(d_inode(dentry)) == CEPH_SNAPDIR) { |
1567 | valid = 1; | 1566 | valid = 1; |
1568 | } else { | 1567 | } else { |
1569 | valid = dentry_lease_is_valid(dentry, flags, dir); | 1568 | valid = dentry_lease_is_valid(dentry, flags); |
1570 | if (valid == -ECHILD) | 1569 | if (valid == -ECHILD) |
1571 | return valid; | 1570 | return valid; |
1572 | if (valid || dir_lease_is_valid(dir, dentry)) { | 1571 | if (valid || dir_lease_is_valid(dir, dentry)) { |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 88bc68ddd313..709ac3bde86e 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -3941,31 +3941,33 @@ bad: | |||
3941 | } | 3941 | } |
3942 | 3942 | ||
3943 | void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, | 3943 | void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, |
3944 | struct inode *inode, | ||
3945 | struct dentry *dentry, char action, | 3944 | struct dentry *dentry, char action, |
3946 | u32 seq) | 3945 | u32 seq) |
3947 | { | 3946 | { |
3948 | struct ceph_msg *msg; | 3947 | struct ceph_msg *msg; |
3949 | struct ceph_mds_lease *lease; | 3948 | struct ceph_mds_lease *lease; |
3950 | int len = sizeof(*lease) + sizeof(u32); | 3949 | struct inode *dir; |
3951 | int dnamelen = 0; | 3950 | int len = sizeof(*lease) + sizeof(u32) + NAME_MAX; |
3952 | 3951 | ||
3953 | dout("lease_send_msg inode %p dentry %p %s to mds%d\n", | 3952 | dout("lease_send_msg identry %p %s to mds%d\n", |
3954 | inode, dentry, ceph_lease_op_name(action), session->s_mds); | 3953 | dentry, ceph_lease_op_name(action), session->s_mds); |
3955 | dnamelen = dentry->d_name.len; | ||
3956 | len += dnamelen; | ||
3957 | 3954 | ||
3958 | msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS, false); | 3955 | msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS, false); |
3959 | if (!msg) | 3956 | if (!msg) |
3960 | return; | 3957 | return; |
3961 | lease = msg->front.iov_base; | 3958 | lease = msg->front.iov_base; |
3962 | lease->action = action; | 3959 | lease->action = action; |
3963 | lease->ino = cpu_to_le64(ceph_vino(inode).ino); | ||
3964 | lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap); | ||
3965 | lease->seq = cpu_to_le32(seq); | 3960 | lease->seq = cpu_to_le32(seq); |
3966 | put_unaligned_le32(dnamelen, lease + 1); | ||
3967 | memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen); | ||
3968 | 3961 | ||
3962 | spin_lock(&dentry->d_lock); | ||
3963 | dir = d_inode(dentry->d_parent); | ||
3964 | lease->ino = cpu_to_le64(ceph_ino(dir)); | ||
3965 | lease->first = lease->last = cpu_to_le64(ceph_snap(dir)); | ||
3966 | |||
3967 | put_unaligned_le32(dentry->d_name.len, lease + 1); | ||
3968 | memcpy((void *)(lease + 1) + 4, | ||
3969 | dentry->d_name.name, dentry->d_name.len); | ||
3970 | spin_unlock(&dentry->d_lock); | ||
3969 | /* | 3971 | /* |
3970 | * if this is a preemptive lease RELEASE, no need to | 3972 | * if this is a preemptive lease RELEASE, no need to |
3971 | * flush request stream, since the actual request will | 3973 | * flush request stream, since the actual request will |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 9c28b86abcf4..330769ecb601 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -505,7 +505,6 @@ extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, | |||
505 | 505 | ||
506 | extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry); | 506 | extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry); |
507 | extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, | 507 | extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, |
508 | struct inode *inode, | ||
509 | struct dentry *dentry, char action, | 508 | struct dentry *dentry, char action, |
510 | u32 seq); | 509 | u32 seq); |
511 | 510 | ||