From b1242a5e22e40b5399bf53ff470db737b40cd1d9 Mon Sep 17 00:00:00 2001 From: Michal Lenc Date: Thu, 4 Jun 2026 13:20:44 +0200 Subject: [PATCH 1/2] fs/vfs/fs_lock.c: fix flock behavior for more threads and fds We need to use gettid instead of getpid, otherwise flocks applied from different threads are considered as single thread lock and are ignored (or updated). Also fix the behavior if process opens the file multiple times Linux/BSD manual states multiple file descriptors opened by a single process shall be treated independently. Therefore we also need to compare struct file pointer to determine whether the lock applies to the same descriptor or not. Signed-off-by: Michal Lenc --- fs/vfs/fs_lock.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/fs/vfs/fs_lock.c b/fs/vfs/fs_lock.c index 535b35ec39f70..54c9eebcc7559 100644 --- a/fs/vfs/fs_lock.c +++ b/fs/vfs/fs_lock.c @@ -260,18 +260,20 @@ static void file_lock_delete_bucket(FAR struct file_lock_bucket_s *bucket, ****************************************************************************/ static bool file_lock_is_conflict(FAR struct flock *request, - FAR struct flock *internal) + FAR struct file *request_filep, + FAR struct file_lock_s *internal) { /* If the request is not exactly to the left or right of the internal, * then there is an overlap. */ - if (request->l_start <= internal->l_end && request->l_end >= - internal->l_start) + if (request->l_start <= internal->fl_lock.l_end && request->l_end >= + internal->fl_lock.l_start) { - if (request->l_type == F_WRLCK || internal->l_type == F_WRLCK) + if (request->l_type == F_WRLCK || internal->fl_lock.l_type == F_WRLCK) { - return request->l_pid != internal->l_pid; + return request->l_pid != internal->fl_lock.l_pid || + request_filep != internal->fl_file; } } @@ -371,8 +373,8 @@ static int file_lock_modify(FAR struct file *filep, { if (request->l_pid != file_lock->fl_lock.l_pid) { - /* Only file locks with the same pid need to be processed, so the - * lookup is skipped. + /* Only file locks with the same thread id need to be + * processed, so the lookup is skipped. */ if (find) @@ -598,7 +600,7 @@ int file_getlk(FAR struct file *filep, FAR struct flock *flock) list_for_every_entry(&bucket->list, file_lock, struct file_lock_s, fl_node) { - if (file_lock_is_conflict(flock, &file_lock->fl_lock)) + if (file_lock_is_conflict(flock, filep, file_lock)) { memcpy(flock, &file_lock->fl_lock, sizeof(*flock)); goto out; @@ -677,7 +679,7 @@ int file_setlk(FAR struct file *filep, FAR struct flock *flock, goto out_free; } - request.l_pid = getpid(); + request.l_pid = gettid(); nxmutex_lock(&g_protect_lock); @@ -709,7 +711,7 @@ int file_setlk(FAR struct file *filep, FAR struct flock *flock, list_for_every_entry(&bucket->list, file_lock, struct file_lock_s, fl_node) { - if (file_lock_is_conflict(&request, &file_lock->fl_lock)) + if (file_lock_is_conflict(&request, filep, file_lock)) { if (nonblock) { From 348b527d660be18ec2d6616ea03eca32af7d476a Mon Sep 17 00:00:00 2001 From: Michal Lenc Date: Wed, 10 Jun 2026 16:05:02 +0200 Subject: [PATCH 2/2] fs/vfs/fs_lock.c: support flock for SHM driver We can apply file lock on SHM inode as well. Ensure file_lock_get_path function passes and doesn't return EBADF errno. Signed-off-by: Michal Lenc --- fs/vfs/fs_lock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/vfs/fs_lock.c b/fs/vfs/fs_lock.c index 54c9eebcc7559..135232da45299 100644 --- a/fs/vfs/fs_lock.c +++ b/fs/vfs/fs_lock.c @@ -102,10 +102,13 @@ static int file_lock_get_path(FAR struct file *filep, FAR char *path) FAR struct tcb_s *tcb = this_task(); bool is_allowed_type; - /* We only apply file lock on mountpt and driver (f_inode won't be NULL). */ + /* We only apply file lock on mountpt, driver or shm + * (f_inode won't be NULL). + */ is_allowed_type = INODE_IS_MOUNTPT(filep->f_inode) || - INODE_IS_DRIVER(filep->f_inode); + INODE_IS_DRIVER(filep->f_inode) || + INODE_IS_SHM(filep->f_inode); if (!is_allowed_type || tcb->flags & TCB_FLAG_SIGNAL_ACTION) {