Skip to content

Commit

Permalink
cifs: Fix memory leak on the deferred close
Browse files Browse the repository at this point in the history
xfstests on smb21 report kmemleak as below:

  unreferenced object 0xffff8881767d6200 (size 64):
    comm "xfs_io", pid 1284, jiffies 4294777434 (age 20.789s)
    hex dump (first 32 bytes):
      80 5a d0 11 81 88 ff ff 78 8a aa 63 81 88 ff ff  .Z......x..c....
      00 71 99 76 81 88 ff ff 00 00 00 00 00 00 00 00  .q.v............
    backtrace:
      [<00000000ad04e6ea>] cifs_close+0x92/0x2c0
      [<0000000028b93c82>] __fput+0xff/0x3f0
      [<00000000d8116851>] task_work_run+0x85/0xc0
      [<0000000027e14f9e>] do_exit+0x5e5/0x1240
      [<00000000fb492b95>] do_group_exit+0x58/0xe0
      [<00000000129a32d9>] __x64_sys_exit_group+0x28/0x30
      [<00000000e3f7d8e9>] do_syscall_64+0x35/0x80
      [<00000000102e8a0b>] entry_SYSCALL_64_after_hwframe+0x46/0xb0

When cancel the deferred close work, we should also cleanup the struct
cifs_deferred_close.

Fixes: 9e99275 ("cifs: Call close synchronously during unlink/rename/lease break.")
Fixes: e3fc065 ("cifs: Deferred close performance improvements")
Cc: [email protected]
Reviewed-by: Shyam Prasad N <[email protected]>
Signed-off-by: Zhang Xiaoxu <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
z00467499 authored and Steve French committed Aug 19, 2022
1 parent 400d0ad commit ca08d0e
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions fs/cifs/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,8 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
list_for_each_entry(cfile, &cifs_inode->openFileList, flist) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
cifs_del_deferred_close(cfile);

tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
Expand Down Expand Up @@ -766,6 +768,8 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
list_for_each_entry(cfile, &tcon->openFileList, tlist) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
cifs_del_deferred_close(cfile);

tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
Expand Down Expand Up @@ -799,6 +803,8 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
if (strstr(full_path, path)) {
if (delayed_work_pending(&cfile->deferred)) {
if (cancel_delayed_work(&cfile->deferred)) {
cifs_del_deferred_close(cfile);

tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
if (tmp_list == NULL)
break;
Expand Down

0 comments on commit ca08d0e

Please sign in to comment.