X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/baca54322c66983205edecd2ebb00d997878be50..270869139db617e29a35bb9ded41087bb702f9ac:/lunaix-os/kernel/fs/mount.c diff --git a/lunaix-os/kernel/fs/mount.c b/lunaix-os/kernel/fs/mount.c index 2b996d4..c5b7344 100644 --- a/lunaix-os/kernel/fs/mount.c +++ b/lunaix-os/kernel/fs/mount.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -25,7 +25,7 @@ vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point) mnt->parent = parent; mnt->mnt_point = mnt_point; - mnt->super_block = mnt_point->super_block; + vfs_vmnt_assign_sb(mnt, mnt_point->super_block); if (parent) { mnt_mkbusy(parent); @@ -39,6 +39,21 @@ vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point) return mnt; } +void +__vfs_release_vmnt(struct v_mount* mnt) +{ + assert(llist_empty(&mnt->submnts)); + + if (mnt->parent) { + mnt_chillax(mnt->parent); + } + + llist_delete(&mnt->sibmnts); + llist_delete(&mnt->list); + atomic_fetch_sub(&mnt->mnt_point->ref_count, 1); + vfree(mnt); +} + int __vfs_do_unmount(struct v_mount* mnt) { @@ -49,9 +64,6 @@ __vfs_do_unmount(struct v_mount* mnt) return errno; } - llist_delete(&mnt->list); - llist_delete(&mnt->sibmnts); - // detached the inodes from cache, and let lru policy to recycle them for (size_t i = 0; i < VFS_HASHTABLE_SIZE; i++) { struct hbucket* bucket = &sb->i_cache[i]; @@ -61,13 +73,10 @@ __vfs_do_unmount(struct v_mount* mnt) bucket->head->pprev = 0; } - mnt_chillax(mnt->parent); - mnt->mnt_point->mnt = mnt->parent; vfs_sb_free(sb); - atomic_fetch_sub(&mnt->mnt_point->ref_count, 1); - vfree(mnt); + __vfs_release_vmnt(mnt); return errno; } @@ -139,7 +148,7 @@ vfs_mount_at(const char* fs_name, return ENOTBLK; } - if (mnt_point->inode && (mnt_point->inode->itype & F_MFILE)) { + if (mnt_point->inode && !check_directory_node(mnt_point->inode)) { return ENOTDIR; } @@ -148,47 +157,55 @@ vfs_mount_at(const char* fs_name, return ENODEV; } - if (fs->types == FSTYPE_ROFS) { + if ((fs->types & FSTYPE_ROFS)) { options |= MNT_RO; } + if (!(fs->types & FSTYPE_PSEUDO) && !device) { + return ENODEV; + } + + int errno = 0; char* dev_name = "sys"; struct v_mount* parent_mnt = mnt_point->mnt; - struct v_superblock *sb = vfs_sb_alloc(), *old_sb = mnt_point->super_block; - sb->dev = device; - mnt_point->super_block = sb; + struct v_superblock *sb = vfs_sb_alloc(), + *old_sb = mnt_point->super_block; if (device) { dev_name = device->name_val; } - int errno = 0; - if (!(errno = fs->mount(sb, mnt_point))) { - sb->fs = fs; - sb->root = mnt_point; + // prepare v_superblock for fs::mount invoke + sb->dev = device; + sb->fs = fs; + sb->root = mnt_point; + vfs_d_assign_sb(mnt_point, sb); - if (!(mnt_point->mnt = vfs_create_mount(parent_mnt, mnt_point))) { - errno = ENOMEM; - goto cleanup; - } + if (!(mnt_point->mnt = vfs_create_mount(parent_mnt, mnt_point))) { + errno = ENOMEM; + goto cleanup; + } + mnt_point->mnt->flags = options; + if (!(errno = fs->mount(sb, mnt_point))) { kprintf("mount: dev=%s, fs=%s, mode=%d", dev_name, fs_name, options); - - mnt_point->mnt->flags = options; } else { goto cleanup; } + vfs_sb_free(old_sb); return errno; cleanup: - ERROR("mount: dev=%s, fs=%s, mode=%d, err=%d", + ERROR("failed mount: dev=%s, fs=%s, mode=%d, err=%d", dev_name, fs_name, options, errno); - mnt_point->super_block = old_sb; + vfs_d_assign_sb(mnt_point, old_sb); vfs_sb_free(sb); + __vfs_release_vmnt(mnt_point->mnt); + return errno; } @@ -261,7 +278,7 @@ __DEFINE_LXSYSCALL4(int, struct device* device = NULL; if (dev) { - if (!(dev->inode->itype & VFS_IFVOLDEV)) { + if (!check_voldev_node(dev->inode)) { errno = ENOTDEV; goto done; }