Skip to content

Commit b63b388

Browse files
polarvidRbb666
authored andcommitted
feat: add support for dfs remount functionality
This patch introduces a remount feature for the DFS, allowing for the modification of mount parameters without unmounting the filesystem, the remount functionality helps modify certain mount flags (like `MS_RDONLY`) without requiring an unmount, providing more control over mounted filesystems in the system. 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: - Defined new constants for remount flags in `dfs_fs.h`. - Added the `dfs_remount()` function in `dfs_fs.c` to handle remount operations. - Introduced a check for unsupported flags and handle error conditions such as invalid paths or non-directory targets. - Updated the `dfs_mnt` structure in `dfs_mnt.h` to include a read-only flag (`MNT_RDONLY`). - The `dfs_remount()` function allows changing the read-only status of a mounted filesystem. - 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 944f3d0 commit b63b388

File tree

7 files changed

+202
-60
lines changed

7 files changed

+202
-60
lines changed

components/dfs/dfs_v2/include/dfs_fs.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,38 @@ extern "C"
2020
{
2121
#endif
2222

23+
#define MS_RDONLY 1
24+
#define MS_NOSUID 2
25+
#define MS_NODEV 4
26+
#define MS_NOEXEC 8
27+
#define MS_SYNCHRONOUS 16
28+
#define MS_REMOUNT 32
29+
#define MS_MANDLOCK 64
30+
#define MS_DIRSYNC 128
31+
#define MS_NOATIME 1024
32+
#define MS_NODIRATIME 2048
33+
#define MS_BIND 4096
34+
#define MS_MOVE 8192
35+
#define MS_REC 16384
36+
#define MS_SILENT 32768
37+
#define MS_POSIXACL (1<<16)
38+
#define MS_UNBINDABLE (1<<17)
39+
#define MS_PRIVATE (1<<18)
40+
#define MS_SLAVE (1<<19)
41+
#define MS_SHARED (1<<20)
42+
#define MS_RELATIME (1<<21)
43+
#define MS_KERNMOUNT (1<<22)
44+
#define MS_I_VERSION (1<<23)
45+
#define MS_STRICTATIME (1<<24)
46+
#define MS_LAZYTIME (1<<25)
47+
#define MS_NOREMOTELOCK (1<<27)
48+
#define MS_NOSEC (1<<28)
49+
#define MS_BORN (1<<29)
50+
#define MS_ACTIVE (1<<30)
51+
#define MS_NOUSER (1U<<31)
52+
53+
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME)
54+
2355
/* file system partition table */
2456
struct dfs_partition
2557
{
@@ -87,6 +119,7 @@ int dfs_unregister(struct dfs_filesystem_type *fs);
87119
int dfs_register(struct dfs_filesystem_type *fs);
88120
const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
89121

122+
int dfs_remount(const char *path, rt_ubase_t flags, void *data);
90123
int dfs_mount(const char *device_name,
91124
const char *path,
92125
const char *filesystemtype,

components/dfs/dfs_v2/include/dfs_mnt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ 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 */
43+
#define MNT_RDONLY 0x80 /* the mnt is read only */
4244

4345
rt_atomic_t ref_count; /* reference count */
4446

@@ -60,9 +62,13 @@ const char *dfs_mnt_get_mounted_path(struct rt_device *device);
6062
struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt);
6163
int dfs_mnt_unref(struct dfs_mnt* mnt);
6264

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

6570
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);
6672

6773
typedef void (*dfs_mnt_umnt_cb_t)(struct dfs_mnt *mnt);
6874
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: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,52 @@ int dfs_unregister(struct dfs_filesystem_type *fs)
9595
return ret;
9696
}
9797

