[patch] statfs does not detect -t nullfs -o union as a union mount

Jilles Tjoelker jilles at stack.nl
Sat Mar 2 00:00:48 UTC 2013


On Thu, Feb 28, 2013 at 12:21:44AM +0200, Konstantin Belousov wrote:
> On Wed, Feb 27, 2013 at 10:31:42PM +0100, Jilles Tjoelker wrote:
> > While testing recent changes to opendir(), I noticed that fstatfs() does
> > not return the MNT_UNION flag for a -t nullfs -o union mount. As a
> > result, opendir()/readdir() return files that exist in both top and
> > bottom directories twice (at least . and ..). Other -o union mounts and
> > -t unionfs mounts work correctly in this regard.

> > The below patch passes through just the MNT_UNION flag of the nullfs
> > mount itself. Perhaps more flags should be passed through.

> > commit fce32a779af4eb977c9b96feb6e4f811d89f2881
> > Author: Jilles Tjoelker <jilles at stack.nl>
> > Date:   Sat Feb 23 22:22:39 2013 +0100
> > 
> >     nullfs: Preserve the MNT_UNION flag of the nullfs mount itself.
> >     
> >     This is needed so that opendir() can properly detect a union mount like
> >     mount -t nullfs -o union dir1 dir2.
> > 
> > diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
> > index 3724e0a..ff06f57 100644
> > --- a/sys/fs/nullfs/null_vfsops.c
> > +++ b/sys/fs/nullfs/null_vfsops.c
> > @@ -313,7 +313,7 @@ nullfs_statfs(mp, sbp)
> >  
> >  	/* now copy across the "interesting" information and fake the rest */
> >  	sbp->f_type = mstat.f_type;
> > -	sbp->f_flags = mstat.f_flags;
> > +	sbp->f_flags = (sbp->f_flags & MNT_UNION) | mstat.f_flags;
> >  	sbp->f_bsize = mstat.f_bsize;
> >  	sbp->f_iosize = mstat.f_iosize;
> >  	sbp->f_blocks = mstat.f_blocks;

> Would it make sense to preserve more flags from the upper mount ?
> I see a use for MNT_NOEXEC as well, at least.

Yes, preserving MNT_NOEXEC will make -t nullfs -o noexec work better, in
particular rtld's check for libraries loaded via environment variables.

In the same way MNT_RDONLY, MNT_NOSUID and MNT_NOSYMFOLLOW could be
preserved.

On the other hand, MNT_ROOTFS should probably not be passed through from
the underlying filesystem.

This would give
sbp->f_flags = (sbp->f_flags & (MNT_RDONLY | MNT_NOEXEC | MNT_NOSUID |
    MNT_UNION | MNT_NOSYMFOLLOW) | (mstat.f_flags & ~MNT_ROOTFS);

-- 
Jilles Tjoelker


More information about the freebsd-hackers mailing list