diff mbox series

ceph: clear inode pointer when snap realm gets dropped by its inode

Message ID 20190110080359.19469-1-zyan@redhat.com (mailing list archive)
State New, archived
Headers show
Series ceph: clear inode pointer when snap realm gets dropped by its inode | expand

Commit Message

Yan, Zheng Jan. 10, 2019, 8:03 a.m. UTC
snap realm and corresponding inode have pointers to each other.
The two pointer should get clear at the same time. Otherwise,
snap realm's pointer may reference freed inode.

Cc: stable@vger.kernel.org #4.17+
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
---
 fs/ceph/caps.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Luis Henriques Jan. 10, 2019, 10:05 a.m. UTC | #1
"Yan, Zheng" <zyan@redhat.com> writes:

> snap realm and corresponding inode have pointers to each other.
> The two pointer should get clear at the same time. Otherwise,
> snap realm's pointer may reference freed inode.
>
> Cc: stable@vger.kernel.org #4.17+
> Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
> ---
>  fs/ceph/caps.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
> index 9a7c999d608b..0eaf1b48c431 100644
> --- a/fs/ceph/caps.c
> +++ b/fs/ceph/caps.c
> @@ -1035,6 +1035,8 @@ static void drop_inode_snap_realm(struct ceph_inode_info *ci)
>  	list_del_init(&ci->i_snap_realm_item);
>  	ci->i_snap_realm_counter++;
>  	ci->i_snap_realm = NULL;
> +	if (realm->ino == ci->i_vino.ino)
> +		realm->inode = NULL;
>  	spin_unlock(&realm->inodes_with_caps_lock);
>  	ceph_put_snap_realm(ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc,
>  			    realm);

Nice catch!

Reviewed-by: Luis Henriques <lhenriques@suse.com>

Cheers,
diff mbox series

Patch

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 9a7c999d608b..0eaf1b48c431 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1035,6 +1035,8 @@  static void drop_inode_snap_realm(struct ceph_inode_info *ci)
 	list_del_init(&ci->i_snap_realm_item);
 	ci->i_snap_realm_counter++;
 	ci->i_snap_realm = NULL;
+	if (realm->ino == ci->i_vino.ino)
+		realm->inode = NULL;
 	spin_unlock(&realm->inodes_with_caps_lock);
 	ceph_put_snap_realm(ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc,
 			    realm);