98+
#define REMNT_UNSUPP_FLAGS (~(MS_REMOUNT | MS_RMT_MASK))
99+
int dfs_remount(const char *path, rt_ubase_t flags, void *data)
100+
{
101+
int rc = 0;
102+
char *fullpath = RT_NULL;
103+
struct dfs_mnt *mnt = RT_NULL;
104+
105+
if (flags & REMNT_UNSUPP_FLAGS)
106+
{
107+
return -EINVAL;
108+
}
109+
110+
fullpath = dfs_normalize_path(RT_NULL, path);
111+
if (!fullpath)
112+
{
113+
rc = -ENOENT;
114+
}
115+
else
116+
{
117+
DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt = dfs_mnt_lookup(%s)", fullpath);
118+
mnt = dfs_mnt_lookup(fullpath);
119+
if (mnt)
120+
{
121+
dfs_lock();
122+
dfs_mnt_setflags(mnt, flags);
123+
dfs_unlock();
124+
}
125+
else
126+
{
127+
struct stat buf = {0};
128+
if (dfs_file_stat(fullpath, &buf) == 0 && S_ISBLK(buf.st_mode))
129+
{
130+
/* path was not already mounted on target */
131+
rc = -EINVAL;
132+
}
133+
else
134+
{
135+
/* path is not a directory */
136+
rc = -ENOTDIR;
137+
}
138+
}
139+
}
140+
141+
return rc;
142+
}
143+
98144
/*
99145
* parent(mount path)
100146
* mnt_parent <- - - - - - - +
@@ -314,7 +360,7 @@ int dfs_umount(const char *specialfile, int flags)
314360
if (strcmp(mnt->fullpath, fullpath) == 0)
315361
{
316362
/* is the mount point */
317-
rt_atomic_t ref_count = rt_atomic_load(&(mnt->ref_count));
363+
rt_base_t ref_count = rt_atomic_load(&(mnt->ref_count));
318364

319365
if (!(mnt->flags & MNT_IS_LOCKED) && rt_list_isempty(&mnt->child) && (ref_count == 1 || (flags & MNT_FORCE)))
320366
{
@@ -327,17 +373,17 @@ int dfs_umount(const char *specialfile, int flags)
327373
}
328374
else
329375
{
330-
LOG_E("the file system is busy!");
376+
LOG_I("the file system is busy!");
331377
}
332378
}
333379
else
334380
{
335-
LOG_E("the path:%s is not a mountpoint!", fullpath);
381+
LOG_I("the path:%s is not a mountpoint!", fullpath);
336382
}
337383
}
338384
else
339385
{
340-
LOG_E("no filesystem found.");
386+
LOG_I("no filesystem found.");
341387
}
342388
rt_free(fullpath);
343389
}

components/dfs/dfs_v2/src/dfs_mnt.c

Lines changed: 25 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,21 @@ 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+
#ifdef RT_USING_PAGECACHE
297+
dfs_pcache_clean(mnt);
298+
#endif
299+
}
300+
301+
return error;
302+
}
303+
285304
int dfs_mnt_destroy(struct dfs_mnt* mnt)
286305
{
287306
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
@@ -162,7 +162,7 @@ void dfs_pcache_release(size_t count)
162162
dfs_pcache_unlock();
163163
}
164164

165-
void dfs_pcache_unmount(struct dfs_mnt *mnt)
165+
static void _pcache_clean(struct dfs_mnt *mnt, int (*cb)(struct dfs_aspace *aspace))
166166
{
167167
rt_list_t *node = RT_NULL;
168168
struct dfs_aspace *aspace = RT_NULL;
@@ -177,7 +177,7 @@ void dfs_pcache_unmount(struct dfs_mnt *mnt)
177177
if (aspace && aspace->mnt == mnt)
178178
{
179179
dfs_aspace_clean(aspace);
180-
dfs_aspace_release(aspace);
180+
cb(aspace);
181181
}
182182
}
183183

@@ -189,13 +189,28 @@ void dfs_pcache_unmount(struct dfs_mnt *mnt)
189189
if (aspace && aspace->mnt == mnt)
190190
{
191191
dfs_aspace_clean(aspace);
192-
dfs_aspace_release(aspace);
192+
cb(aspace);
193193
}
194194
}
195195

196196
dfs_pcache_unlock();
197197
}
198198

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

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

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

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

11531175
while (count)

0 commit comments

Comments
 (0)