Skip to content

Commit 02a8222

Browse files
committed
feat: support remount with RDONLY flags
This commit introduces enhancements to the remount functionality in the filesystem module, enabling better support for read-only (RDONLY) mounts. The updates is essential for user space init proc to cleanup the runtime resource, ensuring clean handling of cached data and enhancing system robustness during power down processing. Changes: - Added `MNT_LAZY_UMNT` and `MNT_RDONLY` flags to `dfs_mnt` structure. - Introduced `dfs_mnt_setflags` function for dynamic flag management. - Updated `dfs_remount` to utilize `dfs_mnt_setflags` for flag setting. - Enhanced unmount operations with `dfs_mnt_umount_iter` and lazy unmounting. - Added `dfs_pcache_clean` to handle cache cleanup for read-only mounts. - Improved error reporting in `dfs_umount` for better user feedback. - Refactored `sys_mount` to streamline parameter handling and support remounts. - Introduced `_cp_from_usr_string` helper for user-space string operations. - Updated internal APIs to ensure consistency in reference count management. Signed-off-by: Shell <[email protected]>
1 parent 1c97a36 commit 02a8222

File tree

6 files changed

+121
-64
lines changed

6 files changed

+121
-64
lines changed

components/dfs/dfs_v2/include/dfs_mnt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct dfs_mnt
3939
#define MNT_IS_UMOUNT 0x8 /* the mnt is unmount */
4040
#define MNT_IS_LOCKED 0x10 /* the mnt is locked */
4141
#define MNT_FORCE 0x20 /* the mnt force unmount */
42+
#define MNT_LAZY_UMNT 0x40 /* the mnt has pending umount */
4243
#define MNT_RDONLY 0x80 /* the mnt is read only */
4344

4445
rt_atomic_t ref_count; /* reference count */
@@ -61,9 +62,13 @@ const char *dfs_mnt_get_mounted_path(struct rt_device *device);
6162
struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt);
6263
int dfs_mnt_unref(struct dfs_mnt* mnt);
6364

65+
int dfs_mnt_umount(struct dfs_mnt *mnt, int flags);
66+
int dfs_mnt_setflags(struct dfs_mnt *mnt, int flags);
67+
6468
rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath);
6569

6670
int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter);
71+
int dfs_mnt_umount_iter(rt_bool_t (*filter)(struct dfs_mnt *mnt, void *parameter), void *parameter);
6772

6873
typedef void (*dfs_mnt_umnt_cb_t)(struct dfs_mnt *mnt);
6974
RT_OBJECT_HOOKLIST_DECLARE(dfs_mnt_umnt_cb_t, dfs_mnt_umnt);

components/dfs/dfs_v2/include/dfs_pcache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ int dfs_aspace_mmap_write(struct dfs_file *file, struct rt_varea *varea, void *d
118118

119119
void dfs_pcache_release(size_t count);
120120
void dfs_pcache_unmount(struct dfs_mnt *mnt);
121+
void dfs_pcache_clean(struct dfs_mnt *mnt);
121122

122123
#ifdef __cplusplus
123124
}

components/dfs/dfs_v2/src/dfs_fs.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,7 @@ int dfs_remount(const char *path, rt_ubase_t flags, void *data)
119119
if (mnt)
120120
{
121121
dfs_lock();
122-
if (flags & MS_RDONLY)
123-
{
124-
mnt->flags |= MNT_RDONLY;
125-
}
122+
dfs_mnt_setflags(mnt, flags);
126123
dfs_unlock();
127124
}
128125
else
@@ -363,7 +360,7 @@ int dfs_umount(const char *specialfile, int flags)
363360
if (strcmp(mnt->fullpath, fullpath) == 0)
364361
{
365362
/* is the mount point */
366-
rt_atomic_t ref_count = rt_atomic_load(&(mnt->ref_count));
363+
rt_base_t ref_count = rt_atomic_load(&(mnt->ref_count));
367364

368365
if (!(mnt->flags & MNT_IS_LOCKED) && rt_list_isempty(&mnt->child) && (ref_count == 1 || (flags & MNT_FORCE)))
369366
{
@@ -376,17 +373,17 @@ int dfs_umount(const char *specialfile, int flags)
376373
}
377374
else
378375
{
379-
LOG_E("the file system is busy!");
376+
LOG_I("the file system is busy!");
380377
}
381378
}
382379
else
383380
{
384-
LOG_E("the path:%s is not a mountpoint!", fullpath);
381+
LOG_I("the path:%s is not a mountpoint!", fullpath);
385382
}
386383
}
387384
else
388385
{
389-
LOG_E("no filesystem found.");
386+
LOG_I("no filesystem found.");
390387
}
391388
rt_free(fullpath);
392389
}

