mirror of
https://github.com/torvalds/linux.git
synced 2026-10-07 11:06:03 +02:00
ksmbd: check base file delete pending for stream opens
A base file that has been marked for deletion remains present while stream handles are open. Name-based opens of either the base file or one of its streams must return STATUS_DELETE_PENDING during that interval. ksmbd_inode_pending_delete() returned only the per-handle stream state for stream handles. It therefore skipped the inode-wide S_DEL_PENDING state set by the base file delete-on-close path. As a result, a new stream open incorrectly succeeded. Check the inode-wide pending-delete state first for every handle. Only when the base file is not pending, check the per-handle stream state. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
7f8029591b
commit
8dd5ca858d
|
|
@ -229,25 +229,15 @@ bool ksmbd_inode_pending_delete(struct ksmbd_file *fp)
|
|||
struct ksmbd_inode *ci = fp->f_ci;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Stream delete-pending is tracked per-handle (see
|
||||
* ksmbd_fd_set_delete_pending()), not on the shared inode -- the
|
||||
* whole-file flags checked below would never see it set, and would
|
||||
* also incorrectly report a whole-file pending-delete as applying
|
||||
* to an unrelated stream handle on the same inode.
|
||||
*/
|
||||
if (ksmbd_stream_fd(fp)) {
|
||||
bool pending;
|
||||
|
||||
spin_lock(&fp->f_lock);
|
||||
pending = fp->stream_del_pending;
|
||||
spin_unlock(&fp->f_lock);
|
||||
return pending;
|
||||
}
|
||||
|
||||
down_read(&ci->m_lock);
|
||||
ret = (ci->m_flags & S_DEL_PENDING);
|
||||
up_read(&ci->m_lock);
|
||||
if (ret || !ksmbd_stream_fd(fp))
|
||||
return ret;
|
||||
|
||||
spin_lock(&fp->f_lock);
|
||||
ret = fp->stream_del_pending;
|
||||
spin_unlock(&fp->f_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user