diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index 4d2d33df6231..ba3355a6057a 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -1390,19 +1390,19 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp) struct ksmbd_lock *smb_lock; unsigned int old_f_state; + write_lock(&global_ft.lock); if (!fp->is_durable || fp->conn || fp->tcon) { + write_unlock(&global_ft.lock); pr_err("Invalid durable fd [%p:%p]\n", fp->conn, fp->tcon); return -EBADF; } if (has_file_id(fp->volatile_id)) { + write_unlock(&global_ft.lock); pr_err("Still in use durable fd: %llu\n", fp->volatile_id); return -EBADF; } - old_f_state = fp->f_state; - fp->f_state = FP_NEW; - /* * Initialize fp's connection binding before publishing fp into the * session's file table. If __open_id() is ordered first, a @@ -1413,11 +1413,17 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp) */ fp->conn = ksmbd_conn_get(conn); fp->tcon = work->tcon; + write_unlock(&global_ft.lock); + + old_f_state = fp->f_state; + fp->f_state = FP_NEW; __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID); if (!has_file_id(fp->volatile_id)) { + write_lock(&global_ft.lock); fp->conn = NULL; fp->tcon = NULL; + write_unlock(&global_ft.lock); ksmbd_conn_put(conn); fp->f_state = old_f_state; return -EBADF;