[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAOQ4uxg+DnrOPcGpgS3fO7t8BgabQGdfaCY9t2mMzTD7Ek+wEg@mail.gmail.com>
Date: Sun, 16 Feb 2025 21:21:27 +0100
From: Amir Goldstein <amir73il@...il.com>
To: Pali Rohár <pali@...nel.org>
Cc: "Darrick J. Wong" <djwong@...nel.org>, ronnie sahlberg <ronniesahlberg@...il.com>,
Chuck Lever <chuck.lever@...cle.com>, Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>,
Steve French <sfrench@...ba.org>, Alexander Viro <viro@...iv.linux.org.uk>,
linux-fsdevel@...r.kernel.org, linux-cifs@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [RFC PATCH 4/4] cifs: Implement FS_IOC_FS[GS]ETXATTR API for
Windows attributes
On Sun, Feb 16, 2025 at 5:42 PM Pali Rohár <pali@...nel.org> wrote:
>
No empty commit message please
> Signed-off-by: Pali Rohár <pali@...nel.org>
> ---
> fs/smb/client/cifsfs.c | 4 +
> fs/smb/client/cifsfs.h | 2 +
> fs/smb/client/cifsglob.h | 4 +-
> fs/smb/client/cifsproto.h | 2 +-
> fs/smb/client/cifssmb.c | 4 +-
> fs/smb/client/inode.c | 181 ++++++++++++++++++++++++++++++++++++++
> fs/smb/client/ioctl.c | 8 +-
> fs/smb/client/smb1ops.c | 4 +-
> fs/smb/client/smb2ops.c | 8 +-
> fs/smb/client/smb2pdu.c | 4 +-
> fs/smb/client/smb2proto.h | 2 +-
> fs/smb/common/smb2pdu.h | 2 +
> 12 files changed, 209 insertions(+), 16 deletions(-)
>
> diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
> index ea31d693ea9f..b441675f9afd 100644
> --- a/fs/smb/client/cifsfs.c
> +++ b/fs/smb/client/cifsfs.c
> @@ -1182,6 +1182,8 @@ const struct inode_operations cifs_dir_inode_ops = {
> .listxattr = cifs_listxattr,
> .get_acl = cifs_get_acl,
> .set_acl = cifs_set_acl,
> + .fileattr_get = cifs_fileattr_get,
> + .fileattr_set = cifs_fileattr_set,
> };
>
> const struct inode_operations cifs_file_inode_ops = {
> @@ -1192,6 +1194,8 @@ const struct inode_operations cifs_file_inode_ops = {
> .fiemap = cifs_fiemap,
> .get_acl = cifs_get_acl,
> .set_acl = cifs_set_acl,
> + .fileattr_get = cifs_fileattr_get,
> + .fileattr_set = cifs_fileattr_set,
> };
>
> const char *cifs_get_link(struct dentry *dentry, struct inode *inode,
> diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h
> index 831fee962c4d..b1e6025e2cbc 100644
> --- a/fs/smb/client/cifsfs.h
> +++ b/fs/smb/client/cifsfs.h
> @@ -77,6 +77,8 @@ extern int cifs_setattr(struct mnt_idmap *, struct dentry *,
> struct iattr *);
> extern int cifs_fiemap(struct inode *, struct fiemap_extent_info *, u64 start,
> u64 len);
> +extern int cifs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
> +extern int cifs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa);
>
> extern const struct inode_operations cifs_file_inode_ops;
> extern const struct inode_operations cifs_symlink_inode_ops;
> diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
> index b764bfe916b4..233a0a13b0e2 100644
> --- a/fs/smb/client/cifsglob.h
> +++ b/fs/smb/client/cifsglob.h
> @@ -426,7 +426,7 @@ struct smb_version_operations {
> int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *,
> const unsigned int);
> int (*set_compression)(const unsigned int, struct cifs_tcon *,
> - struct cifsFileInfo *);
> + struct cifsFileInfo *, bool);
> /* check if we can send an echo or nor */
> bool (*can_echo)(struct TCP_Server_Info *);
> /* send echo request */
> @@ -538,7 +538,7 @@ struct smb_version_operations {
> int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *,
> bool allocate_crypto);
> int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon,
> - struct cifsFileInfo *src_file);
> + struct cifsFileInfo *src_file, bool enable);
> int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon,
> struct cifsFileInfo *src_file, void __user *);
> int (*notify)(const unsigned int xid, struct file *pfile,
> diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
> index 47ecc0884a74..f5f6be6f343e 100644
> --- a/fs/smb/client/cifsproto.h
> +++ b/fs/smb/client/cifsproto.h
> @@ -506,7 +506,7 @@ extern struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> struct kvec *reparse_iov,
> struct kvec *xattr_iov);
> extern int CIFSSMB_set_compression(const unsigned int xid,
> - struct cifs_tcon *tcon, __u16 fid);
> + struct cifs_tcon *tcon, __u16 fid, bool enable);
> extern int CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms,
> int *oplock, FILE_ALL_INFO *buf);
> extern int SMBOldOpen(const unsigned int xid, struct cifs_tcon *tcon,
> diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
> index 3dbff55b639d..643a55db3ca9 100644
> --- a/fs/smb/client/cifssmb.c
> +++ b/fs/smb/client/cifssmb.c
> @@ -3454,7 +3454,7 @@ struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
>
> int
> CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> - __u16 fid)
> + __u16 fid, bool enable)
> {
> int rc = 0;
> int bytes_returned;
> @@ -3467,7 +3467,7 @@ CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> if (rc)
> return rc;
>
> - pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
> + pSMB->compression_state = cpu_to_le16(enable ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE);
>
> pSMB->TotalParameterCount = 0;
> pSMB->TotalDataCount = cpu_to_le32(2);
> diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
> index dfad9284a87c..d07ebb99c262 100644
> --- a/fs/smb/client/inode.c
> +++ b/fs/smb/client/inode.c
> @@ -13,6 +13,7 @@
> #include <linux/sched/signal.h>
> #include <linux/wait_bit.h>
> #include <linux/fiemap.h>
> +#include <linux/fileattr.h>
> #include <asm/div64.h>
> #include "cifsfs.h"
> #include "cifspdu.h"
> @@ -83,6 +84,7 @@ static void cifs_set_ops(struct inode *inode)
> inode->i_op = &cifs_symlink_inode_ops;
> break;
> default:
> + inode->i_op = &cifs_file_inode_ops;
> init_special_inode(inode, inode->i_mode, inode->i_rdev);
> break;
> }
> @@ -3282,3 +3284,182 @@ cifs_setattr(struct mnt_idmap *idmap, struct dentry *direntry,
> /* BB: add cifs_setattr_legacy for really old servers */
> return rc;
> }
> +
> +int cifs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
> +{
> + struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
> + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
> + struct inode *inode = d_inode(dentry);
> + u32 attrs = CIFS_I(inode)->cifsAttrs;
> + u32 fsattrs = le32_to_cpu(tcon->fsAttrInfo.Attributes);
> + u32 xflags = 0;
> + u32 xflags_mask = FS_XFLAG_IMMUTABLEUSER;
> + u16 xflags2 = 0;
> + u16 xflags2_mask = FS_XFLAG2_HIDDEN | FS_XFLAG2_SYSTEM | FS_XFLAG2_ARCHIVE |
> + FS_XFLAG2_TEMPORARY | FS_XFLAG2_NOTINDEXED |
> + FS_XFLAG2_NOSCRUBDATA | FS_XFLAG2_OFFLINE |
> + FS_XFLAG2_PINNED | FS_XFLAG2_UNPINNED;
> +
> + if (fsattrs & FILE_FILE_COMPRESSION)
> + xflags_mask |= FS_XFLAG_COMPRESSED;
> + if (fsattrs & FILE_SUPPORTS_ENCRYPTION)
> + xflags_mask |= FS_XFLAG_COMPRESSED;
> + if (fsattrs & FILE_SUPPORT_INTEGRITY_STREAMS)
> + xflags_mask |= FS_XFLAG_CHECKSUMS;
> +
> + if (attrs & FILE_ATTRIBUTE_READONLY)
> + xflags |= FS_XFLAG_IMMUTABLEUSER;
> + if (attrs & FILE_ATTRIBUTE_HIDDEN)
> + xflags2 |= FS_XFLAG2_HIDDEN;
> + if (attrs & FILE_ATTRIBUTE_SYSTEM)
> + xflags2 |= FS_XFLAG2_SYSTEM;
> + if (attrs & FILE_ATTRIBUTE_ARCHIVE)
> + xflags2 |= FS_XFLAG2_ARCHIVE;
> + if (attrs & FILE_ATTRIBUTE_TEMPORARY)
> + xflags2 |= FS_XFLAG2_TEMPORARY;
> + if (attrs & FILE_ATTRIBUTE_COMPRESSED)
> + xflags |= FS_XFLAG_COMPRESSED;
> + if (attrs & FILE_ATTRIBUTE_OFFLINE)
> + xflags2 |= FS_XFLAG2_OFFLINE;
> + if (attrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
> + xflags2 |= FS_XFLAG2_NOTINDEXED;
> + if (attrs & FILE_ATTRIBUTE_ENCRYPTED)
> + xflags |= FS_XFLAG_ENCRYPTED;
> + if (attrs & FILE_ATTRIBUTE_INTEGRITY_STREAM)
> + xflags |= FS_XFLAG_CHECKSUMS;
> + if (attrs & FILE_ATTRIBUTE_NO_SCRUB_DATA)
> + xflags2 |= FS_XFLAG2_NOSCRUBDATA;
> + if (attrs & FILE_ATTRIBUTE_PINNED)
> + xflags2 |= FS_XFLAG2_PINNED;
> + if (attrs & FILE_ATTRIBUTE_UNPINNED)
> + xflags2 |= FS_XFLAG2_UNPINNED;
> +
> + fileattr_fill_xflags(fa, xflags, xflags_mask, xflags2, xflags2_mask);
> + return 0;
> +}
> +
> +#define MODIFY_ATTRS_COND(attrs, xflags, xflag, attr) (attrs) ^= ((-(!!((xflags) & (xflag))) ^ (attrs)) & (attr))
> +
> +int cifs_fileattr_set(struct mnt_idmap *idmap,
> + struct dentry *dentry, struct fileattr *fa)
> +{
> + struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
> + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
> + struct inode *inode = d_inode(dentry);
> + u32 attrs = CIFS_I(inode)->cifsAttrs;
> + struct cifsFileInfo open_file_tmp = {};
> + struct cifsFileInfo *open_file = NULL;
> + struct cifs_open_parms oparms;
> + FILE_BASIC_INFO info_buf = {};
> + bool do_close = false;
> + const char *full_path;
> + unsigned int xid;
> + __u32 oplock;
> + void *page;
> + int rc;
> +
> + if ((fa->fsx_xflags_mask & ~(FS_XFLAG_IMMUTABLEUSER | FS_XFLAG_COMPRESSED |
> + FS_XFLAG_ENCRYPTED | FS_XFLAG_CHECKSUMS)) ||
> + (fa->fsx_xflags2_mask & ~(FS_XFLAG2_HIDDEN | FS_XFLAG2_SYSTEM | FS_XFLAG2_ARCHIVE |
> + FS_XFLAG2_TEMPORARY | FS_XFLAG2_NOTINDEXED |
> + FS_XFLAG2_NOSCRUBDATA | FS_XFLAG2_OFFLINE |
> + FS_XFLAG2_PINNED | FS_XFLAG2_UNPINNED)) ||
> + (fa->flags & ~FS_COMMON_FL))
> + return -EOPNOTSUPP;
> +
> + if (fa->fsx_xflags_mask & FS_XFLAG_IMMUTABLEUSER)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags, FS_XFLAG_IMMUTABLEUSER, FILE_ATTRIBUTE_READONLY);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_HIDDEN)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_HIDDEN, FILE_ATTRIBUTE_HIDDEN);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_SYSTEM)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_SYSTEM, FILE_ATTRIBUTE_SYSTEM);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_ARCHIVE)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_TEMPORARY)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_TEMPORARY, FILE_ATTRIBUTE_TEMPORARY);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_NOTINDEXED)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_NOTINDEXED, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_NOSCRUBDATA)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_NOSCRUBDATA, FILE_ATTRIBUTE_NO_SCRUB_DATA);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_OFFLINE)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_OFFLINE, FILE_ATTRIBUTE_OFFLINE);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_PINNED)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_PINNED, FILE_ATTRIBUTE_PINNED);
> + if (fa->fsx_xflags2_mask & FS_XFLAG2_UNPINNED)
> + MODIFY_ATTRS_COND(attrs, fa->fsx_xflags2, FS_XFLAG2_UNPINNED, FILE_ATTRIBUTE_UNPINNED);
> +
> + page = alloc_dentry_path();
> +
> + full_path = build_path_from_dentry(dentry, page);
> + if (IS_ERR(full_path)) {
> + rc = PTR_ERR(full_path);
> + goto out_page;
> + }
> +
> + xid = get_xid();
> +
> + if (attrs != CIFS_I(inode)->cifsAttrs) {
> + info_buf.Attributes = cpu_to_le32(attrs);
> + if (tcon->ses->server->ops->set_file_info)
> + rc = tcon->ses->server->ops->set_file_info(inode, full_path, &info_buf, xid);
> + else
> + rc = -EOPNOTSUPP;
> + if (rc)
> + goto out_xid;
> + CIFS_I(inode)->cifsAttrs = attrs;
> + }
> +
> + if (fa->fsx_xflags_mask & (FS_XFLAG_COMPRESSED | FS_XFLAG_ENCRYPTED | FS_XFLAG_CHECKSUMS)) {
> + open_file = find_writable_file(CIFS_I(inode), FIND_WR_FSUID_ONLY);
> + if (!open_file) {
> + oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE);
> + oparms.fid = &open_file_tmp.fid;
> + oplock = 0;
> + oparms.create_options = cifs_create_options(cifs_sb, 0);
> + rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
> + if (rc)
> + goto out_file;
> + do_close = true;
> + open_file = &open_file_tmp;
> + }
> + }
> +
> + if (fa->fsx_xflags_mask & FS_XFLAG_COMPRESSED) {
> + if (tcon->ses->server->ops->set_compression)
> + rc = tcon->ses->server->ops->set_compression(xid, tcon, open_file, fa->fsx_xflags & FS_XFLAG_COMPRESSED);
> + else
> + rc = -EOPNOTSUPP;
> + if (rc)
> + goto out_file;
> + CIFS_I(inode)->cifsAttrs |= FILE_ATTRIBUTE_COMPRESSED;
> + }
> +
> + if (fa->fsx_xflags_mask & FS_XFLAG_ENCRYPTED) {
> + /* TODO */
> + rc = -EOPNOTSUPP;
> + if (rc)
> + goto out_file;
> + CIFS_I(inode)->cifsAttrs |= FILE_ATTRIBUTE_ENCRYPTED;
> + }
> +
> + if (fa->fsx_xflags_mask & FS_XFLAG_CHECKSUMS) {
> + if (tcon->ses->server->ops->set_integrity)
> + rc = tcon->ses->server->ops->set_integrity(xid, tcon, open_file, fa->fsx_xflags & FS_XFLAG_CHECKSUMS);
> + else
> + rc = -EOPNOTSUPP;
> + if (rc)
> + goto out_file;
> + CIFS_I(inode)->cifsAttrs |= FILE_ATTRIBUTE_INTEGRITY_STREAM;
> + }
> +
> +out_file:
> + if (do_close)
> + tcon->ses->server->ops->close(xid, tcon, oparms.fid);
> + else if (open_file)
> + cifsFileInfo_put(open_file);
> +out_xid:
> + free_xid(xid);
> +out_page:
> + free_dentry_path(page);
> + return rc;
> +}
> diff --git a/fs/smb/client/ioctl.c b/fs/smb/client/ioctl.c
> index 56439da4f119..7c245085f891 100644
> --- a/fs/smb/client/ioctl.c
> +++ b/fs/smb/client/ioctl.c
> @@ -356,12 +356,14 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
> struct cifs_tcon *tcon;
> struct tcon_link *tlink;
> struct cifs_sb_info *cifs_sb;
> +#if 0
> __u64 ExtAttrBits = 0;
> #ifdef CONFIG_CIFS_POSIX
> #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
> __u64 caps;
> #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
> #endif /* CONFIG_CIFS_POSIX */
> +#endif
>
> xid = get_xid();
>
> @@ -372,6 +374,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
> trace_smb3_ioctl(xid, pSMBFile->fid.persistent_fid, command);
>
> switch (command) {
> +#if 0
> case FS_IOC_GETFLAGS:
> if (pSMBFile == NULL)
> break;
> @@ -429,10 +432,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
> /* Try to set compress flag */
> if (tcon->ses->server->ops->set_compression) {
> rc = tcon->ses->server->ops->set_compression(
> - xid, tcon, pSMBFile);
> + xid, tcon, pSMBFile, true);
> cifs_dbg(FYI, "set compress flag rc %d\n", rc);
> }
> break;
> +#endif
> case CIFS_IOC_COPYCHUNK_FILE:
> rc = cifs_ioctl_copychunk(xid, filep, arg);
> break;
> @@ -445,7 +449,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
> tcon = tlink_tcon(pSMBFile->tlink);
> if (tcon->ses->server->ops->set_integrity)
> rc = tcon->ses->server->ops->set_integrity(xid,
> - tcon, pSMBFile);
> + tcon, pSMBFile, true);
> else
> rc = -EOPNOTSUPP;
> break;
> diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
> index ba6452d89df3..2e854bde67de 100644
> --- a/fs/smb/client/smb1ops.c
> +++ b/fs/smb/client/smb1ops.c
> @@ -1245,9 +1245,9 @@ smb_set_file_info(struct inode *inode, const char *full_path,
>
> static int
> cifs_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> - struct cifsFileInfo *cfile)
> + struct cifsFileInfo *cfile, bool enable)
> {
> - return CIFSSMB_set_compression(xid, tcon, cfile->fid.netfid);
> + return CIFSSMB_set_compression(xid, tcon, cfile->fid.netfid, enable);
> }
>
> static int
> diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
> index f8445a9ff9a1..9c66e413c59c 100644
> --- a/fs/smb/client/smb2ops.c
> +++ b/fs/smb/client/smb2ops.c
> @@ -2106,20 +2106,20 @@ smb2_duplicate_extents(const unsigned int xid,
>
> static int
> smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> - struct cifsFileInfo *cfile)
> + struct cifsFileInfo *cfile, bool enable)
> {
> return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid,
> - cfile->fid.volatile_fid);
> + cfile->fid.volatile_fid, enable);
> }
>
> static int
> smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
> - struct cifsFileInfo *cfile)
> + struct cifsFileInfo *cfile, bool enable)
> {
> struct fsctl_set_integrity_information_req integr_info;
> unsigned int ret_data_len;
>
> - integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED);
> + integr_info.ChecksumAlgorithm = cpu_to_le16(enable ? CHECKSUM_TYPE_CRC64 : CHECKSUM_TYPE_NONE);
> integr_info.Flags = 0;
> integr_info.Reserved = 0;
>
> diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> index a75947797d58..57d716cfc800 100644
> --- a/fs/smb/client/smb2pdu.c
> +++ b/fs/smb/client/smb2pdu.c
> @@ -3537,14 +3537,14 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
>
> int
> SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> - u64 persistent_fid, u64 volatile_fid)
> + u64 persistent_fid, u64 volatile_fid, bool enable)
> {
> int rc;
> struct compress_ioctl fsctl_input;
> char *ret_data = NULL;
>
> fsctl_input.CompressionState =
> - cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
> + cpu_to_le16(enable ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE);
>
> rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
> FSCTL_SET_COMPRESSION,
> diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
> index cec5921bfdd2..6086bbdeeae0 100644
> --- a/fs/smb/client/smb2proto.h
> +++ b/fs/smb/client/smb2proto.h
> @@ -250,7 +250,7 @@ extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
> u64 persistent_fid, u64 volatile_fid,
> struct smb2_file_full_ea_info *buf, int len);
> extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> - u64 persistent_fid, u64 volatile_fid);
> + u64 persistent_fid, u64 volatile_fid, bool enable);
> extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
> const u64 persistent_fid, const u64 volatile_fid,
> const __u8 oplock_level);
> diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
> index ab902b155650..a24194bef849 100644
> --- a/fs/smb/common/smb2pdu.h
> +++ b/fs/smb/common/smb2pdu.h
> @@ -1077,6 +1077,8 @@ struct smb2_server_client_notification {
> #define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
> #define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000
> #define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000
> +#define FILE_ATTRIBUTE_PINNED 0x00080000
> +#define FILE_ATTRIBUTE_UNPINNED 0x00100000
> #define FILE_ATTRIBUTE__MASK 0x00007FB7
>
> #define FILE_ATTRIBUTE_READONLY_LE cpu_to_le32(0x00000001)
> --
> 2.20.1
>
Powered by blists - more mailing lists