ksmbd: add mnt_want_write to ksmbd vfs functions
ksmbd is doing write access using vfs helpers. There are the cases that mnt_want_write() is not called in vfs helper. This patch add missing mnt_want_write() to ksmbd vfs functions. Cc: stable@vger.kernel.org Cc: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Родитель
2b9b8f3b68
Коммит
40b268d384
|
@ -2249,7 +2249,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
|
||||||
/* delete the EA only when it exits */
|
/* delete the EA only when it exits */
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
rc = ksmbd_vfs_remove_xattr(idmap,
|
rc = ksmbd_vfs_remove_xattr(idmap,
|
||||||
path->dentry,
|
path,
|
||||||
attr_name);
|
attr_name);
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@ -2263,8 +2263,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
|
||||||
/* if the EA doesn't exist, just do nothing. */
|
/* if the EA doesn't exist, just do nothing. */
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
rc = ksmbd_vfs_setxattr(idmap,
|
rc = ksmbd_vfs_setxattr(idmap, path, attr_name, value,
|
||||||
path->dentry, attr_name, value,
|
|
||||||
le16_to_cpu(eabuf->EaValueLength), 0);
|
le16_to_cpu(eabuf->EaValueLength), 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
ksmbd_debug(SMB,
|
ksmbd_debug(SMB,
|
||||||
|
@ -2321,8 +2320,7 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path,
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ksmbd_vfs_setxattr(idmap, path->dentry,
|
rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name, NULL, 0, 0);
|
||||||
xattr_stream_name, NULL, 0, 0);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
pr_err("Failed to store XATTR stream name :%d\n", rc);
|
pr_err("Failed to store XATTR stream name :%d\n", rc);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2350,7 +2348,7 @@ static int smb2_remove_smb_xattrs(const struct path *path)
|
||||||
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
|
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
|
||||||
!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
|
!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
|
||||||
STREAM_PREFIX_LEN)) {
|
STREAM_PREFIX_LEN)) {
|
||||||
err = ksmbd_vfs_remove_xattr(idmap, path->dentry,
|
err = ksmbd_vfs_remove_xattr(idmap, path,
|
||||||
name);
|
name);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(SMB, "remove xattr failed : %s\n",
|
ksmbd_debug(SMB, "remove xattr failed : %s\n",
|
||||||
|
@ -2397,8 +2395,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, const struct path *
|
||||||
da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
|
da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
|
||||||
XATTR_DOSINFO_ITIME;
|
XATTR_DOSINFO_ITIME;
|
||||||
|
|
||||||
rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_idmap(path->mnt),
|
rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_idmap(path->mnt), path, &da);
|
||||||
path->dentry, &da);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
ksmbd_debug(SMB, "failed to store file attribute into xattr\n");
|
ksmbd_debug(SMB, "failed to store file attribute into xattr\n");
|
||||||
}
|
}
|
||||||
|
@ -2972,7 +2969,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||||
struct inode *inode = d_inode(path.dentry);
|
struct inode *inode = d_inode(path.dentry);
|
||||||
|
|
||||||
posix_acl_rc = ksmbd_vfs_inherit_posix_acl(idmap,
|
posix_acl_rc = ksmbd_vfs_inherit_posix_acl(idmap,
|
||||||
path.dentry,
|
&path,
|
||||||
d_inode(path.dentry->d_parent));
|
d_inode(path.dentry->d_parent));
|
||||||
if (posix_acl_rc)
|
if (posix_acl_rc)
|
||||||
ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
|
ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
|
||||||
|
@ -2988,7 +2985,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (posix_acl_rc)
|
if (posix_acl_rc)
|
||||||
ksmbd_vfs_set_init_posix_acl(idmap,
|
ksmbd_vfs_set_init_posix_acl(idmap,
|
||||||
path.dentry);
|
&path);
|
||||||
|
|
||||||
if (test_share_config_flag(work->tcon->share_conf,
|
if (test_share_config_flag(work->tcon->share_conf,
|
||||||
KSMBD_SHARE_FLAG_ACL_XATTR)) {
|
KSMBD_SHARE_FLAG_ACL_XATTR)) {
|
||||||
|
@ -3028,7 +3025,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||||
|
|
||||||
rc = ksmbd_vfs_set_sd_xattr(conn,
|
rc = ksmbd_vfs_set_sd_xattr(conn,
|
||||||
idmap,
|
idmap,
|
||||||
path.dentry,
|
&path,
|
||||||
pntsd,
|
pntsd,
|
||||||
pntsd_size);
|
pntsd_size);
|
||||||
kfree(pntsd);
|
kfree(pntsd);
|
||||||
|
@ -5464,7 +5461,7 @@ static int smb2_rename(struct ksmbd_work *work,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = ksmbd_vfs_setxattr(file_mnt_idmap(fp->filp),
|
rc = ksmbd_vfs_setxattr(file_mnt_idmap(fp->filp),
|
||||||
fp->filp->f_path.dentry,
|
&fp->filp->f_path,
|
||||||
xattr_stream_name,
|
xattr_stream_name,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@ -5629,8 +5626,7 @@ static int set_file_basic_info(struct ksmbd_file *fp,
|
||||||
da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
|
da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
|
||||||
XATTR_DOSINFO_ITIME;
|
XATTR_DOSINFO_ITIME;
|
||||||
|
|
||||||
rc = ksmbd_vfs_set_dos_attrib_xattr(idmap,
|
rc = ksmbd_vfs_set_dos_attrib_xattr(idmap, &filp->f_path, &da);
|
||||||
filp->f_path.dentry, &da);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
ksmbd_debug(SMB,
|
ksmbd_debug(SMB,
|
||||||
"failed to restore file attribute in EA\n");
|
"failed to restore file attribute in EA\n");
|
||||||
|
@ -7485,7 +7481,7 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
|
||||||
|
|
||||||
da.attr = le32_to_cpu(fp->f_ci->m_fattr);
|
da.attr = le32_to_cpu(fp->f_ci->m_fattr);
|
||||||
ret = ksmbd_vfs_set_dos_attrib_xattr(idmap,
|
ret = ksmbd_vfs_set_dos_attrib_xattr(idmap,
|
||||||
fp->filp->f_path.dentry, &da);
|
&fp->filp->f_path, &da);
|
||||||
if (ret)
|
if (ret)
|
||||||
fp->f_ci->m_fattr = old_fattr;
|
fp->f_ci->m_fattr = old_fattr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1162,8 +1162,7 @@ pass:
|
||||||
pntsd_size += sizeof(struct smb_acl) + nt_size;
|
pntsd_size += sizeof(struct smb_acl) + nt_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ksmbd_vfs_set_sd_xattr(conn, idmap,
|
ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size);
|
||||||
path->dentry, pntsd, pntsd_size);
|
|
||||||
kfree(pntsd);
|
kfree(pntsd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,7 +1382,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
|
||||||
newattrs.ia_valid |= ATTR_MODE;
|
newattrs.ia_valid |= ATTR_MODE;
|
||||||
newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
|
newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
|
||||||
|
|
||||||
ksmbd_vfs_remove_acl_xattrs(idmap, path->dentry);
|
ksmbd_vfs_remove_acl_xattrs(idmap, path);
|
||||||
/* Update posix acls */
|
/* Update posix acls */
|
||||||
if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
|
if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
|
||||||
rc = set_posix_acl(idmap, path->dentry,
|
rc = set_posix_acl(idmap, path->dentry,
|
||||||
|
@ -1414,9 +1413,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
|
||||||
|
|
||||||
if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
|
if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
|
||||||
/* Update WinACL in xattr */
|
/* Update WinACL in xattr */
|
||||||
ksmbd_vfs_remove_sd_xattrs(idmap, path->dentry);
|
ksmbd_vfs_remove_sd_xattrs(idmap, path);
|
||||||
ksmbd_vfs_set_sd_xattr(conn, idmap,
|
ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len);
|
||||||
path->dentry, pntsd, ntsd_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -170,6 +170,10 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mnt_want_write(path.mnt);
|
||||||
|
if (err)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
mode |= S_IFREG;
|
mode |= S_IFREG;
|
||||||
err = vfs_create(mnt_idmap(path.mnt), d_inode(path.dentry),
|
err = vfs_create(mnt_idmap(path.mnt), d_inode(path.dentry),
|
||||||
dentry, mode, true);
|
dentry, mode, true);
|
||||||
|
@ -179,6 +183,9 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
|
||||||
} else {
|
} else {
|
||||||
pr_err("File(%s): creation failed (err:%d)\n", name, err);
|
pr_err("File(%s): creation failed (err:%d)\n", name, err);
|
||||||
}
|
}
|
||||||
|
mnt_drop_write(path.mnt);
|
||||||
|
|
||||||
|
out_err:
|
||||||
done_path_create(&path, dentry);
|
done_path_create(&path, dentry);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -209,30 +216,35 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mnt_want_write(path.mnt);
|
||||||
|
if (err)
|
||||||
|
goto out_err2;
|
||||||
|
|
||||||
idmap = mnt_idmap(path.mnt);
|
idmap = mnt_idmap(path.mnt);
|
||||||
mode |= S_IFDIR;
|
mode |= S_IFDIR;
|
||||||
err = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode);
|
err = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode);
|
||||||
if (err) {
|
if (!err && d_unhashed(dentry)) {
|
||||||
goto out;
|
|
||||||
} else if (d_unhashed(dentry)) {
|
|
||||||
struct dentry *d;
|
struct dentry *d;
|
||||||
|
|
||||||
d = lookup_one(idmap, dentry->d_name.name, dentry->d_parent,
|
d = lookup_one(idmap, dentry->d_name.name, dentry->d_parent,
|
||||||
dentry->d_name.len);
|
dentry->d_name.len);
|
||||||
if (IS_ERR(d)) {
|
if (IS_ERR(d)) {
|
||||||
err = PTR_ERR(d);
|
err = PTR_ERR(d);
|
||||||
goto out;
|
goto out_err1;
|
||||||
}
|
}
|
||||||
if (unlikely(d_is_negative(d))) {
|
if (unlikely(d_is_negative(d))) {
|
||||||
dput(d);
|
dput(d);
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
goto out;
|
goto out_err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d));
|
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d));
|
||||||
dput(d);
|
dput(d);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
|
out_err1:
|
||||||
|
mnt_drop_write(path.mnt);
|
||||||
|
out_err2:
|
||||||
done_path_create(&path, dentry);
|
done_path_create(&path, dentry);
|
||||||
if (err)
|
if (err)
|
||||||
pr_err("mkdir(%s): creation failed (err:%d)\n", name, err);
|
pr_err("mkdir(%s): creation failed (err:%d)\n", name, err);
|
||||||
|
@ -443,7 +455,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
|
||||||
memcpy(&stream_buf[*pos], buf, count);
|
memcpy(&stream_buf[*pos], buf, count);
|
||||||
|
|
||||||
err = ksmbd_vfs_setxattr(idmap,
|
err = ksmbd_vfs_setxattr(idmap,
|
||||||
fp->filp->f_path.dentry,
|
&fp->filp->f_path,
|
||||||
fp->stream.name,
|
fp->stream.name,
|
||||||
(void *)stream_buf,
|
(void *)stream_buf,
|
||||||
size,
|
size,
|
||||||
|
@ -589,6 +601,10 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mnt_want_write(path->mnt);
|
||||||
|
if (err)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
idmap = mnt_idmap(path->mnt);
|
idmap = mnt_idmap(path->mnt);
|
||||||
if (S_ISDIR(d_inode(path->dentry)->i_mode)) {
|
if (S_ISDIR(d_inode(path->dentry)->i_mode)) {
|
||||||
err = vfs_rmdir(idmap, d_inode(parent), path->dentry);
|
err = vfs_rmdir(idmap, d_inode(parent), path->dentry);
|
||||||
|
@ -599,6 +615,7 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(VFS, "unlink failed, err %d\n", err);
|
ksmbd_debug(VFS, "unlink failed, err %d\n", err);
|
||||||
}
|
}
|
||||||
|
mnt_drop_write(path->mnt);
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
ksmbd_revert_fsids(work);
|
ksmbd_revert_fsids(work);
|
||||||
|
@ -644,11 +661,16 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
|
||||||
goto out3;
|
goto out3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mnt_want_write(newpath.mnt);
|
||||||
|
if (err)
|
||||||
|
goto out3;
|
||||||
|
|
||||||
err = vfs_link(oldpath.dentry, mnt_idmap(newpath.mnt),
|
err = vfs_link(oldpath.dentry, mnt_idmap(newpath.mnt),
|
||||||
d_inode(newpath.dentry),
|
d_inode(newpath.dentry),
|
||||||
dentry, NULL);
|
dentry, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(VFS, "vfs_link failed err %d\n", err);
|
ksmbd_debug(VFS, "vfs_link failed err %d\n", err);
|
||||||
|
mnt_drop_write(newpath.mnt);
|
||||||
|
|
||||||
out3:
|
out3:
|
||||||
done_path_create(&newpath, dentry);
|
done_path_create(&newpath, dentry);
|
||||||
|
@ -694,6 +716,10 @@ retry:
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mnt_want_write(old_path->mnt);
|
||||||
|
if (err)
|
||||||
|
goto out2;
|
||||||
|
|
||||||
trap = lock_rename_child(old_child, new_path.dentry);
|
trap = lock_rename_child(old_child, new_path.dentry);
|
||||||
|
|
||||||
old_parent = dget(old_child->d_parent);
|
old_parent = dget(old_child->d_parent);
|
||||||
|
@ -757,6 +783,7 @@ out4:
|
||||||
out3:
|
out3:
|
||||||
dput(old_parent);
|
dput(old_parent);
|
||||||
unlock_rename(old_parent, new_path.dentry);
|
unlock_rename(old_parent, new_path.dentry);
|
||||||
|
mnt_drop_write(old_path->mnt);
|
||||||
out2:
|
out2:
|
||||||
path_put(&new_path);
|
path_put(&new_path);
|
||||||
|
|
||||||
|
@ -897,19 +924,24 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
|
||||||
* Return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry, const char *attr_name,
|
const struct path *path, const char *attr_name,
|
||||||
void *attr_value, size_t attr_size, int flags)
|
void *attr_value, size_t attr_size, int flags)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
err = mnt_want_write(path->mnt);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
err = vfs_setxattr(idmap,
|
err = vfs_setxattr(idmap,
|
||||||
dentry,
|
path->dentry,
|
||||||
attr_name,
|
attr_name,
|
||||||
attr_value,
|
attr_value,
|
||||||
attr_size,
|
attr_size,
|
||||||
flags);
|
flags);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(VFS, "setxattr failed, err %d\n", err);
|
ksmbd_debug(VFS, "setxattr failed, err %d\n", err);
|
||||||
|
mnt_drop_write(path->mnt);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,9 +1045,18 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry, char *attr_name)
|
const struct path *path, char *attr_name)
|
||||||
{
|
{
|
||||||
return vfs_removexattr(idmap, dentry, attr_name);
|
int err;
|
||||||
|
|
||||||
|
err = mnt_want_write(path->mnt);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = vfs_removexattr(idmap, path->dentry, attr_name);
|
||||||
|
mnt_drop_write(path->mnt);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_unlink(struct file *filp)
|
int ksmbd_vfs_unlink(struct file *filp)
|
||||||
|
@ -1024,6 +1065,10 @@ int ksmbd_vfs_unlink(struct file *filp)
|
||||||
struct dentry *dir, *dentry = filp->f_path.dentry;
|
struct dentry *dir, *dentry = filp->f_path.dentry;
|
||||||
struct mnt_idmap *idmap = file_mnt_idmap(filp);
|
struct mnt_idmap *idmap = file_mnt_idmap(filp);
|
||||||
|
|
||||||
|
err = mnt_want_write(filp->f_path.mnt);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
dir = dget_parent(dentry);
|
dir = dget_parent(dentry);
|
||||||
err = ksmbd_vfs_lock_parent(dir, dentry);
|
err = ksmbd_vfs_lock_parent(dir, dentry);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -1041,6 +1086,7 @@ int ksmbd_vfs_unlink(struct file *filp)
|
||||||
ksmbd_debug(VFS, "failed to delete, err %d\n", err);
|
ksmbd_debug(VFS, "failed to delete, err %d\n", err);
|
||||||
out:
|
out:
|
||||||
dput(dir);
|
dput(dir);
|
||||||
|
mnt_drop_write(filp->f_path.mnt);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1244,13 +1290,13 @@ struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
|
int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry)
|
const struct path *path)
|
||||||
{
|
{
|
||||||
char *name, *xattr_list = NULL;
|
char *name, *xattr_list = NULL;
|
||||||
ssize_t xattr_list_len;
|
ssize_t xattr_list_len;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
|
xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
|
||||||
if (xattr_list_len < 0) {
|
if (xattr_list_len < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
} else if (!xattr_list_len) {
|
} else if (!xattr_list_len) {
|
||||||
|
@ -1258,6 +1304,10 @@ int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mnt_want_write(path->mnt);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
for (name = xattr_list; name - xattr_list < xattr_list_len;
|
for (name = xattr_list; name - xattr_list < xattr_list_len;
|
||||||
name += strlen(name) + 1) {
|
name += strlen(name) + 1) {
|
||||||
ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
|
ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
|
||||||
|
@ -1266,25 +1316,26 @@ int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
|
||||||
sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) ||
|
sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) ||
|
||||||
!strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
|
!strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
|
||||||
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
|
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
|
||||||
err = vfs_remove_acl(idmap, dentry, name);
|
err = vfs_remove_acl(idmap, path->dentry, name);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(SMB,
|
ksmbd_debug(SMB,
|
||||||
"remove acl xattr failed : %s\n", name);
|
"remove acl xattr failed : %s\n", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mnt_drop_write(path->mnt);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kvfree(xattr_list);
|
kvfree(xattr_list);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap,
|
int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path)
|
||||||
struct dentry *dentry)
|
|
||||||
{
|
{
|
||||||
char *name, *xattr_list = NULL;
|
char *name, *xattr_list = NULL;
|
||||||
ssize_t xattr_list_len;
|
ssize_t xattr_list_len;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
|
xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
|
||||||
if (xattr_list_len < 0) {
|
if (xattr_list_len < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
} else if (!xattr_list_len) {
|
} else if (!xattr_list_len) {
|
||||||
|
@ -1297,7 +1348,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap,
|
||||||
ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
|
ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
|
||||||
|
|
||||||
if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
|
if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
|
||||||
err = ksmbd_vfs_remove_xattr(idmap, dentry, name);
|
err = ksmbd_vfs_remove_xattr(idmap, path, name);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
|
ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
|
||||||
}
|
}
|
||||||
|
@ -1374,13 +1425,14 @@ out:
|
||||||
|
|
||||||
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
|
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
|
||||||
struct mnt_idmap *idmap,
|
struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
const struct path *path,
|
||||||
struct smb_ntsd *pntsd, int len)
|
struct smb_ntsd *pntsd, int len)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct ndr sd_ndr = {0}, acl_ndr = {0};
|
struct ndr sd_ndr = {0}, acl_ndr = {0};
|
||||||
struct xattr_ntacl acl = {0};
|
struct xattr_ntacl acl = {0};
|
||||||
struct xattr_smb_acl *smb_acl, *def_smb_acl = NULL;
|
struct xattr_smb_acl *smb_acl, *def_smb_acl = NULL;
|
||||||
|
struct dentry *dentry = path->dentry;
|
||||||
struct inode *inode = d_inode(dentry);
|
struct inode *inode = d_inode(dentry);
|
||||||
|
|
||||||
acl.version = 4;
|
acl.version = 4;
|
||||||
|
@ -1432,7 +1484,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ksmbd_vfs_setxattr(idmap, dentry,
|
rc = ksmbd_vfs_setxattr(idmap, path,
|
||||||
XATTR_NAME_SD, sd_ndr.data,
|
XATTR_NAME_SD, sd_ndr.data,
|
||||||
sd_ndr.offset, 0);
|
sd_ndr.offset, 0);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
@ -1522,7 +1574,7 @@ free_n_data:
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
const struct path *path,
|
||||||
struct xattr_dos_attrib *da)
|
struct xattr_dos_attrib *da)
|
||||||
{
|
{
|
||||||
struct ndr n;
|
struct ndr n;
|
||||||
|
@ -1532,7 +1584,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = ksmbd_vfs_setxattr(idmap, dentry, XATTR_NAME_DOS_ATTRIBUTE,
|
err = ksmbd_vfs_setxattr(idmap, path, XATTR_NAME_DOS_ATTRIBUTE,
|
||||||
(void *)n.data, n.offset, 0);
|
(void *)n.data, n.offset, 0);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
|
ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
|
||||||
|
@ -1769,10 +1821,11 @@ void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock)
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry)
|
struct path *path)
|
||||||
{
|
{
|
||||||
struct posix_acl_state acl_state;
|
struct posix_acl_state acl_state;
|
||||||
struct posix_acl *acls;
|
struct posix_acl *acls;
|
||||||
|
struct dentry *dentry = path->dentry;
|
||||||
struct inode *inode = d_inode(dentry);
|
struct inode *inode = d_inode(dentry);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -1802,6 +1855,11 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
posix_state_to_acl(&acl_state, acls->a_entries);
|
posix_state_to_acl(&acl_state, acls->a_entries);
|
||||||
|
|
||||||
|
rc = mnt_want_write(path->mnt);
|
||||||
|
if (rc)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
|
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
|
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
|
||||||
|
@ -1813,16 +1871,20 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||||
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
|
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
|
||||||
rc);
|
rc);
|
||||||
}
|
}
|
||||||
|
mnt_drop_write(path->mnt);
|
||||||
|
|
||||||
|
out_err:
|
||||||
free_acl_state(&acl_state);
|
free_acl_state(&acl_state);
|
||||||
posix_acl_release(acls);
|
posix_acl_release(acls);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry, struct inode *parent_inode)
|
struct path *path, struct inode *parent_inode)
|
||||||
{
|
{
|
||||||
struct posix_acl *acls;
|
struct posix_acl *acls;
|
||||||
struct posix_acl_entry *pace;
|
struct posix_acl_entry *pace;
|
||||||
|
struct dentry *dentry = path->dentry;
|
||||||
struct inode *inode = d_inode(dentry);
|
struct inode *inode = d_inode(dentry);
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
|
||||||
|
@ -1841,6 +1903,10 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = mnt_want_write(path->mnt);
|
||||||
|
if (rc)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
|
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
|
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
|
||||||
|
@ -1852,6 +1918,9 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
||||||
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
|
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
|
||||||
rc);
|
rc);
|
||||||
}
|
}
|
||||||
|
mnt_drop_write(path->mnt);
|
||||||
|
|
||||||
|
out_err:
|
||||||
posix_acl_release(acls);
|
posix_acl_release(acls);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,12 +108,12 @@ ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry, char *attr_name,
|
struct dentry *dentry, char *attr_name,
|
||||||
int attr_name_len);
|
int attr_name_len);
|
||||||
int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry, const char *attr_name,
|
const struct path *path, const char *attr_name,
|
||||||
void *attr_value, size_t attr_size, int flags);
|
void *attr_value, size_t attr_size, int flags);
|
||||||
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
|
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
|
||||||
size_t *xattr_stream_name_size, int s_type);
|
size_t *xattr_stream_name_size, int s_type);
|
||||||
int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry, char *attr_name);
|
const struct path *path, char *attr_name);
|
||||||
int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
|
int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
|
||||||
unsigned int flags, struct path *path,
|
unsigned int flags, struct path *path,
|
||||||
bool caseless);
|
bool caseless);
|
||||||
|
@ -139,26 +139,25 @@ void ksmbd_vfs_posix_lock_wait(struct file_lock *flock);
|
||||||
int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout);
|
int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout);
|
||||||
void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock);
|
void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock);
|
||||||
int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
|
int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry);
|
const struct path *path);
|
||||||
int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap,
|
int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path);
|
||||||
struct dentry *dentry);
|
|
||||||
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
|
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
|
||||||
struct mnt_idmap *idmap,
|
struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
const struct path *path,
|
||||||
struct smb_ntsd *pntsd, int len);
|
struct smb_ntsd *pntsd, int len);
|
||||||
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
|
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
|
||||||
struct mnt_idmap *idmap,
|
struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
struct dentry *dentry,
|
||||||
struct smb_ntsd **pntsd);
|
struct smb_ntsd **pntsd);
|
||||||
int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
const struct path *path,
|
||||||
struct xattr_dos_attrib *da);
|
struct xattr_dos_attrib *da);
|
||||||
int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
|
int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
struct dentry *dentry,
|
||||||
struct xattr_dos_attrib *da);
|
struct xattr_dos_attrib *da);
|
||||||
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry);
|
struct path *path);
|
||||||
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
||||||
struct dentry *dentry,
|
struct path *path,
|
||||||
struct inode *parent_inode);
|
struct inode *parent_inode);
|
||||||
#endif /* __KSMBD_VFS_H__ */
|
#endif /* __KSMBD_VFS_H__ */
|
||||||
|
|
|
@ -252,7 +252,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
|
||||||
if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) {
|
if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) {
|
||||||
ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
|
ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
|
||||||
err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp),
|
err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp),
|
||||||
filp->f_path.dentry,
|
&filp->f_path,
|
||||||
fp->stream.name);
|
fp->stream.name);
|
||||||
if (err)
|
if (err)
|
||||||
pr_err("remove xattr failed : %s\n",
|
pr_err("remove xattr failed : %s\n",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче