Re: xfs_quota: bug: traverses bind mountpoints

Paul Nienaber
2011-07-08T04:48:28Z

I would definitely agree that this is perhaps perhaps quite nonsensical
in the case of user/group quotas. However, a project quota is
conceptually a quota for "files in a directory and its subdirectories on
a particular filesystem", and I would argue that, regardless of
bindmounts, / is never a subdirectory of /foo, and this is where I think
the change in behaviour should be. There's also the somewhat-grey area
of how 'project -C' should behave, and I suppose the simplest and most
sensible answer there is "however 'project -s' and 'project -c' behave",
as that's both at least somewhat sensible and the least likely to
confuse people. I'd be happy to go digging at find at some point soon.

cheers
~Paul

On 11-07-07 8:23 PM, Dave Chinner wrote:
> On Thu, Jul 07, 2011 at 01:46:21PM -0700, Paul Nienaber wrote:
>> So, much like coreutils' du (which also shouldn't), xfs_quota
>> traverses bind mountpoints both when doing 'project -s' and 'project
>> -C', and probably also 'project -c' although I haven't tested it.
>> Testcase and output follows.
> How is a userspace traversal supposed to detect the fact it crosses
> a bind mount when it enters a directory? If you bind a directory
> from the same filesystem, stat(2) on the file returns -identical-
> information regardless of whether you are inside or outside the bind
> mount. So the normal mechanisms (e.g. st_dev changes) for detecting
> such a mount point traversal simply don't work.
>
> So the first question is whether we should be trying to detect bind
> mounts within the same filesystem and handling them for project
> quotas? I don't know the answer to that.
>
> Indeed:
>
> $ find .
> .
> ./projects
> ./projects/foo
> ./projects/foo/chroot
> find: File system loop detected; `./projects/foo/chroot/scratch' is
> part of the same file system loop as `.'.
> ./projects/bar
> ./projects/bar/foo
> ./baz
>
> find has some way of detecting such cases, but it doesn't do it via
> any special syscalls, nor does the newfstatat(AT_SYMLINK_NOFOLLOW)
> call it does return an error. And it does it regardless of whether
> the -xdev option is specified or not. So it must have some form of
> internal logic for detecting such loopy filesystem constructs.
>
> However, operations such as "chmod -R" do *not* detect this
> situation:
>
> $ sudo chown -R -v dave:dave *
> ownership of `baz' retained as dave:dave
> changed ownership of `projects/foo/chroot/scratch/projects/foo/chroot/scratch' to dave:dave
> changed ownership of `projects/foo/chroot/scratch/projects/foo/chroot' to dave:dave
> changed ownership of `projects/foo/chroot/scratch/projects/foo' to dave:dave
> changed ownership of `projects/foo/chroot/scratch/projects/bar/foo' to dave:dave
> changed ownership of `projects/foo/chroot/scratch/projects/bar' to dave:dave
> changed ownership of `projects/foo/chroot/scratch/projects' to dave:dave
> ownership of `projects/foo/chroot/scratch/baz' retained as dave:dave
> changed ownership of `projects/foo/chroot/scratch' to dave:dave
> changed ownership of `projects/foo/chroot' to dave:dave
> changed ownership of `projects/foo' to dave:dave
> ownership of `projects/bar/foo' retained as dave:dave
> ownership of `projects/bar' retained as dave:dave
> changed ownership of `projects' to dave:dave
>
> It's totally unclear what the behaviour of xfs_quota should be,
> because operations that change user and group quotas are completely
> ignorant of bind mounts.
>
> So if we decide bind mounts are important to detect, the second
> question is how do we detect bind mount point traversals in a
> reliable manner that doesn't involve adding significant overhead to
> the directory traversal code? I don't know the answer to that,
> either, and if you care about this enough I guess you'll go and look
> up what find does and tell us about it ;)
>
> Cheers,
>
> Dave.