}
static int cifs_set_compression_by_path(unsigned int xid, struct file *filep,
- struct cifs_tcon *tcon)
+ struct cifs_tcon *tcon,
+ __u16 compression_state)
{
struct inode *inode = file_inode(filep);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
goto close;
}
- rc = server->ops->set_compression(xid, tcon, tmp_cfile);
+ rc = server->ops->set_compression(xid, tcon, tmp_cfile,
+ compression_state);
close:
server->ops->close(xid, tcon, &fid);
static int cifs_ioctl_set_compression(unsigned int xid, struct file *filep,
struct cifs_tcon *tcon,
- struct cifsFileInfo *cfile)
+ struct cifsFileInfo *cfile,
+ __u16 compression_state)
{
struct cifsFileInfo *wfile;
struct cifs_tcon *wtcon;
return -EOPNOTSUPP;
if (cfile && (cfile->fid.access & FILE_WRITE_DATA)) {
- rc = tcon->ses->server->ops->set_compression(xid, tcon, cfile);
+ rc = tcon->ses->server->ops->set_compression(xid, tcon, cfile,
+ compression_state);
if (rc != -EACCES)
return rc;
}
rc = cifs_get_writable_file(CIFS_I(inode), FIND_FSUID_ONLY, &wfile);
if (!rc) {
wtcon = tlink_tcon(wfile->tlink);
- rc = wtcon->ses->server->ops->set_compression(xid, wtcon, wfile);
+ rc = wtcon->ses->server->ops->set_compression(xid, wtcon, wfile,
+ compression_state);
cifsFileInfo_put(wfile);
if (rc != -EACCES)
return rc;
return rc;
}
- return cifs_set_compression_by_path(xid, filep, tcon);
+ return cifs_set_compression_by_path(xid, filep, tcon,
+ compression_state);
}
static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file,
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb;
__u64 ExtAttrBits = 0;
+ bool enable_compression;
+ __u16 compression_state;
#ifdef CONFIG_CIFS_POSIX
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
__u64 caps;
* break;
*/
- /* Currently only flag we can set is compressed flag */
- if ((ExtAttrBits & FS_COMPR_FL) == 0)
+ /* Currently only flag we can set or clear is compressed. */
+ if (ExtAttrBits & ~FS_COMPR_FL) {
+ rc = -EOPNOTSUPP;
break;
+ }
+
+ enable_compression = ExtAttrBits & FS_COMPR_FL;
+ compression_state = enable_compression ?
+ COMPRESSION_FORMAT_DEFAULT :
+ COMPRESSION_FORMAT_NONE;
- /* Try to set compress flag */
rc = cifs_ioctl_set_compression(xid, filep, tcon,
- pSMBFile);
+ pSMBFile,
+ compression_state);
if (rc == 0) {
spin_lock(&inode->i_lock);
- CIFS_I(inode)->cifsAttrs |=
- FILE_ATTRIBUTE_COMPRESSED;
+ if (enable_compression)
+ CIFS_I(inode)->cifsAttrs |=
+ FILE_ATTRIBUTE_COMPRESSED;
+ else
+ CIFS_I(inode)->cifsAttrs &=
+ ~FILE_ATTRIBUTE_COMPRESSED;
spin_unlock(&inode->i_lock);
}
cifs_dbg(FYI, "set compress flag rc %d\n", rc);
int
SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
- u64 persistent_fid, u64 volatile_fid)
+ u64 persistent_fid, u64 volatile_fid,
+ __u16 compression_state)
{
int rc;
struct compress_ioctl fsctl_input;
char *ret_data = NULL;
- fsctl_input.CompressionState =
- cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
+ fsctl_input.CompressionState = cpu_to_le16(compression_state);
rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
FSCTL_SET_COMPRESSION,
u64 persistent_fid, u64 volatile_fid,
struct smb2_file_full_ea_info *buf, int len);
int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
- u64 persistent_fid, u64 volatile_fid);
+ u64 persistent_fid, u64 volatile_fid,
+ __u16 compression_state);
int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
const u64 persistent_fid, const u64 volatile_fid,
__u8 oplock_level);