components/dfs/dfs_v2/src/dfs_mnt.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010

1111
#include <rtthread.h>
1212

13-
#include "dfs.h"
14-
#include "dfs_mnt.h"
15-
#include "dfs_dentry.h"
1613
#include "dfs_private.h"
1714

15+
#include <dfs.h>
16+
#include <dfs_dentry.h>
17+
#include <dfs_mnt.h>
18+
#include <dfs_pcache.h>
19+
1820
#define DBG_TAG "DFS.mnt"
1921
#define DBG_LVL DBG_WARNING
2022
#include <rtdbg.h>
@@ -77,6 +79,7 @@ int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child)
7779
child = _root_mnt;
7880
rt_atomic_sub(&(_root_mnt->parent->ref_count), 1);
7981
rt_atomic_sub(&(_root_mnt->ref_count), 1);
82+
_root_mnt->flags &= ~MNT_IS_LOCKED;
8083

8184
_root_mnt = dfs_mnt_ref(mnt);
8285
mnt->parent = dfs_mnt_ref(mnt);
@@ -244,15 +247,16 @@ struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt)
244247
return mnt;
245248
}
246249

247-
int dfs_mnt_unref(struct dfs_mnt* mnt)
250+
int dfs_mnt_unref(struct dfs_mnt *mnt)
248251
{
249252
rt_err_t ret = RT_EOK;
253+
rt_base_t ref_count;
250254

251255
if (mnt)
252256
{
253-
rt_atomic_sub(&(mnt->ref_count), 1);
257+
ref_count = rt_atomic_sub(&(mnt->ref_count), 1) - 1;
254258

255-
if (rt_atomic_load(&(mnt->ref_count)) == 0)
259+
if (ref_count == 0)
256260
{
257261
dfs_lock();
258262

@@ -282,6 +286,19 @@ int dfs_mnt_unref(struct dfs_mnt* mnt)
282286
return ret;
283287
}
284288

289+
int dfs_mnt_setflags(struct dfs_mnt *mnt, int flags)
290+
{
291+
int error = 0;
292+
293+
if (flags & MS_RDONLY)
294+
{
295+
mnt->flags |= MNT_RDONLY;
296+
dfs_pcache_clean(mnt);
297+
}
298+
299+
return error;
300+
}
301+
285302
int dfs_mnt_destroy(struct dfs_mnt* mnt)
286303
{
287304
rt_err_t ret = RT_EOK;

components/dfs/dfs_v2/src/dfs_pcache.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ void dfs_pcache_release(size_t count)
161161
dfs_pcache_unlock();
162162
}
163163

164-
void dfs_pcache_unmount(struct dfs_mnt *mnt)
164+
static void _pcache_clean(struct dfs_mnt *mnt, int (*cb)(struct dfs_aspace *aspace))
165165
{
166166
rt_list_t *node = RT_NULL;
167167
struct dfs_aspace *aspace = RT_NULL;
@@ -176,7 +176,7 @@ void dfs_pcache_unmount(struct dfs_mnt *mnt)
176176
if (aspace && aspace->mnt == mnt)
177177
{
178178
dfs_aspace_clean(aspace);
179-
dfs_aspace_release(aspace);
179+
cb(aspace);
180180
}
181181
}
182182

@@ -188,13 +188,28 @@ void dfs_pcache_unmount(struct dfs_mnt *mnt)
188188
if (aspace && aspace->mnt == mnt)
189189
{
190190
dfs_aspace_clean(aspace);
191-
dfs_aspace_release(aspace);
191+
cb(aspace);
192192
}
193193
}
194194

195195
dfs_pcache_unlock();
196196
}
197197

