This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch releases/13.0
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit e5199c94ace5b4e856ef7839e4368e00613f34a8
Author: Michal Lenc <[email protected]>
AuthorDate: Thu Jun 4 13:20:44 2026 +0200

    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 <[email protected]>
---
 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 535b35ec39f..54c9eebcc75 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 @@ retry:
       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)
                 {

Reply via email to