summaryrefslogtreecommitdiff
path: root/fs/ksmbd/vfs_cache.c
diff options
context:
space:
mode:
authorHyunchul Lee <hyc.lee@gmail.com>2021-07-10 16:22:41 +0900
committerNamjae Jeon <namjae.jeon@samsung.com>2021-07-10 16:23:50 +0900
commitd63528eb0d43c4796c42aad56889dec12cf4e122 (patch)
treefc8f922b3ac71f30c0778d54a0e6bf0ee020b168 /fs/ksmbd/vfs_cache.c
parent4b92841ef27b56883fa4491a3d51db3eef68c481 (diff)
ksmbd: free ksmbd_lock when file is closed
Append ksmbd_lock into the connection's lock list and the ksmbd_file's lock list. And when a file is closed, detach ksmbd_lock from these lists and free it. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/ksmbd/vfs_cache.c')
-rw-r--r--fs/ksmbd/vfs_cache.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c
index c54c605637a0..92d8c61ffd2a 100644
--- a/fs/ksmbd/vfs_cache.c
+++ b/fs/ksmbd/vfs_cache.c
@@ -302,6 +302,7 @@ static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp
static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
{
struct file *filp;
+ struct ksmbd_lock *smb_lock, *tmp_lock;
fd_limit_close();
__ksmbd_remove_durable_fd(fp);
@@ -313,6 +314,20 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
__ksmbd_inode_close(fp);
if (!IS_ERR_OR_NULL(filp))
fput(filp);
+
+ /* because the reference count of fp is 0, it is guaranteed that
+ * there are not accesses to fp->lock_list.
+ */
+ list_for_each_entry_safe(smb_lock, tmp_lock, &fp->lock_list, flist) {
+ spin_lock(&fp->conn->llist_lock);
+ list_del(&smb_lock->clist);
+ spin_unlock(&fp->conn->llist_lock);
+
+ list_del(&smb_lock->flist);
+ locks_free_lock(smb_lock->fl);
+ kfree(smb_lock);
+ }
+
kfree(fp->filename);
if (ksmbd_stream_fd(fp))
kfree(fp->stream.name);
@@ -549,6 +564,7 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
INIT_LIST_HEAD(&fp->blocked_works);
INIT_LIST_HEAD(&fp->node);
+ INIT_LIST_HEAD(&fp->lock_list);
spin_lock_init(&fp->f_lock);
atomic_set(&fp->refcount, 1);