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

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit ed7a99a0f366358a969a0e8df5daff9dbff0f5e6
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Oct 19 18:10:13 2026 +0200

    fs/v9fs: Keep the file type in the mode of Tsetattr.
    
    V9FS sent only the permission bits (st_mode & 07777) in the mode of
    Tsetattr.  A server can store the mode as it is: QEMU with
    security_model=mapped-xattr writes it to the user.virtfs.mode xattr
    and returns it in Rgetattr.  So after chmod(), stat() showed no file
    type: a regular file had mode 0644, and a symbolic link changed by
    lchmod() was no longer a link.
    
    For CH_STAT_MODE, get the current mode with Tgetattr first and send
    its file type bits with the new permission bits, as the Linux client
    does.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 fs/v9fs/client.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/fs/v9fs/client.c b/fs/v9fs/client.c
index 21b37ea6238..2f10a78f593 100644
--- a/fs/v9fs/client.c
+++ b/fs/v9fs/client.c
@@ -936,6 +936,22 @@ int v9fs_client_chstat(FAR struct v9fs_client_s *client, 
uint32_t fid,
   struct v9fs_lerror_s response;
   struct iovec wiov[1];
   struct iovec riov[1];
+  struct stat st;
+  int ret;
+
+  /* A server can store the mode as it is (QEMU security_model=mapped-xattr),
+   * so keep the file type in it.
+   */
+
+  st.st_mode = 0;
+  if ((flags & CH_STAT_MODE) != 0)
+    {
+      ret = v9fs_client_stat(client, fid, &st);
+      if (ret < 0)
+        {
+          return ret;
+        }
+    }
 
   /* size[4] Tsetattr tag[2] fid[4] valid[4] mode[4] uid[4] gid[4] size[8]
    *                  atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]
@@ -948,7 +964,7 @@ int v9fs_client_chstat(FAR struct v9fs_client_s *client, 
uint32_t fid,
 
   request.fid = fid;
   request.valid = v9fs_map_setattr_flags(flags);
-  request.mode = buf->st_mode & 07777;
+  request.mode = (st.st_mode & S_IFMT) | (buf->st_mode & 07777);
   request.uid = buf->st_uid;
   request.gid = buf->st_gid;
   request.size = buf->st_size;

Reply via email to