summaryrefslogtreecommitdiff
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
authorRohith Surabattula <rohiths@microsoft.com>2021-09-17 21:14:26 +0300
committerSteve French <stfrench@microsoft.com>2021-09-18 00:39:53 +0300
commite3fc065682ebbbd15b0ce0036800f4acbf765d46 (patch)
treeb31cbe6195fabc1ee80741264da61fadd72dfb2b /fs/cifs/misc.c
parent4c51de1e8f928a5b05248714d832d7d991ac319a (diff)
downloadlinux-e3fc065682ebbbd15b0ce0036800f4acbf765d46.tar.xz
cifs: Deferred close performance improvements
During unlink/rename instead of closing all the deferred handles under tcon, close only handles under the requested dentry. Signed-off-by: Rohith Surabattula <rohiths@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index f4313935e734..05138f92d905 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -780,6 +780,43 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
kfree(tmp_list);
}
}
+void
+cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
+{
+ struct cifsFileInfo *cfile;
+ struct list_head *tmp;
+ struct file_list *tmp_list, *tmp_next_list;
+ struct list_head file_head;
+ void *page;
+ const char *full_path;
+
+ INIT_LIST_HEAD(&file_head);
+ page = alloc_dentry_path();
+ spin_lock(&tcon->open_file_lock);
+ list_for_each(tmp, &tcon->openFileList) {
+ cfile = list_entry(tmp, struct cifsFileInfo, tlist);
+ full_path = build_path_from_dentry(cfile->dentry, page);
+ if (strstr(full_path, path)) {
+ if (delayed_work_pending(&cfile->deferred)) {
+ if (cancel_delayed_work(&cfile->deferred)) {
+ tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
+ if (tmp_list == NULL)
+ break;
+ tmp_list->cfile = cfile;
+ list_add_tail(&tmp_list->list, &file_head);
+ }
+ }
+ }
+ }
+ spin_unlock(&tcon->open_file_lock);
+
+ list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
+ _cifsFileInfo_put(tmp_list->cfile, true, false);
+ list_del(&tmp_list->list);
+ kfree(tmp_list);
+ }
+ free_dentry_path(page);
+}
/* parses DFS refferal V3 structure
* caller is responsible for freeing target_nodes