fs/hostfs: move global lock into hostfs_mountpt_s

Replace the global `g_lock` with a per-filesystem `fs->fs_lock`
to improve concurrency for multi-mount scenarios.

Signed-off-by: buxiasen <buxiasen@xiaomi.com>
This commit is contained in:
buxiasen 2025-10-29 23:34:25 +08:00 committed by GUIDINGLI
parent b42ec9a2c1
commit 40844c002c
2 changed files with 62 additions and 55 deletions

View file

@ -39,7 +39,6 @@
#include <nuttx/debug.h>
#include <nuttx/lib/lib.h>
#include <nuttx/mutex.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/fat.h>
#include <nuttx/fs/ioctl.h>
@ -118,12 +117,6 @@ static int hostfs_chstat(FAR struct inode *mountpt,
FAR const char *relpath,
FAR const struct stat *buf, int flags);
/****************************************************************************
* Private Data
****************************************************************************/
static mutex_t g_lock = NXMUTEX_INITIALIZER;
/****************************************************************************
* Public Data
****************************************************************************/
@ -263,7 +256,7 @@ static int hostfs_open(FAR struct file *filep, FAR const char *relpath,
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -334,7 +327,7 @@ errout_with_buffer:
fs_heap_free(hf);
errout_with_lock:
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
if (ret == -EINVAL)
{
ret = -EIO;
@ -368,7 +361,7 @@ static int hostfs_close(FAR struct file *filep)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -428,7 +421,7 @@ static int hostfs_close(FAR struct file *filep)
fs_heap_free(hf);
okout:
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return OK;
}
@ -458,7 +451,7 @@ static ssize_t hostfs_read(FAR struct file *filep, FAR char *buffer,
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -472,7 +465,7 @@ static ssize_t hostfs_read(FAR struct file *filep, FAR char *buffer,
filep->f_pos += ret;
}
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -500,7 +493,7 @@ static ssize_t hostfs_write(FAR struct file *filep, const char *buffer,
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -525,7 +518,7 @@ static ssize_t hostfs_write(FAR struct file *filep, const char *buffer,
}
errout_with_lock:
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -554,7 +547,7 @@ static off_t hostfs_seek(FAR struct file *filep, off_t offset, int whence)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -568,7 +561,7 @@ static off_t hostfs_seek(FAR struct file *filep, off_t offset, int whence)
filep->f_pos = ret;
}
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -597,7 +590,7 @@ static int hostfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -626,7 +619,7 @@ static int hostfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -659,7 +652,7 @@ static int hostfs_sync(FAR struct file *filep)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -667,7 +660,7 @@ static int hostfs_sync(FAR struct file *filep)
host_sync(hf->fd);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return OK;
}
@ -733,7 +726,7 @@ static int hostfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -743,7 +736,7 @@ static int hostfs_fstat(FAR const struct file *filep, FAR struct stat *buf)
ret = host_fstat(hf->fd, buf);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -779,7 +772,7 @@ static int hostfs_fchstat(FAR const struct file *filep,
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -789,7 +782,7 @@ static int hostfs_fchstat(FAR const struct file *filep,
ret = host_fchstat(hf->fd, buf, flags);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -820,7 +813,7 @@ static int hostfs_ftruncate(FAR struct file *filep, off_t length)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -830,7 +823,7 @@ static int hostfs_ftruncate(FAR struct file *filep, off_t length)
ret = host_ftruncate(hf->fd, length);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -864,7 +857,7 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
goto errout_with_hdir;
@ -884,11 +877,11 @@ static int hostfs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
}
*dir = (FAR struct fs_dirent_s *)hdir;
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return OK;
errout_with_lock:
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
errout_with_hdir:
fs_heap_free(hdir);
@ -905,6 +898,7 @@ errout_with_hdir:
static int hostfs_closedir(FAR struct inode *mountpt,
FAR struct fs_dirent_s *dir)
{
FAR struct hostfs_mountpt_s *fs;
FAR struct hostfs_dir_s *hdir;
int ret;
@ -914,11 +908,12 @@ static int hostfs_closedir(FAR struct inode *mountpt,
/* Recover our private data from the inode instance */
fs = mountpt->i_private;
hdir = (FAR struct hostfs_dir_s *)dir;
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -928,7 +923,7 @@ static int hostfs_closedir(FAR struct inode *mountpt,
host_closedir(hdir->dir);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
fs_heap_free(hdir);
return OK;
}
@ -944,6 +939,7 @@ static int hostfs_readdir(FAR struct inode *mountpt,
FAR struct fs_dirent_s *dir,
FAR struct dirent *entry)
{
FAR struct hostfs_mountpt_s *fs;
FAR struct hostfs_dir_s *hdir;
int ret;
@ -953,11 +949,12 @@ static int hostfs_readdir(FAR struct inode *mountpt,
/* Recover our private data from the inode instance */
fs = mountpt->i_private;
hdir = (FAR struct hostfs_dir_s *)dir;
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -967,7 +964,7 @@ static int hostfs_readdir(FAR struct inode *mountpt,
ret = host_readdir(hdir->dir, entry);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -981,6 +978,7 @@ static int hostfs_readdir(FAR struct inode *mountpt,
static int hostfs_rewinddir(FAR struct inode *mountpt,
FAR struct fs_dirent_s *dir)
{
FAR struct hostfs_mountpt_s *fs;
FAR struct hostfs_dir_s *hdir;
int ret;
@ -990,11 +988,12 @@ static int hostfs_rewinddir(FAR struct inode *mountpt,
/* Recover our private data from the inode instance */
fs = mountpt->i_private;
hdir = (FAR struct hostfs_dir_s *)dir;
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1004,7 +1003,7 @@ static int hostfs_rewinddir(FAR struct inode *mountpt,
host_rewinddir(hdir->dir);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return OK;
}
@ -1046,6 +1045,10 @@ static int hostfs_bind(FAR struct inode *blkdriver, FAR const void *data,
return -ENOMEM;
}
/* Hostfs by instance lock initialize */
nxmutex_init(&fs->fs_lock);
/* The options we support are:
* "fs=whatever", remote dir
*/
@ -1072,7 +1075,7 @@ static int hostfs_bind(FAR struct inode *blkdriver, FAR const void *data,
/* Take the lock for the mount */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
fs_heap_free(fs);
@ -1104,7 +1107,7 @@ static int hostfs_bind(FAR struct inode *blkdriver, FAR const void *data,
}
*handle = (FAR void *)fs;
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return OK;
}
@ -1129,7 +1132,7 @@ static int hostfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
/* Check if there are sill any files opened on the filesystem. */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1139,7 +1142,7 @@ static int hostfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
{
/* We cannot unmount now.. there are open files */
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
/* This implementation currently only supports unmounting if there are
* no open file references.
@ -1148,7 +1151,8 @@ static int hostfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
return (flags != 0) ? -ENOSYS : -EBUSY;
}
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
nxmutex_destroy(&fs->fs_lock);
fs_heap_free(fs);
return ret;
}
@ -1173,7 +1177,7 @@ static int hostfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
fs = mountpt->i_private;
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1184,7 +1188,7 @@ static int hostfs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf)
ret = host_statfs(fs->fs_root, buf);
buf->f_type = HOSTFS_MAGIC;
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -1209,7 +1213,7 @@ static int hostfs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
fs = mountpt->i_private;
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1223,7 +1227,7 @@ static int hostfs_unlink(FAR struct inode *mountpt, FAR const char *relpath)
ret = host_unlink(path);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -1249,7 +1253,7 @@ static int hostfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
fs = mountpt->i_private;
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1263,7 +1267,7 @@ static int hostfs_mkdir(FAR struct inode *mountpt, FAR const char *relpath,
ret = host_mkdir(path, mode);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -1290,7 +1294,7 @@ int hostfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath)
/* Take the lock */
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1304,7 +1308,7 @@ int hostfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath)
ret = host_rmdir(path);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -1331,7 +1335,7 @@ int hostfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath,
fs = mountpt->i_private;
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1348,7 +1352,7 @@ int hostfs_rename(FAR struct inode *mountpt, FAR const char *oldrelpath,
ret = host_rename(oldpath, newpath);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -1374,7 +1378,7 @@ static int hostfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
fs = mountpt->i_private;
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1388,7 +1392,7 @@ static int hostfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
ret = host_stat(path, buf);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}
@ -1414,7 +1418,7 @@ static int hostfs_chstat(FAR struct inode *mountpt, FAR const char *relpath,
fs = mountpt->i_private;
ret = nxmutex_lock(&g_lock);
ret = nxmutex_lock(&fs->fs_lock);
if (ret < 0)
{
return ret;
@ -1428,7 +1432,7 @@ static int hostfs_chstat(FAR struct inode *mountpt, FAR const char *relpath,
ret = host_chstat(path, buf, flags);
nxmutex_unlock(&g_lock);
nxmutex_unlock(&fs->fs_lock);
return ret;
}

View file

@ -34,6 +34,8 @@
#include <stdint.h>
#include <stdbool.h>
#include <nuttx/mutex.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -65,6 +67,7 @@ struct hostfs_ofile_s
struct hostfs_mountpt_s
{
FAR struct hostfs_ofile_s *fs_head; /* A singly-linked list of open files */
mutex_t fs_lock;
char fs_root[HOSTFS_MAX_PATH];
};