summaryrefslogtreecommitdiff
path: root/fs/cifsd/vfs.c
diff options
context:
space:
mode:
authorHyunchul Lee <hyc.lee@gmail.com>2021-05-26 18:59:06 +0900
committerNamjae Jeon <namjae.jeon@samsung.com>2021-05-26 19:13:54 +0900
commita6a5fa77805b291afc90291a6ae705b1759b9735 (patch)
tree861dcd20a4053c9277d5c3f2110a8ed6198a6f97 /fs/cifsd/vfs.c
parentfc2d1b58c4f2c7240093d738ca99cfcf7a8b3107 (diff)
downloadlwn-a6a5fa77805b291afc90291a6ae705b1759b9735.tar.gz
lwn-a6a5fa77805b291afc90291a6ae705b1759b9735.zip
cifsd: lookup a file with LOOKUP_FOLLOW only if 'follow symlinks = yes'
Some vfs help functions lookup a file with LOOKUP_FOLLOW regardless of the "follow symlinks" option. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifsd/vfs.c')
-rw-r--r--fs/cifsd/vfs.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c
index 355e1a5a893b..291953eff5fa 100644
--- a/fs/cifsd/vfs.c
+++ b/fs/cifsd/vfs.c
@@ -572,11 +572,16 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
struct path path;
struct dentry *dentry, *parent;
int err;
+ int flags = 0;
if (ksmbd_override_fsids(work))
return -ENOMEM;
- err = kern_path(name, LOOKUP_FOLLOW, &path);
+ if (test_share_config_flag(work->tcon->share_conf,
+ KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
+ flags = LOOKUP_FOLLOW;
+
+ err = kern_path(name, flags, &path);
if (err) {
ksmbd_debug(VFS, "can't get %s, err %d\n", name, err);
ksmbd_revert_fsids(work);
@@ -634,11 +639,16 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
struct path oldpath, newpath;
struct dentry *dentry;
int err;
+ int flags = 0;
if (ksmbd_override_fsids(work))
return -ENOMEM;
- err = kern_path(oldname, LOOKUP_FOLLOW, &oldpath);
+ if (test_share_config_flag(work->tcon->share_conf,
+ KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
+ flags = LOOKUP_FOLLOW;
+
+ err = kern_path(oldname, flags, &oldpath);
if (err) {
ksmbd_err("cannot get linux path for %s, err = %d\n",
oldname, err);
@@ -646,7 +656,7 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
}
dentry = kern_path_create(AT_FDCWD, newname, &newpath,
- LOOKUP_FOLLOW | LOOKUP_REVAL);
+ flags | LOOKUP_REVAL);
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
ksmbd_err("path create err for %s, err %d\n", newname, err);
@@ -749,6 +759,7 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
struct dentry *src_dent, *trap_dent, *src_child;
char *dst_name;
int err;
+ int flags;
dst_name = extract_last_component(newname);
if (!dst_name)
@@ -757,7 +768,12 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
src_dent_parent = dget_parent(fp->filp->f_path.dentry);
src_dent = fp->filp->f_path.dentry;
- err = kern_path(newname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &dst_path);
+ flags = LOOKUP_DIRECTORY;
+ if (test_share_config_flag(work->tcon->share_conf,
+ KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS))
+ flags |= LOOKUP_FOLLOW;
+
+ err = kern_path(newname, flags, &dst_path);
if (err) {
ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err);
goto out;