aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/ioctl.c
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2013-10-14 16:31:32 -0400
committerSteve French <smfrench@gmail.com>2013-10-28 10:22:31 -0400
commit64a5cfa6db94c5abba2cafe77aca077dd1e3283b (patch)
tree4a17ded1db5b4e83ced56aa4d6d081d2a72211e4 /fs/cifs/ioctl.c
parent7ff8d45c9dccf0744404d6fe44468ede7c1b9533 (diff)
Allow setting per-file compression via SMB2/3
Allow cifs/smb2/smb3 to return whether or not a file is compressed via lsattr, and allow SMB2/SMB3 to set the per-file compression flag ("chattr +c filename" on an smb3 mount). Windows users often set the compressed flag (it can be done from the desktop and file manager). David Disseldorp has patches to Samba server to support this (at least on btrfs) which are complementary to this Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/ioctl.c')
-rw-r--r--fs/cifs/ioctl.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 3e0845585853..029867078aff 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * vfs operations that deal with io control 4 * vfs operations that deal with io control
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2005,2007 6 * Copyright (C) International Business Machines Corp., 2005,2013
7 * Author(s): Steve French (sfrench@us.ibm.com) 7 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 8 *
9 * This library is free software; you can redistribute it and/or modify 9 * This library is free software; you can redistribute it and/or modify
@@ -34,13 +34,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
34 int rc = -ENOTTY; /* strange error - but the precedent */ 34 int rc = -ENOTTY; /* strange error - but the precedent */
35 unsigned int xid; 35 unsigned int xid;
36 struct cifs_sb_info *cifs_sb; 36 struct cifs_sb_info *cifs_sb;
37#ifdef CONFIG_CIFS_POSIX
38 struct cifsFileInfo *pSMBFile = filep->private_data; 37 struct cifsFileInfo *pSMBFile = filep->private_data;
39 struct cifs_tcon *tcon; 38 struct cifs_tcon *tcon;
40 __u64 ExtAttrBits = 0; 39 __u64 ExtAttrBits = 0;
41 __u64 ExtAttrMask = 0; 40 __u64 ExtAttrMask = 0;
42 __u64 caps; 41 __u64 caps;
43#endif /* CONFIG_CIFS_POSIX */
44 42
45 xid = get_xid(); 43 xid = get_xid();
46 44
@@ -49,12 +47,12 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
49 cifs_sb = CIFS_SB(inode->i_sb); 47 cifs_sb = CIFS_SB(inode->i_sb);
50 48
51 switch (command) { 49 switch (command) {
52#ifdef CONFIG_CIFS_POSIX
53 case FS_IOC_GETFLAGS: 50 case FS_IOC_GETFLAGS:
54 if (pSMBFile == NULL) 51 if (pSMBFile == NULL)
55 break; 52 break;
56 tcon = tlink_tcon(pSMBFile->tlink); 53 tcon = tlink_tcon(pSMBFile->tlink);
57 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); 54 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
55#ifdef CONFIG_CIFS_POSIX
58 if (CIFS_UNIX_EXTATTR_CAP & caps) { 56 if (CIFS_UNIX_EXTATTR_CAP & caps) {
59 rc = CIFSGetExtAttr(xid, tcon, 57 rc = CIFSGetExtAttr(xid, tcon,
60 pSMBFile->fid.netfid, 58 pSMBFile->fid.netfid,
@@ -63,29 +61,50 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
63 rc = put_user(ExtAttrBits & 61 rc = put_user(ExtAttrBits &
64 FS_FL_USER_VISIBLE, 62 FS_FL_USER_VISIBLE,
65 (int __user *)arg); 63 (int __user *)arg);
64 if (rc != EOPNOTSUPP)
65 break;
66 }
67#endif /* CONFIG_CIFS_POSIX */
68 rc = 0;
69 if (CIFS_I(inode)->cifsAttrs & ATTR_COMPRESSED) {
70 /* add in the compressed bit */
71 ExtAttrBits = FS_COMPR_FL;
72 rc = put_user(ExtAttrBits & FS_FL_USER_VISIBLE,
73 (int __user *)arg);
66 } 74 }
67 break; 75 break;
68
69 case FS_IOC_SETFLAGS: 76 case FS_IOC_SETFLAGS:
70 if (pSMBFile == NULL) 77 if (pSMBFile == NULL)
71 break; 78 break;
72 tcon = tlink_tcon(pSMBFile->tlink); 79 tcon = tlink_tcon(pSMBFile->tlink);
73 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); 80 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
74 if (CIFS_UNIX_EXTATTR_CAP & caps) { 81
75 if (get_user(ExtAttrBits, (int __user *)arg)) { 82 if (get_user(ExtAttrBits, (int __user *)arg)) {
76 rc = -EFAULT; 83 rc = -EFAULT;
77 break; 84 break;
78 } 85 }
79 /* 86
80 * rc = CIFSGetExtAttr(xid, tcon, 87 /*
81 * pSMBFile->fid.netfid, 88 * if (CIFS_UNIX_EXTATTR_CAP & caps)
82 * extAttrBits, 89 * rc = CIFSSetExtAttr(xid, tcon,
83 * &ExtAttrMask); 90 * pSMBFile->fid.netfid,
84 */ 91 * extAttrBits,
92 * &ExtAttrMask);
93 * if (rc != EOPNOTSUPP)
94 * break;
95 */
96
97 /* Currently only flag we can set is compressed flag */
98 if ((ExtAttrBits & FS_COMPR_FL) == 0)
99 break;
100
101 /* Try to set compress flag */
102 if (tcon->ses->server->ops->set_compression) {
103 rc = tcon->ses->server->ops->set_compression(
104 xid, tcon, pSMBFile);
105 cifs_dbg(FYI, "set compress flag rc %d\n", rc);
85 } 106 }
86 cifs_dbg(FYI, "set flags not implemented yet\n");
87 break; 107 break;
88#endif /* CONFIG_CIFS_POSIX */
89 default: 108 default:
90 cifs_dbg(FYI, "unsupported ioctl\n"); 109 cifs_dbg(FYI, "unsupported ioctl\n");
91 break; 110 break;