llist_append(&parent->submnts, &mnt->sibmnts);
mutex_unlock(&mnt->parent->lock);
}
-
+
atomic_fetch_add(&mnt_point->ref_count, 1);
return mnt;
mnt_chillax(mnt->parent);
+ mnt->mnt_point->mnt = mnt->parent;
+
vfs_sb_free(sb);
- vfs_d_free(mnt->mnt_point);
+ atomic_fetch_sub(&mnt->mnt_point->ref_count, 1);
vfree(mnt);
return errno;
return ENOTBLK;
}
- if (mnt_point->inode && !(mnt_point->inode->itype & VFS_IFDIR)) {
+ if (mnt_point->inode && (mnt_point->inode->itype & F_MFILE)) {
return ENOTDIR;
}
goto cleanup;
}
- kprintf("mount: dev=%s, fs=%s, mode=%d\n", dev_name, fs_name, options);
+ kprintf("mount: dev=%s, fs=%s, mode=%d", dev_name, fs_name, options);
mnt_point->mnt->flags = options;
} else {
return errno;
cleanup:
- kprintf(KERROR "mount: dev=%s, fs=%s, mode=%d, err=%d\n",
- dev_name,
- fs_name,
- options,
- errno);
+ ERROR("mount: dev=%s, fs=%s, mode=%d, err=%d",
+ dev_name,
+ fs_name,
+ options,
+ errno);
mnt_point->super_block = old_sb;
vfs_sb_free(sb);
return errno;
int,
options)
{
- struct v_dnode *dev, *mnt;
+ struct v_dnode *dev = NULL, *mnt = NULL;
int errno = 0;
- if ((errno = vfs_walk(__current->cwd, source, &dev, NULL, 0))) {
- goto done;
- }
+ // It is fine if source is not exist, as some mounting don't require it
+ vfs_walk(__current->cwd, source, &dev, NULL, 0);
if ((errno = vfs_walk(__current->cwd, target, &mnt, NULL, 0))) {
goto done;
goto done;
}
+ if (mnt->mnt->mnt_point == mnt) {
+ errno = EBUSY;
+ goto done;
+ }
+
// By our convention.
// XXX could we do better?
- struct device* device = (struct device*)dev->inode->data;
+ struct device* device = NULL;
- if (!(dev->inode->itype & VFS_IFVOLDEV) || !device) {
- errno = ENOTDEV;
- goto done;
+ if (dev) {
+ if (!(dev->inode->itype & VFS_IFVOLDEV)) {
+ errno = ENOTDEV;
+ goto done;
+ }
+ device = (struct device*)dev->inode->data;
}
errno = vfs_mount_at(fstype, device, mnt, options);