cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vfs.c (45333B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
      4 *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
      5 */
      6
      7#include <linux/kernel.h>
      8#include <linux/fs.h>
      9#include <linux/uaccess.h>
     10#include <linux/backing-dev.h>
     11#include <linux/writeback.h>
     12#include <linux/xattr.h>
     13#include <linux/falloc.h>
     14#include <linux/fsnotify.h>
     15#include <linux/dcache.h>
     16#include <linux/slab.h>
     17#include <linux/vmalloc.h>
     18#include <linux/sched/xacct.h>
     19#include <linux/crc32c.h>
     20
     21#include "../internal.h"	/* for vfs_path_lookup */
     22
     23#include "glob.h"
     24#include "oplock.h"
     25#include "connection.h"
     26#include "vfs.h"
     27#include "vfs_cache.h"
     28#include "smbacl.h"
     29#include "ndr.h"
     30#include "auth.h"
     31#include "misc.h"
     32
     33#include "smb_common.h"
     34#include "mgmt/share_config.h"
     35#include "mgmt/tree_connect.h"
     36#include "mgmt/user_session.h"
     37#include "mgmt/user_config.h"
     38
     39static char *extract_last_component(char *path)
     40{
     41	char *p = strrchr(path, '/');
     42
     43	if (p && p[1] != '\0') {
     44		*p = '\0';
     45		p++;
     46	} else {
     47		p = NULL;
     48	}
     49	return p;
     50}
     51
     52static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work,
     53				    struct inode *parent_inode,
     54				    struct inode *inode)
     55{
     56	if (!test_share_config_flag(work->tcon->share_conf,
     57				    KSMBD_SHARE_FLAG_INHERIT_OWNER))
     58		return;
     59
     60	i_uid_write(inode, i_uid_read(parent_inode));
     61}
     62
     63/**
     64 * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable
     65 *
     66 * the parent dentry got by dget_parent or @parent could be
     67 * unstable, we try to lock a parent inode and lookup the
     68 * child dentry again.
     69 *
     70 * the reference count of @parent isn't incremented.
     71 */
     72int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent,
     73			  struct dentry *child)
     74{
     75	struct dentry *dentry;
     76	int ret = 0;
     77
     78	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
     79	dentry = lookup_one(user_ns, child->d_name.name, parent,
     80			    child->d_name.len);
     81	if (IS_ERR(dentry)) {
     82		ret = PTR_ERR(dentry);
     83		goto out_err;
     84	}
     85
     86	if (dentry != child) {
     87		ret = -ESTALE;
     88		dput(dentry);
     89		goto out_err;
     90	}
     91
     92	dput(dentry);
     93	return 0;
     94out_err:
     95	inode_unlock(d_inode(parent));
     96	return ret;
     97}
     98
     99int ksmbd_vfs_may_delete(struct user_namespace *user_ns,
    100			 struct dentry *dentry)
    101{
    102	struct dentry *parent;
    103	int ret;
    104
    105	parent = dget_parent(dentry);
    106	ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
    107	if (ret) {
    108		dput(parent);
    109		return ret;
    110	}
    111
    112	ret = inode_permission(user_ns, d_inode(parent),
    113			       MAY_EXEC | MAY_WRITE);
    114
    115	inode_unlock(d_inode(parent));
    116	dput(parent);
    117	return ret;
    118}
    119
    120int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
    121				   struct dentry *dentry, __le32 *daccess)
    122{
    123	struct dentry *parent;
    124	int ret = 0;
    125
    126	*daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL);
    127
    128	if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_WRITE))
    129		*daccess |= cpu_to_le32(WRITE_DAC | WRITE_OWNER | SYNCHRONIZE |
    130				FILE_WRITE_DATA | FILE_APPEND_DATA |
    131				FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES |
    132				FILE_DELETE_CHILD);
    133
    134	if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_READ))
    135		*daccess |= FILE_READ_DATA_LE | FILE_READ_EA_LE;
    136
    137	if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC))
    138		*daccess |= FILE_EXECUTE_LE;
    139
    140	parent = dget_parent(dentry);
    141	ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
    142	if (ret) {
    143		dput(parent);
    144		return ret;
    145	}
    146
    147	if (!inode_permission(user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE))
    148		*daccess |= FILE_DELETE_LE;
    149
    150	inode_unlock(d_inode(parent));
    151	dput(parent);
    152	return ret;
    153}
    154
    155/**
    156 * ksmbd_vfs_create() - vfs helper for smb create file
    157 * @work:	work
    158 * @name:	file name that is relative to share
    159 * @mode:	file create mode
    160 *
    161 * Return:	0 on success, otherwise error
    162 */
    163int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
    164{
    165	struct path path;
    166	struct dentry *dentry;
    167	int err;
    168
    169	dentry = ksmbd_vfs_kern_path_create(work, name,
    170					    LOOKUP_NO_SYMLINKS, &path);
    171	if (IS_ERR(dentry)) {
    172		err = PTR_ERR(dentry);
    173		if (err != -ENOENT)
    174			pr_err("path create failed for %s, err %d\n",
    175			       name, err);
    176		return err;
    177	}
    178
    179	mode |= S_IFREG;
    180	err = vfs_create(mnt_user_ns(path.mnt), d_inode(path.dentry),
    181			 dentry, mode, true);
    182	if (!err) {
    183		ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
    184					d_inode(dentry));
    185	} else {
    186		pr_err("File(%s): creation failed (err:%d)\n", name, err);
    187	}
    188	done_path_create(&path, dentry);
    189	return err;
    190}
    191
    192/**
    193 * ksmbd_vfs_mkdir() - vfs helper for smb create directory
    194 * @work:	work
    195 * @name:	directory name that is relative to share
    196 * @mode:	directory create mode
    197 *
    198 * Return:	0 on success, otherwise error
    199 */
    200int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
    201{
    202	struct user_namespace *user_ns;
    203	struct path path;
    204	struct dentry *dentry;
    205	int err;
    206
    207	dentry = ksmbd_vfs_kern_path_create(work, name,
    208					    LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
    209					    &path);
    210	if (IS_ERR(dentry)) {
    211		err = PTR_ERR(dentry);
    212		if (err != -EEXIST)
    213			ksmbd_debug(VFS, "path create failed for %s, err %d\n",
    214				    name, err);
    215		return err;
    216	}
    217
    218	user_ns = mnt_user_ns(path.mnt);
    219	mode |= S_IFDIR;
    220	err = vfs_mkdir(user_ns, d_inode(path.dentry), dentry, mode);
    221	if (err) {
    222		goto out;
    223	} else if (d_unhashed(dentry)) {
    224		struct dentry *d;
    225
    226		d = lookup_one(user_ns, dentry->d_name.name, dentry->d_parent,
    227			       dentry->d_name.len);
    228		if (IS_ERR(d)) {
    229			err = PTR_ERR(d);
    230			goto out;
    231		}
    232		if (unlikely(d_is_negative(d))) {
    233			dput(d);
    234			err = -ENOENT;
    235			goto out;
    236		}
    237
    238		ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d));
    239		dput(d);
    240	}
    241out:
    242	done_path_create(&path, dentry);
    243	if (err)
    244		pr_err("mkdir(%s): creation failed (err:%d)\n", name, err);
    245	return err;
    246}
    247
    248static ssize_t ksmbd_vfs_getcasexattr(struct user_namespace *user_ns,
    249				      struct dentry *dentry, char *attr_name,
    250				      int attr_name_len, char **attr_value)
    251{
    252	char *name, *xattr_list = NULL;
    253	ssize_t value_len = -ENOENT, xattr_list_len;
    254
    255	xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
    256	if (xattr_list_len <= 0)
    257		goto out;
    258
    259	for (name = xattr_list; name - xattr_list < xattr_list_len;
    260			name += strlen(name) + 1) {
    261		ksmbd_debug(VFS, "%s, len %zd\n", name, strlen(name));
    262		if (strncasecmp(attr_name, name, attr_name_len))
    263			continue;
    264
    265		value_len = ksmbd_vfs_getxattr(user_ns,
    266					       dentry,
    267					       name,
    268					       attr_value);
    269		if (value_len < 0)
    270			pr_err("failed to get xattr in file\n");
    271		break;
    272	}
    273
    274out:
    275	kvfree(xattr_list);
    276	return value_len;
    277}
    278
    279static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos,
    280				 size_t count)
    281{
    282	ssize_t v_len;
    283	char *stream_buf = NULL;
    284
    285	ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n",
    286		    *pos, count);
    287
    288	v_len = ksmbd_vfs_getcasexattr(file_mnt_user_ns(fp->filp),
    289				       fp->filp->f_path.dentry,
    290				       fp->stream.name,
    291				       fp->stream.size,
    292				       &stream_buf);
    293	if ((int)v_len <= 0)
    294		return (int)v_len;
    295
    296	if (v_len <= *pos) {
    297		count = -EINVAL;
    298		goto free_buf;
    299	}
    300
    301	if (v_len - *pos < count)
    302		count = v_len - *pos;
    303
    304	memcpy(buf, &stream_buf[*pos], count);
    305
    306free_buf:
    307	kvfree(stream_buf);
    308	return count;
    309}
    310
    311/**
    312 * check_lock_range() - vfs helper for smb byte range file locking
    313 * @filp:	the file to apply the lock to
    314 * @start:	lock start byte offset
    315 * @end:	lock end byte offset
    316 * @type:	byte range type read/write
    317 *
    318 * Return:	0 on success, otherwise error
    319 */
    320static int check_lock_range(struct file *filp, loff_t start, loff_t end,
    321			    unsigned char type)
    322{
    323	struct file_lock *flock;
    324	struct file_lock_context *ctx = file_inode(filp)->i_flctx;
    325	int error = 0;
    326
    327	if (!ctx || list_empty_careful(&ctx->flc_posix))
    328		return 0;
    329
    330	spin_lock(&ctx->flc_lock);
    331	list_for_each_entry(flock, &ctx->flc_posix, fl_list) {
    332		/* check conflict locks */
    333		if (flock->fl_end >= start && end >= flock->fl_start) {
    334			if (flock->fl_type == F_RDLCK) {
    335				if (type == WRITE) {
    336					pr_err("not allow write by shared lock\n");
    337					error = 1;
    338					goto out;
    339				}
    340			} else if (flock->fl_type == F_WRLCK) {
    341				/* check owner in lock */
    342				if (flock->fl_file != filp) {
    343					error = 1;
    344					pr_err("not allow rw access by exclusive lock from other opens\n");
    345					goto out;
    346				}
    347			}
    348		}
    349	}
    350out:
    351	spin_unlock(&ctx->flc_lock);
    352	return error;
    353}
    354
    355/**
    356 * ksmbd_vfs_read() - vfs helper for smb file read
    357 * @work:	smb work
    358 * @fid:	file id of open file
    359 * @count:	read byte count
    360 * @pos:	file pos
    361 *
    362 * Return:	number of read bytes on success, otherwise error
    363 */
    364int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
    365		   loff_t *pos)
    366{
    367	struct file *filp = fp->filp;
    368	ssize_t nbytes = 0;
    369	char *rbuf = work->aux_payload_buf;
    370	struct inode *inode = file_inode(filp);
    371
    372	if (S_ISDIR(inode->i_mode))
    373		return -EISDIR;
    374
    375	if (unlikely(count == 0))
    376		return 0;
    377
    378	if (work->conn->connection_type) {
    379		if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) {
    380			pr_err("no right to read(%pd)\n",
    381			       fp->filp->f_path.dentry);
    382			return -EACCES;
    383		}
    384	}
    385
    386	if (ksmbd_stream_fd(fp))
    387		return ksmbd_vfs_stream_read(fp, rbuf, pos, count);
    388
    389	if (!work->tcon->posix_extensions) {
    390		int ret;
    391
    392		ret = check_lock_range(filp, *pos, *pos + count - 1, READ);
    393		if (ret) {
    394			pr_err("unable to read due to lock\n");
    395			return -EAGAIN;
    396		}
    397	}
    398
    399	nbytes = kernel_read(filp, rbuf, count, pos);
    400	if (nbytes < 0) {
    401		pr_err("smb read failed, err = %zd\n", nbytes);
    402		return nbytes;
    403	}
    404
    405	filp->f_pos = *pos;
    406	return nbytes;
    407}
    408
    409static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
    410				  size_t count)
    411{
    412	char *stream_buf = NULL, *wbuf;
    413	struct user_namespace *user_ns = file_mnt_user_ns(fp->filp);
    414	size_t size, v_len;
    415	int err = 0;
    416
    417	ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n",
    418		    *pos, count);
    419
    420	size = *pos + count;
    421	if (size > XATTR_SIZE_MAX) {
    422		size = XATTR_SIZE_MAX;
    423		count = (*pos + count) - XATTR_SIZE_MAX;
    424	}
    425
    426	v_len = ksmbd_vfs_getcasexattr(user_ns,
    427				       fp->filp->f_path.dentry,
    428				       fp->stream.name,
    429				       fp->stream.size,
    430				       &stream_buf);
    431	if ((int)v_len < 0) {
    432		pr_err("not found stream in xattr : %zd\n", v_len);
    433		err = (int)v_len;
    434		goto out;
    435	}
    436
    437	if (v_len < size) {
    438		wbuf = kvmalloc(size, GFP_KERNEL | __GFP_ZERO);
    439		if (!wbuf) {
    440			err = -ENOMEM;
    441			goto out;
    442		}
    443
    444		if (v_len > 0)
    445			memcpy(wbuf, stream_buf, v_len);
    446		kvfree(stream_buf);
    447		stream_buf = wbuf;
    448	}
    449
    450	memcpy(&stream_buf[*pos], buf, count);
    451
    452	err = ksmbd_vfs_setxattr(user_ns,
    453				 fp->filp->f_path.dentry,
    454				 fp->stream.name,
    455				 (void *)stream_buf,
    456				 size,
    457				 0);
    458	if (err < 0)
    459		goto out;
    460
    461	fp->filp->f_pos = *pos;
    462	err = 0;
    463out:
    464	kvfree(stream_buf);
    465	return err;
    466}
    467
    468/**
    469 * ksmbd_vfs_write() - vfs helper for smb file write
    470 * @work:	work
    471 * @fid:	file id of open file
    472 * @buf:	buf containing data for writing
    473 * @count:	read byte count
    474 * @pos:	file pos
    475 * @sync:	fsync after write
    476 * @written:	number of bytes written
    477 *
    478 * Return:	0 on success, otherwise error
    479 */
    480int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
    481		    char *buf, size_t count, loff_t *pos, bool sync,
    482		    ssize_t *written)
    483{
    484	struct ksmbd_session *sess = work->sess;
    485	struct file *filp;
    486	loff_t	offset = *pos;
    487	int err = 0;
    488
    489	if (sess->conn->connection_type) {
    490		if (!(fp->daccess & FILE_WRITE_DATA_LE)) {
    491			pr_err("no right to write(%pd)\n",
    492			       fp->filp->f_path.dentry);
    493			err = -EACCES;
    494			goto out;
    495		}
    496	}
    497
    498	filp = fp->filp;
    499
    500	if (ksmbd_stream_fd(fp)) {
    501		err = ksmbd_vfs_stream_write(fp, buf, pos, count);
    502		if (!err)
    503			*written = count;
    504		goto out;
    505	}
    506
    507	if (!work->tcon->posix_extensions) {
    508		err = check_lock_range(filp, *pos, *pos + count - 1, WRITE);
    509		if (err) {
    510			pr_err("unable to write due to lock\n");
    511			err = -EAGAIN;
    512			goto out;
    513		}
    514	}
    515
    516	/* Do we need to break any of a levelII oplock? */
    517	smb_break_all_levII_oplock(work, fp, 1);
    518
    519	err = kernel_write(filp, buf, count, pos);
    520	if (err < 0) {
    521		ksmbd_debug(VFS, "smb write failed, err = %d\n", err);
    522		goto out;
    523	}
    524
    525	filp->f_pos = *pos;
    526	*written = err;
    527	err = 0;
    528	if (sync) {
    529		err = vfs_fsync_range(filp, offset, offset + *written, 0);
    530		if (err < 0)
    531			pr_err("fsync failed for filename = %pd, err = %d\n",
    532			       fp->filp->f_path.dentry, err);
    533	}
    534
    535out:
    536	return err;
    537}
    538
    539/**
    540 * ksmbd_vfs_getattr() - vfs helper for smb getattr
    541 * @work:	work
    542 * @fid:	file id of open file
    543 * @attrs:	inode attributes
    544 *
    545 * Return:	0 on success, otherwise error
    546 */
    547int ksmbd_vfs_getattr(struct path *path, struct kstat *stat)
    548{
    549	int err;
    550
    551	err = vfs_getattr(path, stat, STATX_BTIME, AT_STATX_SYNC_AS_STAT);
    552	if (err)
    553		pr_err("getattr failed, err %d\n", err);
    554	return err;
    555}
    556
    557/**
    558 * ksmbd_vfs_fsync() - vfs helper for smb fsync
    559 * @work:	work
    560 * @fid:	file id of open file
    561 *
    562 * Return:	0 on success, otherwise error
    563 */
    564int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id)
    565{
    566	struct ksmbd_file *fp;
    567	int err;
    568
    569	fp = ksmbd_lookup_fd_slow(work, fid, p_id);
    570	if (!fp) {
    571		pr_err("failed to get filp for fid %llu\n", fid);
    572		return -ENOENT;
    573	}
    574	err = vfs_fsync(fp->filp, 0);
    575	if (err < 0)
    576		pr_err("smb fsync failed, err = %d\n", err);
    577	ksmbd_fd_put(work, fp);
    578	return err;
    579}
    580
    581/**
    582 * ksmbd_vfs_remove_file() - vfs helper for smb rmdir or unlink
    583 * @name:	directory or file name that is relative to share
    584 *
    585 * Return:	0 on success, otherwise error
    586 */
    587int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
    588{
    589	struct user_namespace *user_ns;
    590	struct path path;
    591	struct dentry *parent;
    592	int err;
    593
    594	if (ksmbd_override_fsids(work))
    595		return -ENOMEM;
    596
    597	err = ksmbd_vfs_kern_path(work, name, LOOKUP_NO_SYMLINKS, &path, false);
    598	if (err) {
    599		ksmbd_debug(VFS, "can't get %s, err %d\n", name, err);
    600		ksmbd_revert_fsids(work);
    601		return err;
    602	}
    603
    604	user_ns = mnt_user_ns(path.mnt);
    605	parent = dget_parent(path.dentry);
    606	err = ksmbd_vfs_lock_parent(user_ns, parent, path.dentry);
    607	if (err) {
    608		dput(parent);
    609		path_put(&path);
    610		ksmbd_revert_fsids(work);
    611		return err;
    612	}
    613
    614	if (!d_inode(path.dentry)->i_nlink) {
    615		err = -ENOENT;
    616		goto out_err;
    617	}
    618
    619	if (S_ISDIR(d_inode(path.dentry)->i_mode)) {
    620		err = vfs_rmdir(user_ns, d_inode(parent), path.dentry);
    621		if (err && err != -ENOTEMPTY)
    622			ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name,
    623				    err);
    624	} else {
    625		err = vfs_unlink(user_ns, d_inode(parent), path.dentry, NULL);
    626		if (err)
    627			ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name,
    628				    err);
    629	}
    630
    631out_err:
    632	inode_unlock(d_inode(parent));
    633	dput(parent);
    634	path_put(&path);
    635	ksmbd_revert_fsids(work);
    636	return err;
    637}
    638
    639/**
    640 * ksmbd_vfs_link() - vfs helper for creating smb hardlink
    641 * @oldname:	source file name
    642 * @newname:	hardlink name that is relative to share
    643 *
    644 * Return:	0 on success, otherwise error
    645 */
    646int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
    647		   const char *newname)
    648{
    649	struct path oldpath, newpath;
    650	struct dentry *dentry;
    651	int err;
    652
    653	if (ksmbd_override_fsids(work))
    654		return -ENOMEM;
    655
    656	err = kern_path(oldname, LOOKUP_NO_SYMLINKS, &oldpath);
    657	if (err) {
    658		pr_err("cannot get linux path for %s, err = %d\n",
    659		       oldname, err);
    660		goto out1;
    661	}
    662
    663	dentry = ksmbd_vfs_kern_path_create(work, newname,
    664					    LOOKUP_NO_SYMLINKS | LOOKUP_REVAL,
    665					    &newpath);
    666	if (IS_ERR(dentry)) {
    667		err = PTR_ERR(dentry);
    668		pr_err("path create err for %s, err %d\n", newname, err);
    669		goto out2;
    670	}
    671
    672	err = -EXDEV;
    673	if (oldpath.mnt != newpath.mnt) {
    674		pr_err("vfs_link failed err %d\n", err);
    675		goto out3;
    676	}
    677
    678	err = vfs_link(oldpath.dentry, mnt_user_ns(newpath.mnt),
    679		       d_inode(newpath.dentry),
    680		       dentry, NULL);
    681	if (err)
    682		ksmbd_debug(VFS, "vfs_link failed err %d\n", err);
    683
    684out3:
    685	done_path_create(&newpath, dentry);
    686out2:
    687	path_put(&oldpath);
    688out1:
    689	ksmbd_revert_fsids(work);
    690	return err;
    691}
    692
    693static int ksmbd_validate_entry_in_use(struct dentry *src_dent)
    694{
    695	struct dentry *dst_dent;
    696
    697	spin_lock(&src_dent->d_lock);
    698	list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) {
    699		struct ksmbd_file *child_fp;
    700
    701		if (d_really_is_negative(dst_dent))
    702			continue;
    703
    704		child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent));
    705		if (child_fp) {
    706			spin_unlock(&src_dent->d_lock);
    707			ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n");
    708			return -EACCES;
    709		}
    710	}
    711	spin_unlock(&src_dent->d_lock);
    712
    713	return 0;
    714}
    715
    716static int __ksmbd_vfs_rename(struct ksmbd_work *work,
    717			      struct user_namespace *src_user_ns,
    718			      struct dentry *src_dent_parent,
    719			      struct dentry *src_dent,
    720			      struct user_namespace *dst_user_ns,
    721			      struct dentry *dst_dent_parent,
    722			      struct dentry *trap_dent,
    723			      char *dst_name)
    724{
    725	struct dentry *dst_dent;
    726	int err;
    727
    728	if (!work->tcon->posix_extensions) {
    729		err = ksmbd_validate_entry_in_use(src_dent);
    730		if (err)
    731			return err;
    732	}
    733
    734	if (d_really_is_negative(src_dent_parent))
    735		return -ENOENT;
    736	if (d_really_is_negative(dst_dent_parent))
    737		return -ENOENT;
    738	if (d_really_is_negative(src_dent))
    739		return -ENOENT;
    740	if (src_dent == trap_dent)
    741		return -EINVAL;
    742
    743	if (ksmbd_override_fsids(work))
    744		return -ENOMEM;
    745
    746	dst_dent = lookup_one(dst_user_ns, dst_name, dst_dent_parent,
    747			      strlen(dst_name));
    748	err = PTR_ERR(dst_dent);
    749	if (IS_ERR(dst_dent)) {
    750		pr_err("lookup failed %s [%d]\n", dst_name, err);
    751		goto out;
    752	}
    753
    754	err = -ENOTEMPTY;
    755	if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) {
    756		struct renamedata rd = {
    757			.old_mnt_userns	= src_user_ns,
    758			.old_dir	= d_inode(src_dent_parent),
    759			.old_dentry	= src_dent,
    760			.new_mnt_userns	= dst_user_ns,
    761			.new_dir	= d_inode(dst_dent_parent),
    762			.new_dentry	= dst_dent,
    763		};
    764		err = vfs_rename(&rd);
    765	}
    766	if (err)
    767		pr_err("vfs_rename failed err %d\n", err);
    768	if (dst_dent)
    769		dput(dst_dent);
    770out:
    771	ksmbd_revert_fsids(work);
    772	return err;
    773}
    774
    775int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
    776			char *newname)
    777{
    778	struct user_namespace *user_ns;
    779	struct path dst_path;
    780	struct dentry *src_dent_parent, *dst_dent_parent;
    781	struct dentry *src_dent, *trap_dent, *src_child;
    782	char *dst_name;
    783	int err;
    784
    785	dst_name = extract_last_component(newname);
    786	if (!dst_name) {
    787		dst_name = newname;
    788		newname = "";
    789	}
    790
    791	src_dent_parent = dget_parent(fp->filp->f_path.dentry);
    792	src_dent = fp->filp->f_path.dentry;
    793
    794	err = ksmbd_vfs_kern_path(work, newname,
    795				  LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
    796				  &dst_path, false);
    797	if (err) {
    798		ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err);
    799		goto out;
    800	}
    801	dst_dent_parent = dst_path.dentry;
    802
    803	trap_dent = lock_rename(src_dent_parent, dst_dent_parent);
    804	dget(src_dent);
    805	dget(dst_dent_parent);
    806	user_ns = file_mnt_user_ns(fp->filp);
    807	src_child = lookup_one(user_ns, src_dent->d_name.name, src_dent_parent,
    808			       src_dent->d_name.len);
    809	if (IS_ERR(src_child)) {
    810		err = PTR_ERR(src_child);
    811		goto out_lock;
    812	}
    813
    814	if (src_child != src_dent) {
    815		err = -ESTALE;
    816		dput(src_child);
    817		goto out_lock;
    818	}
    819	dput(src_child);
    820
    821	err = __ksmbd_vfs_rename(work,
    822				 user_ns,
    823				 src_dent_parent,
    824				 src_dent,
    825				 mnt_user_ns(dst_path.mnt),
    826				 dst_dent_parent,
    827				 trap_dent,
    828				 dst_name);
    829out_lock:
    830	dput(src_dent);
    831	dput(dst_dent_parent);
    832	unlock_rename(src_dent_parent, dst_dent_parent);
    833	path_put(&dst_path);
    834out:
    835	dput(src_dent_parent);
    836	return err;
    837}
    838
    839/**
    840 * ksmbd_vfs_truncate() - vfs helper for smb file truncate
    841 * @work:	work
    842 * @fid:	file id of old file
    843 * @size:	truncate to given size
    844 *
    845 * Return:	0 on success, otherwise error
    846 */
    847int ksmbd_vfs_truncate(struct ksmbd_work *work,
    848		       struct ksmbd_file *fp, loff_t size)
    849{
    850	int err = 0;
    851	struct file *filp;
    852
    853	filp = fp->filp;
    854
    855	/* Do we need to break any of a levelII oplock? */
    856	smb_break_all_levII_oplock(work, fp, 1);
    857
    858	if (!work->tcon->posix_extensions) {
    859		struct inode *inode = file_inode(filp);
    860
    861		if (size < inode->i_size) {
    862			err = check_lock_range(filp, size,
    863					       inode->i_size - 1, WRITE);
    864		} else {
    865			err = check_lock_range(filp, inode->i_size,
    866					       size - 1, WRITE);
    867		}
    868
    869		if (err) {
    870			pr_err("failed due to lock\n");
    871			return -EAGAIN;
    872		}
    873	}
    874
    875	err = vfs_truncate(&filp->f_path, size);
    876	if (err)
    877		pr_err("truncate failed, err %d\n", err);
    878	return err;
    879}
    880
    881/**
    882 * ksmbd_vfs_listxattr() - vfs helper for smb list extended attributes
    883 * @dentry:	dentry of file for listing xattrs
    884 * @list:	destination buffer
    885 * @size:	destination buffer length
    886 *
    887 * Return:	xattr list length on success, otherwise error
    888 */
    889ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
    890{
    891	ssize_t size;
    892	char *vlist = NULL;
    893
    894	size = vfs_listxattr(dentry, NULL, 0);
    895	if (size <= 0)
    896		return size;
    897
    898	vlist = kvmalloc(size, GFP_KERNEL | __GFP_ZERO);
    899	if (!vlist)
    900		return -ENOMEM;
    901
    902	*list = vlist;
    903	size = vfs_listxattr(dentry, vlist, size);
    904	if (size < 0) {
    905		ksmbd_debug(VFS, "listxattr failed\n");
    906		kvfree(vlist);
    907		*list = NULL;
    908	}
    909
    910	return size;
    911}
    912
    913static ssize_t ksmbd_vfs_xattr_len(struct user_namespace *user_ns,
    914				   struct dentry *dentry, char *xattr_name)
    915{
    916	return vfs_getxattr(user_ns, dentry, xattr_name, NULL, 0);
    917}
    918
    919/**
    920 * ksmbd_vfs_getxattr() - vfs helper for smb get extended attributes value
    921 * @user_ns:	user namespace
    922 * @dentry:	dentry of file for getting xattrs
    923 * @xattr_name:	name of xattr name to query
    924 * @xattr_buf:	destination buffer xattr value
    925 *
    926 * Return:	read xattr value length on success, otherwise error
    927 */
    928ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns,
    929			   struct dentry *dentry,
    930			   char *xattr_name, char **xattr_buf)
    931{
    932	ssize_t xattr_len;
    933	char *buf;
    934
    935	*xattr_buf = NULL;
    936	xattr_len = ksmbd_vfs_xattr_len(user_ns, dentry, xattr_name);
    937	if (xattr_len < 0)
    938		return xattr_len;
    939
    940	buf = kmalloc(xattr_len + 1, GFP_KERNEL);
    941	if (!buf)
    942		return -ENOMEM;
    943
    944	xattr_len = vfs_getxattr(user_ns, dentry, xattr_name,
    945				 (void *)buf, xattr_len);
    946	if (xattr_len > 0)
    947		*xattr_buf = buf;
    948	else
    949		kfree(buf);
    950	return xattr_len;
    951}
    952
    953/**
    954 * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value
    955 * @user_ns:	user namespace
    956 * @dentry:	dentry to set XATTR at
    957 * @name:	xattr name for setxattr
    958 * @value:	xattr value to set
    959 * @size:	size of xattr value
    960 * @flags:	destination buffer length
    961 *
    962 * Return:	0 on success, otherwise error
    963 */
    964int ksmbd_vfs_setxattr(struct user_namespace *user_ns,
    965		       struct dentry *dentry, const char *attr_name,
    966		       const void *attr_value, size_t attr_size, int flags)
    967{
    968	int err;
    969
    970	err = vfs_setxattr(user_ns,
    971			   dentry,
    972			   attr_name,
    973			   attr_value,
    974			   attr_size,
    975			   flags);
    976	if (err)
    977		ksmbd_debug(VFS, "setxattr failed, err %d\n", err);
    978	return err;
    979}
    980
    981/**
    982 * ksmbd_vfs_set_fadvise() - convert smb IO caching options to linux options
    983 * @filp:	file pointer for IO
    984 * @options:	smb IO options
    985 */
    986void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option)
    987{
    988	struct address_space *mapping;
    989
    990	mapping = filp->f_mapping;
    991
    992	if (!option || !mapping)
    993		return;
    994
    995	if (option & FILE_WRITE_THROUGH_LE) {
    996		filp->f_flags |= O_SYNC;
    997	} else if (option & FILE_SEQUENTIAL_ONLY_LE) {
    998		filp->f_ra.ra_pages = inode_to_bdi(mapping->host)->ra_pages * 2;
    999		spin_lock(&filp->f_lock);
   1000		filp->f_mode &= ~FMODE_RANDOM;
   1001		spin_unlock(&filp->f_lock);
   1002	} else if (option & FILE_RANDOM_ACCESS_LE) {
   1003		spin_lock(&filp->f_lock);
   1004		filp->f_mode |= FMODE_RANDOM;
   1005		spin_unlock(&filp->f_lock);
   1006	}
   1007}
   1008
   1009int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp,
   1010			loff_t off, loff_t len)
   1011{
   1012	smb_break_all_levII_oplock(work, fp, 1);
   1013	if (fp->f_ci->m_fattr & FILE_ATTRIBUTE_SPARSE_FILE_LE)
   1014		return vfs_fallocate(fp->filp,
   1015				     FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
   1016				     off, len);
   1017
   1018	return vfs_fallocate(fp->filp,
   1019			     FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE,
   1020			     off, len);
   1021}
   1022
   1023int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
   1024			 struct file_allocated_range_buffer *ranges,
   1025			 unsigned int in_count, unsigned int *out_count)
   1026{
   1027	struct file *f = fp->filp;
   1028	struct inode *inode = file_inode(fp->filp);
   1029	loff_t maxbytes = (u64)inode->i_sb->s_maxbytes, end;
   1030	loff_t extent_start, extent_end;
   1031	int ret = 0;
   1032
   1033	if (start > maxbytes)
   1034		return -EFBIG;
   1035
   1036	if (!in_count)
   1037		return 0;
   1038
   1039	/*
   1040	 * Shrink request scope to what the fs can actually handle.
   1041	 */
   1042	if (length > maxbytes || (maxbytes - length) < start)
   1043		length = maxbytes - start;
   1044
   1045	if (start + length > inode->i_size)
   1046		length = inode->i_size - start;
   1047
   1048	*out_count = 0;
   1049	end = start + length;
   1050	while (start < end && *out_count < in_count) {
   1051		extent_start = vfs_llseek(f, start, SEEK_DATA);
   1052		if (extent_start < 0) {
   1053			if (extent_start != -ENXIO)
   1054				ret = (int)extent_start;
   1055			break;
   1056		}
   1057
   1058		if (extent_start >= end)
   1059			break;
   1060
   1061		extent_end = vfs_llseek(f, extent_start, SEEK_HOLE);
   1062		if (extent_end < 0) {
   1063			if (extent_end != -ENXIO)
   1064				ret = (int)extent_end;
   1065			break;
   1066		} else if (extent_start >= extent_end) {
   1067			break;
   1068		}
   1069
   1070		ranges[*out_count].file_offset = cpu_to_le64(extent_start);
   1071		ranges[(*out_count)++].length =
   1072			cpu_to_le64(min(extent_end, end) - extent_start);
   1073
   1074		start = extent_end;
   1075	}
   1076
   1077	return ret;
   1078}
   1079
   1080int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
   1081			   struct dentry *dentry, char *attr_name)
   1082{
   1083	return vfs_removexattr(user_ns, dentry, attr_name);
   1084}
   1085
   1086int ksmbd_vfs_unlink(struct user_namespace *user_ns,
   1087		     struct dentry *dir, struct dentry *dentry)
   1088{
   1089	int err = 0;
   1090
   1091	err = ksmbd_vfs_lock_parent(user_ns, dir, dentry);
   1092	if (err)
   1093		return err;
   1094	dget(dentry);
   1095
   1096	if (S_ISDIR(d_inode(dentry)->i_mode))
   1097		err = vfs_rmdir(user_ns, d_inode(dir), dentry);
   1098	else
   1099		err = vfs_unlink(user_ns, d_inode(dir), dentry, NULL);
   1100
   1101	dput(dentry);
   1102	inode_unlock(d_inode(dir));
   1103	if (err)
   1104		ksmbd_debug(VFS, "failed to delete, err %d\n", err);
   1105
   1106	return err;
   1107}
   1108
   1109static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
   1110		       loff_t offset, u64 ino, unsigned int d_type)
   1111{
   1112	struct ksmbd_readdir_data *buf;
   1113
   1114	buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
   1115	buf->dirent_count++;
   1116
   1117	if (buf->dirent_count > 2)
   1118		return -ENOTEMPTY;
   1119	return 0;
   1120}
   1121
   1122/**
   1123 * ksmbd_vfs_empty_dir() - check for empty directory
   1124 * @fp:	ksmbd file pointer
   1125 *
   1126 * Return:	true if directory empty, otherwise false
   1127 */
   1128int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
   1129{
   1130	int err;
   1131	struct ksmbd_readdir_data readdir_data;
   1132
   1133	memset(&readdir_data, 0, sizeof(struct ksmbd_readdir_data));
   1134
   1135	set_ctx_actor(&readdir_data.ctx, __dir_empty);
   1136	readdir_data.dirent_count = 0;
   1137
   1138	err = iterate_dir(fp->filp, &readdir_data.ctx);
   1139	if (readdir_data.dirent_count > 2)
   1140		err = -ENOTEMPTY;
   1141	else
   1142		err = 0;
   1143	return err;
   1144}
   1145
   1146static int __caseless_lookup(struct dir_context *ctx, const char *name,
   1147			     int namlen, loff_t offset, u64 ino,
   1148			     unsigned int d_type)
   1149{
   1150	struct ksmbd_readdir_data *buf;
   1151
   1152	buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
   1153
   1154	if (buf->used != namlen)
   1155		return 0;
   1156	if (!strncasecmp((char *)buf->private, name, namlen)) {
   1157		memcpy((char *)buf->private, name, namlen);
   1158		buf->dirent_count = 1;
   1159		return -EEXIST;
   1160	}
   1161	return 0;
   1162}
   1163
   1164/**
   1165 * ksmbd_vfs_lookup_in_dir() - lookup a file in a directory
   1166 * @dir:	path info
   1167 * @name:	filename to lookup
   1168 * @namelen:	filename length
   1169 *
   1170 * Return:	0 on success, otherwise error
   1171 */
   1172static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen)
   1173{
   1174	int ret;
   1175	struct file *dfilp;
   1176	int flags = O_RDONLY | O_LARGEFILE;
   1177	struct ksmbd_readdir_data readdir_data = {
   1178		.ctx.actor	= __caseless_lookup,
   1179		.private	= name,
   1180		.used		= namelen,
   1181		.dirent_count	= 0,
   1182	};
   1183
   1184	dfilp = dentry_open(dir, flags, current_cred());
   1185	if (IS_ERR(dfilp))
   1186		return PTR_ERR(dfilp);
   1187
   1188	ret = iterate_dir(dfilp, &readdir_data.ctx);
   1189	if (readdir_data.dirent_count > 0)
   1190		ret = 0;
   1191	fput(dfilp);
   1192	return ret;
   1193}
   1194
   1195/**
   1196 * ksmbd_vfs_kern_path() - lookup a file and get path info
   1197 * @name:	file path that is relative to share
   1198 * @flags:	lookup flags
   1199 * @path:	if lookup succeed, return path info
   1200 * @caseless:	caseless filename lookup
   1201 *
   1202 * Return:	0 on success, otherwise error
   1203 */
   1204int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name,
   1205			unsigned int flags, struct path *path, bool caseless)
   1206{
   1207	struct ksmbd_share_config *share_conf = work->tcon->share_conf;
   1208	int err;
   1209
   1210	flags |= LOOKUP_BENEATH;
   1211	err = vfs_path_lookup(share_conf->vfs_path.dentry,
   1212			      share_conf->vfs_path.mnt,
   1213			      name,
   1214			      flags,
   1215			      path);
   1216	if (!err)
   1217		return 0;
   1218
   1219	if (caseless) {
   1220		char *filepath;
   1221		struct path parent;
   1222		size_t path_len, remain_len;
   1223
   1224		filepath = kstrdup(name, GFP_KERNEL);
   1225		if (!filepath)
   1226			return -ENOMEM;
   1227
   1228		path_len = strlen(filepath);
   1229		remain_len = path_len;
   1230
   1231		parent = share_conf->vfs_path;
   1232		path_get(&parent);
   1233
   1234		while (d_can_lookup(parent.dentry)) {
   1235			char *filename = filepath + path_len - remain_len;
   1236			char *next = strchrnul(filename, '/');
   1237			size_t filename_len = next - filename;
   1238			bool is_last = !next[0];
   1239
   1240			if (filename_len == 0)
   1241				break;
   1242
   1243			err = ksmbd_vfs_lookup_in_dir(&parent, filename,
   1244						      filename_len);
   1245			path_put(&parent);
   1246			if (err)
   1247				goto out;
   1248
   1249			next[0] = '\0';
   1250
   1251			err = vfs_path_lookup(share_conf->vfs_path.dentry,
   1252					      share_conf->vfs_path.mnt,
   1253					      filepath,
   1254					      flags,
   1255					      &parent);
   1256			if (err)
   1257				goto out;
   1258			else if (is_last) {
   1259				*path = parent;
   1260				goto out;
   1261			}
   1262
   1263			next[0] = '/';
   1264			remain_len -= filename_len + 1;
   1265		}
   1266
   1267		path_put(&parent);
   1268		err = -EINVAL;
   1269out:
   1270		kfree(filepath);
   1271	}
   1272	return err;
   1273}
   1274
   1275struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
   1276					  const char *name,
   1277					  unsigned int flags,
   1278					  struct path *path)
   1279{
   1280	char *abs_name;
   1281	struct dentry *dent;
   1282
   1283	abs_name = convert_to_unix_name(work->tcon->share_conf, name);
   1284	if (!abs_name)
   1285		return ERR_PTR(-ENOMEM);
   1286
   1287	dent = kern_path_create(AT_FDCWD, abs_name, path, flags);
   1288	kfree(abs_name);
   1289	return dent;
   1290}
   1291
   1292int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns,
   1293				struct dentry *dentry)
   1294{
   1295	char *name, *xattr_list = NULL;
   1296	ssize_t xattr_list_len;
   1297	int err = 0;
   1298
   1299	xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
   1300	if (xattr_list_len < 0) {
   1301		goto out;
   1302	} else if (!xattr_list_len) {
   1303		ksmbd_debug(SMB, "empty xattr in the file\n");
   1304		goto out;
   1305	}
   1306
   1307	for (name = xattr_list; name - xattr_list < xattr_list_len;
   1308	     name += strlen(name) + 1) {
   1309		ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
   1310
   1311		if (!strncmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
   1312			     sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) ||
   1313		    !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
   1314			     sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
   1315			err = ksmbd_vfs_remove_xattr(user_ns, dentry, name);
   1316			if (err)
   1317				ksmbd_debug(SMB,
   1318					    "remove acl xattr failed : %s\n", name);
   1319		}
   1320	}
   1321out:
   1322	kvfree(xattr_list);
   1323	return err;
   1324}
   1325
   1326int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns,
   1327			       struct dentry *dentry)
   1328{
   1329	char *name, *xattr_list = NULL;
   1330	ssize_t xattr_list_len;
   1331	int err = 0;
   1332
   1333	xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
   1334	if (xattr_list_len < 0) {
   1335		goto out;
   1336	} else if (!xattr_list_len) {
   1337		ksmbd_debug(SMB, "empty xattr in the file\n");
   1338		goto out;
   1339	}
   1340
   1341	for (name = xattr_list; name - xattr_list < xattr_list_len;
   1342			name += strlen(name) + 1) {
   1343		ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
   1344
   1345		if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
   1346			err = ksmbd_vfs_remove_xattr(user_ns, dentry, name);
   1347			if (err)
   1348				ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
   1349		}
   1350	}
   1351out:
   1352	kvfree(xattr_list);
   1353	return err;
   1354}
   1355
   1356static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct user_namespace *user_ns,
   1357							    struct inode *inode,
   1358							    int acl_type)
   1359{
   1360	struct xattr_smb_acl *smb_acl = NULL;
   1361	struct posix_acl *posix_acls;
   1362	struct posix_acl_entry *pa_entry;
   1363	struct xattr_acl_entry *xa_entry;
   1364	int i;
   1365
   1366	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL))
   1367		return NULL;
   1368
   1369	posix_acls = get_acl(inode, acl_type);
   1370	if (!posix_acls)
   1371		return NULL;
   1372
   1373	smb_acl = kzalloc(sizeof(struct xattr_smb_acl) +
   1374			  sizeof(struct xattr_acl_entry) * posix_acls->a_count,
   1375			  GFP_KERNEL);
   1376	if (!smb_acl)
   1377		goto out;
   1378
   1379	smb_acl->count = posix_acls->a_count;
   1380	pa_entry = posix_acls->a_entries;
   1381	xa_entry = smb_acl->entries;
   1382	for (i = 0; i < posix_acls->a_count; i++, pa_entry++, xa_entry++) {
   1383		switch (pa_entry->e_tag) {
   1384		case ACL_USER:
   1385			xa_entry->type = SMB_ACL_USER;
   1386			xa_entry->uid = posix_acl_uid_translate(user_ns, pa_entry);
   1387			break;
   1388		case ACL_USER_OBJ:
   1389			xa_entry->type = SMB_ACL_USER_OBJ;
   1390			break;
   1391		case ACL_GROUP:
   1392			xa_entry->type = SMB_ACL_GROUP;
   1393			xa_entry->gid = posix_acl_gid_translate(user_ns, pa_entry);
   1394			break;
   1395		case ACL_GROUP_OBJ:
   1396			xa_entry->type = SMB_ACL_GROUP_OBJ;
   1397			break;
   1398		case ACL_OTHER:
   1399			xa_entry->type = SMB_ACL_OTHER;
   1400			break;
   1401		case ACL_MASK:
   1402			xa_entry->type = SMB_ACL_MASK;
   1403			break;
   1404		default:
   1405			pr_err("unknown type : 0x%x\n", pa_entry->e_tag);
   1406			goto out;
   1407		}
   1408
   1409		if (pa_entry->e_perm & ACL_READ)
   1410			xa_entry->perm |= SMB_ACL_READ;
   1411		if (pa_entry->e_perm & ACL_WRITE)
   1412			xa_entry->perm |= SMB_ACL_WRITE;
   1413		if (pa_entry->e_perm & ACL_EXECUTE)
   1414			xa_entry->perm |= SMB_ACL_EXECUTE;
   1415	}
   1416out:
   1417	posix_acl_release(posix_acls);
   1418	return smb_acl;
   1419}
   1420
   1421int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
   1422			   struct user_namespace *user_ns,
   1423			   struct dentry *dentry,
   1424			   struct smb_ntsd *pntsd, int len)
   1425{
   1426	int rc;
   1427	struct ndr sd_ndr = {0}, acl_ndr = {0};
   1428	struct xattr_ntacl acl = {0};
   1429	struct xattr_smb_acl *smb_acl, *def_smb_acl = NULL;
   1430	struct inode *inode = d_inode(dentry);
   1431
   1432	acl.version = 4;
   1433	acl.hash_type = XATTR_SD_HASH_TYPE_SHA256;
   1434	acl.current_time = ksmbd_UnixTimeToNT(current_time(inode));
   1435
   1436	memcpy(acl.desc, "posix_acl", 9);
   1437	acl.desc_len = 10;
   1438
   1439	pntsd->osidoffset =
   1440		cpu_to_le32(le32_to_cpu(pntsd->osidoffset) + NDR_NTSD_OFFSETOF);
   1441	pntsd->gsidoffset =
   1442		cpu_to_le32(le32_to_cpu(pntsd->gsidoffset) + NDR_NTSD_OFFSETOF);
   1443	pntsd->dacloffset =
   1444		cpu_to_le32(le32_to_cpu(pntsd->dacloffset) + NDR_NTSD_OFFSETOF);
   1445
   1446	acl.sd_buf = (char *)pntsd;
   1447	acl.sd_size = len;
   1448
   1449	rc = ksmbd_gen_sd_hash(conn, acl.sd_buf, acl.sd_size, acl.hash);
   1450	if (rc) {
   1451		pr_err("failed to generate hash for ndr acl\n");
   1452		return rc;
   1453	}
   1454
   1455	smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
   1456						 ACL_TYPE_ACCESS);
   1457	if (S_ISDIR(inode->i_mode))
   1458		def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
   1459							     ACL_TYPE_DEFAULT);
   1460
   1461	rc = ndr_encode_posix_acl(&acl_ndr, user_ns, inode,
   1462				  smb_acl, def_smb_acl);
   1463	if (rc) {
   1464		pr_err("failed to encode ndr to posix acl\n");
   1465		goto out;
   1466	}
   1467
   1468	rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset,
   1469			       acl.posix_acl_hash);
   1470	if (rc) {
   1471		pr_err("failed to generate hash for ndr acl\n");
   1472		goto out;
   1473	}
   1474
   1475	rc = ndr_encode_v4_ntacl(&sd_ndr, &acl);
   1476	if (rc) {
   1477		pr_err("failed to encode ndr to posix acl\n");
   1478		goto out;
   1479	}
   1480
   1481	rc = ksmbd_vfs_setxattr(user_ns, dentry,
   1482				XATTR_NAME_SD, sd_ndr.data,
   1483				sd_ndr.offset, 0);
   1484	if (rc < 0)
   1485		pr_err("Failed to store XATTR ntacl :%d\n", rc);
   1486
   1487	kfree(sd_ndr.data);
   1488out:
   1489	kfree(acl_ndr.data);
   1490	kfree(smb_acl);
   1491	kfree(def_smb_acl);
   1492	return rc;
   1493}
   1494
   1495int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
   1496			   struct user_namespace *user_ns,
   1497			   struct dentry *dentry,
   1498			   struct smb_ntsd **pntsd)
   1499{
   1500	int rc;
   1501	struct ndr n;
   1502	struct inode *inode = d_inode(dentry);
   1503	struct ndr acl_ndr = {0};
   1504	struct xattr_ntacl acl;
   1505	struct xattr_smb_acl *smb_acl = NULL, *def_smb_acl = NULL;
   1506	__u8 cmp_hash[XATTR_SD_HASH_SIZE] = {0};
   1507
   1508	rc = ksmbd_vfs_getxattr(user_ns, dentry, XATTR_NAME_SD, &n.data);
   1509	if (rc <= 0)
   1510		return rc;
   1511
   1512	n.length = rc;
   1513	rc = ndr_decode_v4_ntacl(&n, &acl);
   1514	if (rc)
   1515		goto free_n_data;
   1516
   1517	smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
   1518						 ACL_TYPE_ACCESS);
   1519	if (S_ISDIR(inode->i_mode))
   1520		def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode,
   1521							     ACL_TYPE_DEFAULT);
   1522
   1523	rc = ndr_encode_posix_acl(&acl_ndr, user_ns, inode, smb_acl,
   1524				  def_smb_acl);
   1525	if (rc) {
   1526		pr_err("failed to encode ndr to posix acl\n");
   1527		goto out_free;
   1528	}
   1529
   1530	rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset, cmp_hash);
   1531	if (rc) {
   1532		pr_err("failed to generate hash for ndr acl\n");
   1533		goto out_free;
   1534	}
   1535
   1536	if (memcmp(cmp_hash, acl.posix_acl_hash, XATTR_SD_HASH_SIZE)) {
   1537		pr_err("hash value diff\n");
   1538		rc = -EINVAL;
   1539		goto out_free;
   1540	}
   1541
   1542	*pntsd = acl.sd_buf;
   1543	(*pntsd)->osidoffset = cpu_to_le32(le32_to_cpu((*pntsd)->osidoffset) -
   1544					   NDR_NTSD_OFFSETOF);
   1545	(*pntsd)->gsidoffset = cpu_to_le32(le32_to_cpu((*pntsd)->gsidoffset) -
   1546					   NDR_NTSD_OFFSETOF);
   1547	(*pntsd)->dacloffset = cpu_to_le32(le32_to_cpu((*pntsd)->dacloffset) -
   1548					   NDR_NTSD_OFFSETOF);
   1549
   1550	rc = acl.sd_size;
   1551out_free:
   1552	kfree(acl_ndr.data);
   1553	kfree(smb_acl);
   1554	kfree(def_smb_acl);
   1555	if (rc < 0) {
   1556		kfree(acl.sd_buf);
   1557		*pntsd = NULL;
   1558	}
   1559
   1560free_n_data:
   1561	kfree(n.data);
   1562	return rc;
   1563}
   1564
   1565int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns,
   1566				   struct dentry *dentry,
   1567				   struct xattr_dos_attrib *da)
   1568{
   1569	struct ndr n;
   1570	int err;
   1571
   1572	err = ndr_encode_dos_attr(&n, da);
   1573	if (err)
   1574		return err;
   1575
   1576	err = ksmbd_vfs_setxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE,
   1577				 (void *)n.data, n.offset, 0);
   1578	if (err)
   1579		ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
   1580	kfree(n.data);
   1581
   1582	return err;
   1583}
   1584
   1585int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns,
   1586				   struct dentry *dentry,
   1587				   struct xattr_dos_attrib *da)
   1588{
   1589	struct ndr n;
   1590	int err;
   1591
   1592	err = ksmbd_vfs_getxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE,
   1593				 (char **)&n.data);
   1594	if (err > 0) {
   1595		n.length = err;
   1596		if (ndr_decode_dos_attr(&n, da))
   1597			err = -EINVAL;
   1598		kfree(n.data);
   1599	} else {
   1600		ksmbd_debug(SMB, "failed to load dos attribute in xattr\n");
   1601	}
   1602
   1603	return err;
   1604}
   1605
   1606/**
   1607 * ksmbd_vfs_init_kstat() - convert unix stat information to smb stat format
   1608 * @p:          destination buffer
   1609 * @ksmbd_kstat:      ksmbd kstat wrapper
   1610 */
   1611void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
   1612{
   1613	struct file_directory_info *info = (struct file_directory_info *)(*p);
   1614	struct kstat *kstat = ksmbd_kstat->kstat;
   1615	u64 time;
   1616
   1617	info->FileIndex = 0;
   1618	info->CreationTime = cpu_to_le64(ksmbd_kstat->create_time);
   1619	time = ksmbd_UnixTimeToNT(kstat->atime);
   1620	info->LastAccessTime = cpu_to_le64(time);
   1621	time = ksmbd_UnixTimeToNT(kstat->mtime);
   1622	info->LastWriteTime = cpu_to_le64(time);
   1623	time = ksmbd_UnixTimeToNT(kstat->ctime);
   1624	info->ChangeTime = cpu_to_le64(time);
   1625
   1626	if (ksmbd_kstat->file_attributes & FILE_ATTRIBUTE_DIRECTORY_LE) {
   1627		info->EndOfFile = 0;
   1628		info->AllocationSize = 0;
   1629	} else {
   1630		info->EndOfFile = cpu_to_le64(kstat->size);
   1631		info->AllocationSize = cpu_to_le64(kstat->blocks << 9);
   1632	}
   1633	info->ExtFileAttributes = ksmbd_kstat->file_attributes;
   1634
   1635	return info;
   1636}
   1637
   1638int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
   1639				struct user_namespace *user_ns,
   1640				struct dentry *dentry,
   1641				struct ksmbd_kstat *ksmbd_kstat)
   1642{
   1643	u64 time;
   1644	int rc;
   1645
   1646	generic_fillattr(user_ns, d_inode(dentry), ksmbd_kstat->kstat);
   1647
   1648	time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime);
   1649	ksmbd_kstat->create_time = time;
   1650
   1651	/*
   1652	 * set default value for the case that store dos attributes is not yes
   1653	 * or that acl is disable in server's filesystem and the config is yes.
   1654	 */
   1655	if (S_ISDIR(ksmbd_kstat->kstat->mode))
   1656		ksmbd_kstat->file_attributes = FILE_ATTRIBUTE_DIRECTORY_LE;
   1657	else
   1658		ksmbd_kstat->file_attributes = FILE_ATTRIBUTE_ARCHIVE_LE;
   1659
   1660	if (test_share_config_flag(work->tcon->share_conf,
   1661				   KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
   1662		struct xattr_dos_attrib da;
   1663
   1664		rc = ksmbd_vfs_get_dos_attrib_xattr(user_ns, dentry, &da);
   1665		if (rc > 0) {
   1666			ksmbd_kstat->file_attributes = cpu_to_le32(da.attr);
   1667			ksmbd_kstat->create_time = da.create_time;
   1668		} else {
   1669			ksmbd_debug(VFS, "fail to load dos attribute.\n");
   1670		}
   1671	}
   1672
   1673	return 0;
   1674}
   1675
   1676ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns,
   1677				struct dentry *dentry, char *attr_name,
   1678				int attr_name_len)
   1679{
   1680	char *name, *xattr_list = NULL;
   1681	ssize_t value_len = -ENOENT, xattr_list_len;
   1682
   1683	xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
   1684	if (xattr_list_len <= 0)
   1685		goto out;
   1686
   1687	for (name = xattr_list; name - xattr_list < xattr_list_len;
   1688			name += strlen(name) + 1) {
   1689		ksmbd_debug(VFS, "%s, len %zd\n", name, strlen(name));
   1690		if (strncasecmp(attr_name, name, attr_name_len))
   1691			continue;
   1692
   1693		value_len = ksmbd_vfs_xattr_len(user_ns, dentry, name);
   1694		break;
   1695	}
   1696
   1697out:
   1698	kvfree(xattr_list);
   1699	return value_len;
   1700}
   1701
   1702int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
   1703				size_t *xattr_stream_name_size, int s_type)
   1704{
   1705	char *type, *buf;
   1706
   1707	if (s_type == DIR_STREAM)
   1708		type = ":$INDEX_ALLOCATION";
   1709	else
   1710		type = ":$DATA";
   1711
   1712	buf = kasprintf(GFP_KERNEL, "%s%s%s",
   1713			XATTR_NAME_STREAM, stream_name,	type);
   1714	if (!buf)
   1715		return -ENOMEM;
   1716
   1717	*xattr_stream_name = buf;
   1718	*xattr_stream_name_size = strlen(buf) + 1;
   1719
   1720	return 0;
   1721}
   1722
   1723int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
   1724			       struct ksmbd_file *src_fp,
   1725			       struct ksmbd_file *dst_fp,
   1726			       struct srv_copychunk *chunks,
   1727			       unsigned int chunk_count,
   1728			       unsigned int *chunk_count_written,
   1729			       unsigned int *chunk_size_written,
   1730			       loff_t *total_size_written)
   1731{
   1732	unsigned int i;
   1733	loff_t src_off, dst_off, src_file_size;
   1734	size_t len;
   1735	int ret;
   1736
   1737	*chunk_count_written = 0;
   1738	*chunk_size_written = 0;
   1739	*total_size_written = 0;
   1740
   1741	if (!(src_fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) {
   1742		pr_err("no right to read(%pd)\n", src_fp->filp->f_path.dentry);
   1743		return -EACCES;
   1744	}
   1745	if (!(dst_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) {
   1746		pr_err("no right to write(%pd)\n", dst_fp->filp->f_path.dentry);
   1747		return -EACCES;
   1748	}
   1749
   1750	if (ksmbd_stream_fd(src_fp) || ksmbd_stream_fd(dst_fp))
   1751		return -EBADF;
   1752
   1753	smb_break_all_levII_oplock(work, dst_fp, 1);
   1754
   1755	if (!work->tcon->posix_extensions) {
   1756		for (i = 0; i < chunk_count; i++) {
   1757			src_off = le64_to_cpu(chunks[i].SourceOffset);
   1758			dst_off = le64_to_cpu(chunks[i].TargetOffset);
   1759			len = le32_to_cpu(chunks[i].Length);
   1760
   1761			if (check_lock_range(src_fp->filp, src_off,
   1762					     src_off + len - 1, READ))
   1763				return -EAGAIN;
   1764			if (check_lock_range(dst_fp->filp, dst_off,
   1765					     dst_off + len - 1, WRITE))
   1766				return -EAGAIN;
   1767		}
   1768	}
   1769
   1770	src_file_size = i_size_read(file_inode(src_fp->filp));
   1771
   1772	for (i = 0; i < chunk_count; i++) {
   1773		src_off = le64_to_cpu(chunks[i].SourceOffset);
   1774		dst_off = le64_to_cpu(chunks[i].TargetOffset);
   1775		len = le32_to_cpu(chunks[i].Length);
   1776
   1777		if (src_off + len > src_file_size)
   1778			return -E2BIG;
   1779
   1780		ret = vfs_copy_file_range(src_fp->filp, src_off,
   1781					  dst_fp->filp, dst_off, len, 0);
   1782		if (ret == -EOPNOTSUPP || ret == -EXDEV)
   1783			ret = generic_copy_file_range(src_fp->filp, src_off,
   1784						      dst_fp->filp, dst_off,
   1785						      len, 0);
   1786		if (ret < 0)
   1787			return ret;
   1788
   1789		*chunk_count_written += 1;
   1790		*total_size_written += ret;
   1791	}
   1792	return 0;
   1793}
   1794
   1795void ksmbd_vfs_posix_lock_wait(struct file_lock *flock)
   1796{
   1797	wait_event(flock->fl_wait, !flock->fl_blocker);
   1798}
   1799
   1800int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout)
   1801{
   1802	return wait_event_interruptible_timeout(flock->fl_wait,
   1803						!flock->fl_blocker,
   1804						timeout);
   1805}
   1806
   1807void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock)
   1808{
   1809	locks_delete_block(flock);
   1810}
   1811
   1812int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns,
   1813				 struct inode *inode)
   1814{
   1815	struct posix_acl_state acl_state;
   1816	struct posix_acl *acls;
   1817	int rc;
   1818
   1819	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL))
   1820		return -EOPNOTSUPP;
   1821
   1822	ksmbd_debug(SMB, "Set posix acls\n");
   1823	rc = init_acl_state(&acl_state, 1);
   1824	if (rc)
   1825		return rc;
   1826
   1827	/* Set default owner group */
   1828	acl_state.owner.allow = (inode->i_mode & 0700) >> 6;
   1829	acl_state.group.allow = (inode->i_mode & 0070) >> 3;
   1830	acl_state.other.allow = inode->i_mode & 0007;
   1831	acl_state.users->aces[acl_state.users->n].uid = inode->i_uid;
   1832	acl_state.users->aces[acl_state.users->n++].perms.allow =
   1833		acl_state.owner.allow;
   1834	acl_state.groups->aces[acl_state.groups->n].gid = inode->i_gid;
   1835	acl_state.groups->aces[acl_state.groups->n++].perms.allow =
   1836		acl_state.group.allow;
   1837	acl_state.mask.allow = 0x07;
   1838
   1839	acls = posix_acl_alloc(6, GFP_KERNEL);
   1840	if (!acls) {
   1841		free_acl_state(&acl_state);
   1842		return -ENOMEM;
   1843	}
   1844	posix_state_to_acl(&acl_state, acls->a_entries);
   1845	rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls);
   1846	if (rc < 0)
   1847		ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
   1848			    rc);
   1849	else if (S_ISDIR(inode->i_mode)) {
   1850		posix_state_to_acl(&acl_state, acls->a_entries);
   1851		rc = set_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT,
   1852				   acls);
   1853		if (rc < 0)
   1854			ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
   1855				    rc);
   1856	}
   1857	free_acl_state(&acl_state);
   1858	posix_acl_release(acls);
   1859	return rc;
   1860}
   1861
   1862int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns,
   1863				struct inode *inode, struct inode *parent_inode)
   1864{
   1865	struct posix_acl *acls;
   1866	struct posix_acl_entry *pace;
   1867	int rc, i;
   1868
   1869	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL))
   1870		return -EOPNOTSUPP;
   1871
   1872	acls = get_acl(parent_inode, ACL_TYPE_DEFAULT);
   1873	if (!acls)
   1874		return -ENOENT;
   1875	pace = acls->a_entries;
   1876
   1877	for (i = 0; i < acls->a_count; i++, pace++) {
   1878		if (pace->e_tag == ACL_MASK) {
   1879			pace->e_perm = 0x07;
   1880			break;
   1881		}
   1882	}
   1883
   1884	rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls);
   1885	if (rc < 0)
   1886		ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
   1887			    rc);
   1888	if (S_ISDIR(inode->i_mode)) {
   1889		rc = set_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT,
   1890				   acls);
   1891		if (rc < 0)
   1892			ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
   1893				    rc);
   1894	}
   1895	posix_acl_release(acls);
   1896	return rc;
   1897}