* @brief Mount a filesystem at the specified path * * This function mounts a filesystem of the specified type at the given path with optional device. * It handles both root filesystem mounting and regular filesystem mounting scenarios. * * @param[in] device_name The name of the device to mount (optional) * @param[in] path The path of the mount point * @param[in] filesystemtype The type of t
| 219 | * @note Automatic reference counting management for mount points |
| 220 | */ |
| 221 | int dfs_mount(const char *device_name, |
| 222 | const char *path, |
| 223 | const char *filesystemtype, |
| 224 | unsigned long rwflag, |
| 225 | const void *data) |
| 226 | { |
| 227 | int ret = RT_EOK; |
| 228 | char *fullpath = RT_NULL; |
| 229 | rt_device_t dev_id = RT_NULL; |
| 230 | struct dfs_mnt *mnt_parent = RT_NULL, *mnt_child = RT_NULL; |
| 231 | struct dfs_dentry *mntpoint_dentry = RT_NULL; |
| 232 | struct dfs_filesystem_type *type = *_find_filesystem(filesystemtype); |
| 233 | |
| 234 | /* normalize the mount path */ |
| 235 | if (type) |
| 236 | { |
| 237 | fullpath = dfs_normalize_path(RT_NULL, path); |
| 238 | if (!fullpath) |
| 239 | { |
| 240 | rt_set_errno(EPERM); |
| 241 | ret = -1; |
| 242 | } |
| 243 | } |
| 244 | else |
| 245 | { |
| 246 | rt_set_errno(ENODEV); |
| 247 | ret = -1; |
| 248 | } |
| 249 | |
| 250 | /* Main mounting procedure */ |
| 251 | if (fullpath) |
| 252 | { |
| 253 | DLOG(note, "mnt", "mount %s(%s) on path: %s", device_name, filesystemtype, fullpath); |
| 254 | |
| 255 | /* open specific device */ |
| 256 | if (device_name) dev_id = rt_device_find(device_name); |
| 257 | |
| 258 | /* Check device requirements */ |
| 259 | if (!(type->fs_ops->flags & FS_NEED_DEVICE) || |
| 260 | ((type->fs_ops->flags & FS_NEED_DEVICE) && dev_id)) |
| 261 | { |
| 262 | DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt_parent = dfs_mnt_lookup(%s)", fullpath); |
| 263 | mnt_parent = dfs_mnt_lookup(fullpath); /* Find parent mount point */ |
| 264 | |
| 265 | /* Handle root filesystem mounting */ |
| 266 | if ((!mnt_parent && (strcmp(fullpath, "/") == 0 || strcmp(fullpath, "/dev") == 0)) |
| 267 | || (mnt_parent && strcmp(fullpath, "/") == 0 && strcmp(mnt_parent->fullpath, fullpath) != 0)) |
| 268 | { |
| 269 | LOG_D("no mnt found @ mount point %s, should be root.", fullpath); |
| 270 | DLOG(msg, "mnt", "dfs", DLOG_MSG_RET, "no mnt"); |
| 271 | |
| 272 | /* it's the root file system */ |
| 273 | /* the mount point dentry is the same as root dentry. */ |
| 274 | /* Create root filesystem mount point */ |
| 275 | DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt_parent = dfs_mnt_create(path)"); |
| 276 | mnt_parent = dfs_mnt_create(fullpath); /* mnt->ref_count should be 1. */ |
| 277 | if (mnt_parent) |
| 278 | { |
no test coverage detected