On Fri, Feb 12, 2021 at 10:34:50AM +0100, Ahmad Fatoum wrote: > From: Ahmad Fatoum <ahmad@xxxxxx> > > The VFS layer already increase the mount reference count for the mount > point. This means e.g. following sequence is well-behaving: > > mkdir -p /mnt/disk0.0/media > mount -o loop backing.squashfs /mnt/disk0.0/media > umount /mnt/disk0.0 > > barebox will do the right thing and report > > umount: Device or resource busy > > However the reference count of the file where backing.squashfs comes > from is not incremented on mount with the effect that following sequence > crashes: > > mkdir -p /media > mount -o loop /mnt/disk0.0/backing.squashfs /media > umount /mnt/disk0.0 # should've returned EBUSY > umount /media > > Fix this by touching the backing store's mount reference count when > loop mounting and unmounting. > > Signed-off-by: Ahmad Fatoum <ahmad@xxxxxx> > --- > fs/fs.c | 42 ++++++++++++++++++++++++++++++++++++------ > 1 file changed, 36 insertions(+), 6 deletions(-) Applied, thanks Sascha > > diff --git a/fs/fs.c b/fs/fs.c > index 00b8645fb0e9..3db24b7b6822 100644 > --- a/fs/fs.c > +++ b/fs/fs.c > @@ -89,7 +89,13 @@ static int init_fs(void) > > postcore_initcall(init_fs); > > +struct filename; > + > static struct fs_device_d *get_fsdevice_by_path(const char *path); > +static int filename_lookup(int dfd, struct filename *name, unsigned flags, > + struct path *path);; > +static struct filename *getname(const char *filename); > +static void path_put(const struct path *path); > > LIST_HEAD(fs_device_list); > > @@ -683,6 +689,8 @@ static void fs_remove(struct device_d *dev) > struct fs_device_d *fsdev = dev_to_fs_device(dev); > struct super_block *sb = &fsdev->sb; > struct inode *inode, *tmp; > + struct path path; > + int ret; > > if (fsdev->dev.driver) { > dev->driver->remove(dev); > @@ -695,9 +703,17 @@ static void fs_remove(struct device_d *dev) > if (fsdev->cdev) > cdev_close(fsdev->cdev); > > - if (fsdev->loop && fsdev->cdev) > + if (fsdev->loop && fsdev->cdev) { > cdev_remove_loop(fsdev->cdev); > > + ret = filename_lookup(AT_FDCWD, getname(fsdev->backingstore), > + LOOKUP_FOLLOW, &path); > + if (!ret) { > + mntput(path.mnt); > + path_put(&path); > + } > + } > + > if (fsdev->vfsmount.mountpoint) > fsdev->vfsmount.mountpoint->d_flags &= ~DCACHE_MOUNTED; > > @@ -767,16 +783,30 @@ static const char *detect_fs(const char *filename, const char *fsoptions) > int fsdev_open_cdev(struct fs_device_d *fsdev) > { > unsigned long long offset = 0; > + struct path path = {}; > + int ret; > > parseopt_b(fsdev->options, "loop", &fsdev->loop); > parseopt_llu_suffix(fsdev->options, "offset", &offset); > - if (fsdev->loop) > - fsdev->cdev = cdev_create_loop(fsdev->backingstore, O_RDWR, > - offset); > - else > + if (fsdev->loop) { > + ret = filename_lookup(AT_FDCWD, getname(fsdev->backingstore), > + LOOKUP_FOLLOW, &path); > + if (ret) > + return ret; > + > + fsdev->cdev = cdev_create_loop(fsdev->backingstore, O_RDWR, offset); > + } else { > fsdev->cdev = cdev_open(fsdev->backingstore, O_RDWR); > - if (!fsdev->cdev) > + } > + if (!fsdev->cdev) { > + path_put(&path); > return -EINVAL; > + } > + > + if (path.mnt) { > + mntget(path.mnt); > + path_put(&path); > + } > > fsdev->dev.parent = fsdev->cdev->dev; > fsdev->parent_device = fsdev->cdev->dev; > -- > 2.29.2 > > > _______________________________________________ > barebox mailing list > barebox@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox