Skip to content

Commit e3fc065

Browse files
rohiths-msftsmfrench
authored andcommitted
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 <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 4c51de1 commit e3fc065

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

fs/cifs/cifsproto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
267267

268268
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
269269

270+
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
271+
const char *path);
272+
270273
extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx);
271274
extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
272275
int from_reconnect);

fs/cifs/inode.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
16241624
goto unlink_out;
16251625
}
16261626

1627-
cifs_close_deferred_file(CIFS_I(inode));
1627+
cifs_close_deferred_file_under_dentry(tcon, full_path);
16281628
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
16291629
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
16301630
rc = CIFSPOSIXDelFile(xid, tcon, full_path,
@@ -2113,9 +2113,9 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
21132113
goto cifs_rename_exit;
21142114
}
21152115

2116-
cifs_close_deferred_file(CIFS_I(d_inode(source_dentry)));
2116+
cifs_close_deferred_file_under_dentry(tcon, from_name);
21172117
if (d_inode(target_dentry) != NULL)
2118-
cifs_close_deferred_file(CIFS_I(d_inode(target_dentry)));
2118+
cifs_close_deferred_file_under_dentry(tcon, to_name);
21192119

21202120
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
21212121
to_name);

fs/cifs/misc.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,43 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
780780
kfree(tmp_list);
781781
}
782782
}
783+
void
784+
cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
785+
{
786+
struct cifsFileInfo *cfile;
787+
struct list_head *tmp;
788+
struct file_list *tmp_list, *tmp_next_list;
789+
struct list_head file_head;
790+
void *page;
791+
const char *full_path;
792+
793+
INIT_LIST_HEAD(&file_head);
794+
page = alloc_dentry_path();
795+
spin_lock(&tcon->open_file_lock);
796+
list_for_each(tmp, &tcon->openFileList) {
797+
cfile = list_entry(tmp, struct cifsFileInfo, tlist);
798+
full_path = build_path_from_dentry(cfile->dentry, page);
799+
if (strstr(full_path, path)) {
800+
if (delayed_work_pending(&cfile->deferred)) {
801+
if (cancel_delayed_work(&cfile->deferred)) {
802+
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
803+
if (tmp_list == NULL)
804+
break;
805+
tmp_list->cfile = cfile;
806+
list_add_tail(&tmp_list->list, &file_head);
807+
}
808+
}
809+
}
810+
}
811+
spin_unlock(&tcon->open_file_lock);
812+
813+
list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
814+
_cifsFileInfo_put(tmp_list->cfile, true, false);
815+
list_del(&tmp_list->list);
816+
kfree(tmp_list);
817+
}
818+
free_dentry_path(page);
819+
}
783820

784821
/* parses DFS refferal V3 structure
785822
* caller is responsible for freeing target_nodes

0 commit comments

Comments
 (0)