mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
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>
This commit is contained in:
parent
4c51de1e8f
commit
e3fc065682
@ -267,6 +267,9 @@ extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
|
|||||||
|
|
||||||
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
|
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
|
||||||
|
|
||||||
|
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
|
||||||
|
const char *path);
|
||||||
|
|
||||||
extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx);
|
extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx);
|
||||||
extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
|
extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
|
||||||
int from_reconnect);
|
int from_reconnect);
|
||||||
|
@ -1624,7 +1624,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
|
|||||||
goto unlink_out;
|
goto unlink_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
cifs_close_deferred_file(CIFS_I(inode));
|
cifs_close_deferred_file_under_dentry(tcon, full_path);
|
||||||
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
||||||
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
||||||
rc = CIFSPOSIXDelFile(xid, tcon, full_path,
|
rc = CIFSPOSIXDelFile(xid, tcon, full_path,
|
||||||
@ -2113,9 +2113,9 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
|
|||||||
goto cifs_rename_exit;
|
goto cifs_rename_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
cifs_close_deferred_file(CIFS_I(d_inode(source_dentry)));
|
cifs_close_deferred_file_under_dentry(tcon, from_name);
|
||||||
if (d_inode(target_dentry) != NULL)
|
if (d_inode(target_dentry) != NULL)
|
||||||
cifs_close_deferred_file(CIFS_I(d_inode(target_dentry)));
|
cifs_close_deferred_file_under_dentry(tcon, to_name);
|
||||||
|
|
||||||
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
|
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
|
||||||
to_name);
|
to_name);
|
||||||
|
@ -780,6 +780,43 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
|
|||||||
kfree(tmp_list);
|
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
|
/* parses DFS refferal V3 structure
|
||||||
* caller is responsible for freeing target_nodes
|
* caller is responsible for freeing target_nodes
|
||||||
|
Loading…
Reference in New Issue
Block a user