From: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
To: viro@ZenIV.linux.org.uk
Cc: linux-fsdevel@vger.kernel.org,
Gabriel Krisman Bertazi <krisman@collabora.co.uk>
Subject: [PATCH NOMERGE 02/13] vfs: Propagate LOOKUP_CASEFOLD after doing parent lookups
Date: Tue, 22 May 2018 17:38:07 -0300 [thread overview]
Message-ID: <20180522203818.14666-3-krisman@collabora.co.uk> (raw)
In-Reply-To: <20180522203818.14666-1-krisman@collabora.co.uk>
filename_parentat() is executed in order to quickly access a child
dentry for creation, unlinking or rename, outside the path_walk path.
Although, if the parent was accessed via a CI mount, we need to make
sure the child will also be searched in a CI manner, so the nameidata
flag from the first search needs to be propageted to the following child
__lookup_hash call.
Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
---
fs/namei.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 54 insertions(+), 7 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index ddd5c9e9ab3c..135a9a4e676b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2369,7 +2369,7 @@ static int path_parentat(struct nameidata *nd, unsigned flags,
static struct filename *filename_parentat(int dfd, struct filename *name,
unsigned int flags, struct path *parent,
- struct qstr *last, int *type)
+ struct qstr *last, int *type, bool *foldtree)
{
int retval;
struct nameidata nd;
@@ -2385,6 +2385,7 @@ static struct filename *filename_parentat(int dfd, struct filename *name,
if (likely(!retval)) {
*last = nd.last;
*type = nd.last_type;
+ *foldtree = !!(nd.flags & LOOKUP_CASEFOLD);
audit_inode(name, parent->dentry, LOOKUP_PARENT);
} else {
putname(name);
@@ -2401,9 +2402,14 @@ struct dentry *kern_path_locked(const char *name, struct path *path)
struct dentry *d;
struct qstr last;
int type;
+ bool foldtree = false;
filename = filename_parentat(AT_FDCWD, getname_kernel(name), 0, path,
- &last, &type);
+ &last, &type, &foldtree);
+
+ /* kernel path don't care about foldtree. Root cannot be folded. */
+ WARN_ON(foldtree);
+
if (IS_ERR(filename))
return ERR_CAST(filename);
if (unlikely(type != LAST_NORM)) {
@@ -3620,6 +3626,7 @@ static struct dentry *filename_create(int dfd, struct filename *name,
int err2;
int error;
bool is_dir = (lookup_flags & LOOKUP_DIRECTORY);
+ bool foldtree = false;
/*
* Note that only LOOKUP_REVAL and LOOKUP_DIRECTORY matter here. Any
@@ -3627,7 +3634,8 @@ static struct dentry *filename_create(int dfd, struct filename *name,
*/
lookup_flags &= LOOKUP_REVAL;
- name = filename_parentat(dfd, name, lookup_flags, path, &last, &type);
+ name = filename_parentat(dfd, name, lookup_flags, path, &last,
+ &type, &foldtree);
if (IS_ERR(name))
return ERR_CAST(name);
@@ -3644,6 +3652,16 @@ static struct dentry *filename_create(int dfd, struct filename *name,
* Do the final lookup.
*/
lookup_flags |= LOOKUP_CREATE | LOOKUP_EXCL;
+
+ /* If parent is a casefold mountpoint, search for an existing
+ * dentry with LOOKUP_CASEFOLD.
+ * LOOKUP_CASEFOLD needs to be explicitly cleared in case it is
+ * doing retry. */
+ if (foldtree)
+ lookup_flags |= LOOKUP_CASEFOLD;
+ else
+ lookup_flags &= ~LOOKUP_CASEFOLD;
+
inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
dentry = __lookup_hash(&last, path->dentry, lookup_flags);
if (IS_ERR(dentry))
@@ -3904,9 +3922,10 @@ static long do_rmdir(int dfd, const char __user *pathname)
struct qstr last;
int type;
unsigned int lookup_flags = 0;
+ bool foldtree;
retry:
name = filename_parentat(dfd, getname(pathname), lookup_flags,
- &path, &last, &type);
+ &path, &last, &type, &foldtree);
if (IS_ERR(name))
return PTR_ERR(name);
@@ -3926,6 +3945,13 @@ static long do_rmdir(int dfd, const char __user *pathname)
if (error)
goto exit1;
+ /* LOOKUP_CASEFOLD needs to be explicitly cleared in case it is
+ * doing retry. */
+ if (foldtree)
+ lookup_flags |= LOOKUP_CASEFOLD;
+ else
+ lookup_flags &= ~LOOKUP_CASEFOLD;
+
inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
dentry = __lookup_hash(&last, path.dentry, lookup_flags);
error = PTR_ERR(dentry);
@@ -4033,8 +4059,10 @@ long do_unlinkat(int dfd, struct filename *name)
struct inode *inode = NULL;
struct inode *delegated_inode = NULL;
unsigned int lookup_flags = 0;
+ bool foldtree = false;
retry:
- name = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
+ name = filename_parentat(dfd, name, lookup_flags, &path, &last, &type,
+ &foldtree);
if (IS_ERR(name))
return PTR_ERR(name);
@@ -4045,6 +4073,13 @@ long do_unlinkat(int dfd, struct filename *name)
error = mnt_want_write(path.mnt);
if (error)
goto exit1;
+
+ /* LOOKUP_CASEFOLD needs to be explicitly cleared in case it is
+ * doing retry. */
+ if (foldtree)
+ lookup_flags |= LOOKUP_CASEFOLD;
+ else
+ lookup_flags &= ~LOOKUP_CASEFOLD;
retry_deleg:
inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
dentry = __lookup_hash(&last, path.dentry, lookup_flags);
@@ -4514,6 +4549,7 @@ SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
struct filename *to;
unsigned int lookup_flags = 0, target_flags = LOOKUP_RENAME_TARGET;
bool should_retry = false;
+ bool foldtree = false;
int error;
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
@@ -4531,14 +4567,14 @@ SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
retry:
from = filename_parentat(olddfd, getname(oldname), lookup_flags,
- &old_path, &old_last, &old_type);
+ &old_path, &old_last, &old_type, &foldtree);
if (IS_ERR(from)) {
error = PTR_ERR(from);
goto exit;
}
to = filename_parentat(newdfd, getname(newname), lookup_flags,
- &new_path, &new_last, &new_type);
+ &new_path, &new_last, &new_type, &foldtree);
if (IS_ERR(to)) {
error = PTR_ERR(to);
goto exit1;
@@ -4561,6 +4597,17 @@ SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
if (error)
goto exit2;
+ /* Since rename(2) doesn't work across mountpoints, we are sure
+ * that foldtree for TO and FROM are the same.
+ *
+ * LOOKUP_CASEFOLD needs to be explicitly cleared in case it is
+ * doing retry. */
+ if (foldtree)
+ lookup_flags |= LOOKUP_CASEFOLD;
+ else
+ lookup_flags &= ~LOOKUP_CASEFOLD;
+
+
retry_deleg:
trap = lock_rename(new_path.dentry, old_path.dentry);
--
2.17.0
next prev parent reply other threads:[~2018-05-22 20:37 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-22 20:38 [PATCH NOMERGE 00/13] Case insensitiveness as a mountpoint Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 01/13] vfs: Add support for mounting with MS_CASEFOLD Gabriel Krisman Bertazi
2018-05-22 20:38 ` Gabriel Krisman Bertazi [this message]
2018-05-22 20:38 ` [PATCH NOMERGE 03/13] vfs: Add support for positive dentries CI lookups in the dentry cache Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 04/13] vfs: Allow bind,remount with MS_CASEFOLD Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 05/13] vfs: Handle case-exact lookup in d_add_ci Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 06/13] vfs: Add Support for hard negative dentries in the dcache Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 07/13] vfs: Handle MNT_CASEFOLD in /proc/mounts Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 08/13] fscrypt: Introduce charset-based matching functions Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 09/13] ext4: Include encoding information on the superblock Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 10/13] ext4: Plumb LOOK_CASEFOLD up to ext4 comparison functions Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 11/13] ext4: Support charset name matching Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 12/13] ext4: Implement ext4 dcache hooks for custom charsets Gabriel Krisman Bertazi
2018-05-22 20:38 ` [PATCH NOMERGE 13/13] ext4: Notify VFS of support for casefolded mountpoints Gabriel Krisman Bertazi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180522203818.14666-3-krisman@collabora.co.uk \
--to=krisman@collabora.co.uk \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).