]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ceph: fix memory leak in ceph_readdir when note_last_dentry returns error
authorXiubo Li <xiubli@redhat.com>
Sat, 5 Mar 2022 11:52:59 +0000 (19:52 +0800)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 27 Apr 2022 09:59:22 +0000 (11:59 +0200)
BugLink: https://bugs.launchpad.net/bugs/1969107
[ Upstream commit f639d9867eea647005dc824e0e24f39ffc50d4e4 ]

Reset the last_readdir at the same time, and add a comment explaining
why we don't free last_readdir when dir_emit returns false.

Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit 2fe82d3254029ef9ec4e7be890125d5ef4f537de)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
fs/ceph/dir.c

index 133dbd9338e7304e40cda2a86ffca10a9905d3a9..d91fa53e12b33a89b728f66b55f98345a9d60ea1 100644 (file)
@@ -478,8 +478,11 @@ more:
                                        2 : (fpos_off(rde->offset) + 1);
                        err = note_last_dentry(dfi, rde->name, rde->name_len,
                                               next_offset);
-                       if (err)
+                       if (err) {
+                               ceph_mdsc_put_request(dfi->last_readdir);
+                               dfi->last_readdir = NULL;
                                return err;
+                       }
                } else if (req->r_reply_info.dir_end) {
                        dfi->next_offset = 2;
                        /* keep last name */
@@ -520,6 +523,12 @@ more:
                if (!dir_emit(ctx, rde->name, rde->name_len,
                              ceph_present_ino(inode->i_sb, le64_to_cpu(rde->inode.in->ino)),
                              le32_to_cpu(rde->inode.in->mode) >> 12)) {
+                       /*
+                        * NOTE: Here no need to put the 'dfi->last_readdir',
+                        * because when dir_emit stops us it's most likely
+                        * doesn't have enough memory, etc. So for next readdir
+                        * it will continue.
+                        */
                        dout("filldir stopping us...\n");
                        return 0;
                }