198+
void dfs_pcache_unmount(struct dfs_mnt *mnt)
199+
{
200+
_pcache_clean(mnt, dfs_aspace_release);
201+
}
202+
203+
static int _dummy_cb(struct dfs_aspace *mnt)
204+
{
205+
return 0;
206+
}
207+
208+
void dfs_pcache_clean(struct dfs_mnt *mnt)
209+
{
210+
_pcache_clean(mnt, _dummy_cb);
211+
}
212+
198213
static int dfs_pcache_limit_check(void)
199214
{
200215
int index = 4;
@@ -1139,14 +1154,21 @@ int dfs_aspace_write(struct dfs_file *file, const void *buf, size_t count, off_t
11391154

11401155
if (file && file->vnode && file->vnode->aspace)
11411156
{
1142-
if (!(file->vnode->aspace->ops->write))
1143-
return ret;
11441157
struct dfs_vnode *vnode = file->vnode;
11451158
struct dfs_aspace *aspace = vnode->aspace;
11461159

11471160
struct dfs_page *page;
11481161
char *ptr = (char *)buf;
11491162

1163+
if (!(aspace->ops->write))
1164+
{
1165+
return ret;
1166+
}
1167+
else if (aspace->mnt && (aspace->mnt->flags & MNT_RDONLY))
1168+
{
1169+
return -EROFS;
1170+
}
1171+
11501172
ret = 0;
11511173

11521174
while (count)

components/lwp/lwp_syscall.c

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5743,79 +5743,94 @@ sysret_t sys_fstatfs64(int fd, size_t sz, struct statfs *buf)
57435743
return ret;
57445744
}
57455745

5746-
sysret_t sys_mount(char *source, char *target,
5747-
char *filesystemtype,
5748-
unsigned long mountflags, void *data)
5749-
{
5750-
char *copy_source;
5751-
char *copy_target;
5752-
char *copy_filesystemtype;
5753-
size_t len_source, copy_len_source;
5754-
size_t len_target, copy_len_target;
5755-
size_t len_filesystemtype, copy_len_filesystemtype;
5746+
static char *_cp_from_usr_string(char *dst, char *src, size_t length)
5747+
{
5748+
char *rc;
5749+
size_t copied_bytes;
5750+
if (length)
5751+
{
5752+
copied_bytes = lwp_get_from_user(dst, src, length);
5753+
dst[copied_bytes] = '\0';
5754+
rc = dst;
5755+
}
5756+
else
5757+
{
5758+
rc = RT_NULL;
5759+
}
5760+
return rc;
5761+
}
5762+
5763+
sysret_t sys_mount(char *source, char *target, char *filesystemtype,
5764+
unsigned long mountflags, void *data)
5765+
{
5766+
char *kbuffer, *ksource, *ktarget, *kfs;
5767+
size_t len_source, len_target, len_fs;
57565768
char *tmp = NULL;
57575769
int ret = 0;
57585770
struct stat buf = {0};
5771+
char *dev_fullpath = RT_NULL;
57595772

5760-
len_source = lwp_user_strlen(source);
5761-
if (len_source <= 0)
5773+
len_source = source ? lwp_user_strlen(source) : 0;
5774+
if (len_source < 0)
57625775
return -EINVAL;
57635776

5764-
len_target = lwp_user_strlen(target);
5777+
len_target = target ? lwp_user_strlen(target) : 0;
57655778
if (len_target <= 0)
57665779
return -EINVAL;
57675780

5768-
len_filesystemtype = lwp_user_strlen(filesystemtype);
5769-
if (len_filesystemtype <= 0)
5781+
len_fs = filesystemtype ? lwp_user_strlen(filesystemtype) : 0;
5782+
if (len_fs < 0)
57705783
return -EINVAL;
57715784

5772-
copy_source = (char*)rt_malloc(len_source + 1 + len_target + 1 + len_filesystemtype + 1);
5773-
if (!copy_source)
5785+
kbuffer = (char *)rt_malloc(len_source + 1 + len_target + 1 + len_fs + 1);
5786+
if (!kbuffer)
57745787
{
57755788
return -ENOMEM;
57765789
}
5777-
copy_target = copy_source + len_source + 1;
5778-
copy_filesystemtype = copy_target + len_target + 1;
57795790

5780-
copy_len_source = lwp_get_from_user(copy_source, source, len_source);
5781-
copy_source[copy_len_source] = '\0';
5782-
copy_len_target = lwp_get_from_user(copy_target, target, len_target);
5783-
copy_target[copy_len_target] = '\0';
5784-
copy_len_filesystemtype = lwp_get_from_user(copy_filesystemtype, filesystemtype, len_filesystemtype);
5785-
copy_filesystemtype[copy_len_filesystemtype] = '\0';
5791+
/* get parameters from user space */
5792+
ksource = kbuffer;
5793+
ktarget = ksource + len_source + 1;
5794+
kfs = ktarget + len_target + 1;
5795+
ksource = _cp_from_usr_string(ksource, source, len_source);
5796+
ktarget = _cp_from_usr_string(ktarget, target, len_target);
5797+
kfs = _cp_from_usr_string(kfs, filesystemtype, len_fs);
57865798

5787-
if (strcmp(copy_filesystemtype, "nfs") == 0)
5799+
if (mountflags & MS_REMOUNT)
57885800
{
5789-
tmp = copy_source;
5790-
copy_source = NULL;
5801+
ret = dfs_remount(ktarget, mountflags, data);
57915802
}
5792-
if (strcmp(copy_filesystemtype, "tmp") == 0)
5803+
else
57935804
{
5794-
copy_source = NULL;
5795-
}
5805+
if (strcmp(kfs, "nfs") == 0)
5806+
{
5807+
tmp = ksource;
5808+
ksource = NULL;
5809+
}
5810+
if (strcmp(kfs, "tmp") == 0)
5811+
{
5812+
ksource = NULL;
5813+
}
57965814

5797-
if (copy_source && stat(copy_source, &buf) && S_ISBLK(buf.st_mode))
5798-
{
5799-
char *dev_fullpath = dfs_normalize_path(RT_NULL, copy_source);
5800-
RT_ASSERT(rt_strncmp(dev_fullpath, "/dev/", sizeof("/dev/") - 1) == 0);
5801-
ret = dfs_mount(dev_fullpath + sizeof("/dev/") - 1, copy_target, copy_filesystemtype, 0, tmp);
5802-
if (ret < 0)
5815+
if (ksource && dfs_file_stat(ksource, &buf) && S_ISBLK(buf.st_mode))
58035816
{
5804-
ret = -rt_get_errno();
5817+
dev_fullpath = dfs_normalize_path(RT_NULL, ksource);
5818+
RT_ASSERT(rt_strncmp(dev_fullpath, "/dev/", sizeof("/dev/") - 1) == 0);
5819+
ret = dfs_mount(dev_fullpath + sizeof("/dev/") - 1, ktarget, kfs, 0, tmp);
58055820
}
5806-
rt_free(copy_source);
5807-
rt_free(dev_fullpath);
5808-
}
5809-
else
5810-
{
5811-
ret = dfs_mount(copy_source, copy_target, copy_filesystemtype, 0, tmp);
5821+
else
5822+
{
5823+
ret = dfs_mount(ksource, ktarget, kfs, 0, tmp);
5824+
}
5825+
58125826
if (ret < 0)
58135827
{
58145828
ret = -rt_get_errno();
58155829
}
5816-
rt_free(copy_source);
58175830
}
58185831

5832+
rt_free(kbuffer);
5833+
rt_free(dev_fullpath);
58195834
return ret;
58205835
}
58215836

0 commit comments

Comments
 (0)