net/local: simplify file descriptor passing using shared filep references

This commit removes unnecessary file duplication and memory allocation when
passing file descriptors through Unix domain sockets, leveraging the new
filep reference counting framework.

Background:
With the new filep framework, file structures (filep) can be safely shared
across processes using reference counting. When passing file descriptors
through SCM_RIGHTS control messages on local sockets, the previous
implementation unnecessarily duplicated the entire file structure.

Changes:

1. In local_sendctl() (sender side):
   - Removed allocation of filep2 structure (kmm_zalloc)
   - Removed file_dup2() call that copied the file structure
   - Now directly stores the original filep with its reference count
   - Eliminates memory allocation overhead and potential failure points

2. In local_recvctl() (receiver side):
   - Changed from file_close() + kmm_free() to file_put()
   - file_put() properly decrements reference count and handles cleanup
   - Consistent with the new filep reference counting model

3. In local_freectl() (cleanup on error):
   - Changed from file_close() + kmm_free() to file_put()
   - Ensures proper reference count management during error paths

Technical Details:
The new filep framework ensures that:
- Multiple file descriptors across different processes can reference the
  same underlying filep structure safely
- Reference counting (via file_get/file_put) manages lifetime correctly
- The underlying file object is only released when all references are gone

This change is safe because file_dup() in the receiver already calls
file_get() internally to increment the reference count for the new fd,
so the filep remains valid after the sender calls file_put().

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1
2025-11-06 15:56:59 +08:00
committed by Xiang Xiao
parent 1b6733c056
commit d1bc2800e3
2 changed files with 3 additions and 22 deletions
+1 -2
View File
@@ -177,8 +177,7 @@ static void local_recvctl(FAR struct local_conn_s *conn,
{
fds[i] = file_dup(peer->lc_cfps[i], 0,
flags & MSG_CMSG_CLOEXEC ? O_CLOEXEC : 0);
file_close(peer->lc_cfps[i]);
kmm_free(peer->lc_cfps[i]);
file_put(peer->lc_cfps[i]);
peer->lc_cfps[i] = NULL;
peer->lc_cfpcount--;
if (fds[i] < 0)
+2 -20
View File
@@ -65,8 +65,7 @@ static void local_freectl(FAR struct local_conn_s *conn, int count)
while (count-- > 0)
{
file_close(peer->lc_cfps[--peer->lc_cfpcount]);
kmm_free(peer->lc_cfps[peer->lc_cfpcount]);
file_put(peer->lc_cfps[--peer->lc_cfpcount]);
peer->lc_cfps[peer->lc_cfpcount] = NULL;
}
}
@@ -75,7 +74,6 @@ static int local_sendctl(FAR struct local_conn_s *conn,
FAR struct msghdr *msg)
{
FAR struct local_conn_s *peer;
FAR struct file *filep2;
FAR struct file *filep;
FAR struct cmsghdr *cmsg;
int count = 0;
@@ -117,23 +115,7 @@ static int local_sendctl(FAR struct local_conn_s *conn,
goto fail;
}
filep2 = kmm_zalloc(sizeof(*filep2));
if (!filep2)
{
file_put(filep);
ret = -ENOMEM;
goto fail;
}
ret = file_dup2(filep, filep2);
file_put(filep);
if (ret < 0)
{
kmm_free(filep2);
goto fail;
}
peer->lc_cfps[peer->lc_cfpcount++] = filep2;
peer->lc_cfps[peer->lc_cfpcount++] = filep;
}
}