mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
vfs: make LAST_XXX private to fs/namei.c
The only user of LAST_XXX outside of fs/namei.c is fs/smb/server/vfs.c; ksmbd_vfs_path_lookup() calls vfs_path_parent_lookup() and expects a LAST_NORM last type (or it will be ENOENT). ksmbd_vfs_rename() also calls vfs_path_parent_lookup() but forgets the LAST_NORM check. It does not really make sense to have vfs_path_parent_lookup() expose the last_type because it is only needed to ensure it is LAST_NORM. So let's do this check in vfs_path_parent_lookup() instead and keep the LAST_XXX internal to fs/namei.c. This changes the ENOENT errno in ksmbd_vfs_path_lookup() to EINVAL, which matches better with how this is handled by callers of filename_parentat(). Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl> Link: https://patch.msgid.link/20260528175854.57626-1-jkoolstra@xs4all.nl Reviewed-by: Amir Goldstein <amir73il@gmail.com> Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
8c47b5e9b9
commit
f2f1dddcca
20
fs/namei.c
20
fs/namei.c
|
|
@ -129,6 +129,11 @@
|
|||
static struct kmem_cache *__names_cache __ro_after_init;
|
||||
#define names_cache runtime_const_ptr(__names_cache)
|
||||
|
||||
/*
|
||||
* Type of the last component on LOOKUP_PARENT
|
||||
*/
|
||||
enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT};
|
||||
|
||||
void __init filename_init(void)
|
||||
{
|
||||
__names_cache = kmem_cache_create_usercopy("names_cache", sizeof(struct filename), 0,
|
||||
|
|
@ -3051,15 +3056,22 @@ EXPORT_SYMBOL(kern_path);
|
|||
* @flags: lookup flags
|
||||
* @parent: pointer to struct path to fill
|
||||
* @last: last component
|
||||
* @type: type of the last component
|
||||
* @root: pointer to struct path of the base directory
|
||||
*/
|
||||
int vfs_path_parent_lookup(struct filename *filename, unsigned int flags,
|
||||
struct path *parent, struct qstr *last, int *type,
|
||||
struct path *parent, struct qstr *last,
|
||||
const struct path *root)
|
||||
{
|
||||
return __filename_parentat(AT_FDCWD, filename, flags, parent, last,
|
||||
type, root);
|
||||
int type;
|
||||
int err = __filename_parentat(AT_FDCWD, filename, flags, parent, last,
|
||||
&type, root);
|
||||
if (err)
|
||||
return err;
|
||||
if (unlikely(type != LAST_NORM)) {
|
||||
path_put(parent);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_path_parent_lookup);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include <linux/sched/xacct.h>
|
||||
#include <linux/crc32c.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/splice.h>
|
||||
|
||||
#include "glob.h"
|
||||
|
|
@ -56,7 +55,7 @@ static int ksmbd_vfs_path_lookup(struct ksmbd_share_config *share_conf,
|
|||
{
|
||||
struct qstr last;
|
||||
const struct path *root_share_path = &share_conf->vfs_path;
|
||||
int err, type;
|
||||
int err;
|
||||
struct dentry *d;
|
||||
|
||||
if (pathname[0] == '\0') {
|
||||
|
|
@ -67,17 +66,11 @@ static int ksmbd_vfs_path_lookup(struct ksmbd_share_config *share_conf,
|
|||
}
|
||||
|
||||
CLASS(filename_kernel, filename)(pathname);
|
||||
err = vfs_path_parent_lookup(filename, flags,
|
||||
path, &last, &type,
|
||||
err = vfs_path_parent_lookup(filename, flags, path, &last,
|
||||
root_share_path);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (unlikely(type != LAST_NORM)) {
|
||||
path_put(path);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (for_remove) {
|
||||
err = mnt_want_write(path->mnt);
|
||||
if (err) {
|
||||
|
|
@ -668,7 +661,6 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
|
|||
struct renamedata rd;
|
||||
struct ksmbd_share_config *share_conf = work->tcon->share_conf;
|
||||
struct ksmbd_file *parent_fp;
|
||||
int new_type;
|
||||
int err, lookup_flags = LOOKUP_NO_SYMLINKS;
|
||||
|
||||
if (ksmbd_override_fsids(work))
|
||||
|
|
@ -678,8 +670,7 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
|
|||
|
||||
retry:
|
||||
err = vfs_path_parent_lookup(to, lookup_flags | LOOKUP_BENEATH,
|
||||
&new_path, &new_last, &new_type,
|
||||
&share_conf->vfs_path);
|
||||
&new_path, &new_last, &share_conf->vfs_path);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,6 @@ enum { MAX_NESTED_LINKS = 8 };
|
|||
|
||||
#define MAXSYMLINKS 40
|
||||
|
||||
/*
|
||||
* Type of the last component on LOOKUP_PARENT
|
||||
*/
|
||||
enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT};
|
||||
|
||||
/* pathwalk mode */
|
||||
#define LOOKUP_FOLLOW BIT(0) /* follow links at the end */
|
||||
#define LOOKUP_DIRECTORY BIT(1) /* require a directory */
|
||||
|
|
@ -67,7 +62,7 @@ static inline void end_removing_path(const struct path *path , struct dentry *de
|
|||
end_creating_path(path, dentry);
|
||||
}
|
||||
int vfs_path_parent_lookup(struct filename *filename, unsigned int flags,
|
||||
struct path *parent, struct qstr *last, int *type,
|
||||
struct path *parent, struct qstr *last,
|
||||
const struct path *root);
|
||||
int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *,
|
||||
unsigned int, struct path *);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user