Re: (reiserfs) Re: NFSv4 ACLs (was: ...ACL's and reiser...)

Xuan Baldauf (xuan--reiserfs@baldauf.org)
Sun, 06 Aug 2000 18:44:45 +0200


tytso@valinux.com wrote:

> Date: Sun, 06 Aug 2000 15:52:19 +0200
> From: Xuan Baldauf <xuan--reiserfs@baldauf.org>
>
> Tytso does not like the idea. And after some thinking about the issue, I can
> understand him. It is because
>
> (1) resolving from the bottom to the top might be more costly than
> static ACLs if no path component checking is needed anymore (path
> component checking is UNIX's Achilles Heel compared to NT) and (2)
> there is no definite parent for files with n_link>1
>
> The difference here is that NT always does path resolution from the
> root, whereas in Unix, we do path resolution of relative pathnames
> (i.e., those whose pathname don't start with a '/') relative to the
> current working directory.
>
> So doing full inheritable ACL's will force the Unix permissions checking
> model to be as SLOW as NT. (Consider how many relative pathnames are
> used when doing a kernel compile, for example.) And oh by the way, it's
> not just me who doesn't like this; most of the folks I chatted to at the
> OLS thought it was also an insane idea, including sct and alan, and a
> number of others. I very much doubt something like this would ever go
> into the VFS core. (If a filesystem wants to do this in their
> filesystem dependent code, and trash their Andrew benchmark scores, they
> can feel free to do so. :-)
>
> (1) can be circumvented by having a (persistent) ACL change cache in
> reiserfs. When accessing a file, the cache (usually empty) is checked
> against wether the entry in the cache applies to a particular
> file. If the cache entries do not apply to the file, the files ACL is
> checked. This way you can always have inheriting ACLs, make ACL
> changes of millions of files atomic. (Changes place an entry in the
> cache, and a background thread changes the resolved ACL entries in
> every file.)
>
> What are you storing in the cache? If you are storing the entry for
> each directory, you still have to do the full pathname resolution to
> find all of the parent directories. If you are storing cache entries
> index by inode number, then each time there is an ACL change, you have
> to flush the entire ACL cache. Also, this doesn't help you if you're
> doing something like a kernel compile, since you still have to do the
> full pathname resolution for every new file that you've never seen
> before. (Which in the case of the kernel compile, happens a lot.)
>
> - Ted

There might be a misconception, I surely was not clear enough. Imagine a filesystem
where every filesystem object (file, directory) has it's fully resolved ACL stored
in (a) it's directory entry or (b) it's stat data. (This also needs to be
discussed.) This way, you can quickly know wether to allow or deny an access, you
do not need to check ACLs of all parents. I think this is the way you (Ted) imagine
ACLs.

The only real drawback of this implementation would be that ACL setting is slow.
(But checking is (much) more important than setting.) But there might be an easy
way to overcome the problem: when you run

chacl -R "user bob: deny" /test/abc

to deny every access from bob to every file below and including "/test/abc", chacl
does not recursively change all ACLs but tells the filesystem an order "for every
fs object including and below /test/abc, deny access from user bob". This order
might|should be stored on disk. After the filesystem receives the order, it starts
a background thread (or uses a userspace daemon) which executes this order. When
the daemon is ready, it tells the filesystem that the order has been completed. The
filesystem removes the order from its order list.

So far, nothing has changed regarding the speed characteristics of setting and
checking ACLs. But now, for every access, the filesystem can easily know wether the
list of pending orders is empty or not (most of the time, it will be empty). If
some access needs to be checked, and the list of orders is not empty, the access is
first checked against all the orders. If there is a match in the list of pending
orders, the order-list is authorative (because it is newer it shows how access
control should be). If there is no match, the on-disk fully resolved ACL must be
authorative. If the order list is empty, there won't be a match, and therefore
checking for matching can be left out entirely.

The orders should be saved (using the journal) (at least if the order cannot be
executed in one atomic journaled operation) because after a crash, you would want
to have the new state rather than the old one. (Using conventional static ACLs or
chmod|chown, you always would end up in the middle).

This way, you have following characteristics:
- you almost always have resolved ACLs for every fs object
- chacl takes effect immediately, no need to wait hours until ACLs are set like on
NT
- you might be faster than rwx (because with rwx, you need to check every path
component)
- changing ACLs of a bunch of files can be made an atomic operation
- but: setting still slows down system speed (but compared to the gain in checking
speed, it should be bearable)

This concept is quite appealing for me, what do you think?

Xuân. :o)

P.S.: I hope that I have been clearer now (I'm not a native english speaker), if
questions remain, please ask. :o)
P.P.S.: To the question: "What are you storing in the cache?": I store the list of
pending acl-change orders in the cache. (The word cache was quite misleading.
Sorry.)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/