fscrypt: cache decrypted symlink target in ->i_link
authorEric Biggers <ebiggers@google.com>
Wed, 10 Apr 2019 20:21:15 +0000 (13:21 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 17 Apr 2019 16:43:29 +0000 (12:43 -0400)
commit2c58d548f5706d085c4b009f6abb945220460632
treeb263f432d3ad778b6970ebbb842bd0a577e88cdc
parent4c4f7c19b3c721aed418bc97907b411608c5c6a0
fscrypt: cache decrypted symlink target in ->i_link

Path lookups that traverse encrypted symlink(s) are very slow because
each encrypted symlink needs to be decrypted each time it's followed.
This also involves dropping out of rcu-walk mode.

Make encrypted symlinks faster by caching the decrypted symlink target
in ->i_link.  The first call to fscrypt_get_symlink() sets it.  Then,
the existing VFS path lookup code uses the non-NULL ->i_link to take the
fast path where ->get_link() isn't called, and lookups in rcu-walk mode
remain in rcu-walk mode.

Also set ->i_link immediately when a new encrypted symlink is created.

To safely free the symlink target after an RCU grace period has elapsed,
introduce a new function fscrypt_free_inode(), and make the relevant
filesystems call it just before actually freeing the inode.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/crypto/hooks.c
fs/crypto/keyinfo.c
fs/ext4/super.c
fs/f2fs/super.c
fs/ubifs/super.c
include/linux/fscrypt.h