aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 12:24:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 12:24:13 -0500
commit6facac1ab68fbf9cbad31a9d521f3a0d6aa9470e (patch)
tree1b00b4d9aab6c5567036157044da98857a84237a
parent3f1c64f410e4394ecefadd7a597a7c20368a65fc (diff)
parentc299dd0e2d3dd61d0048a9d9b021aa01f023ed0c (diff)
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull CIFS fixes from Steve French: "This includes a set of misc. cifs fixes (most importantly some byte range lock related write fixes from Pavel, and some ACL and idmap related fixes from Jeff) but also includes the SMB2.02 dialect enablement, and a key fix for SMB3 mounts. Default authentication upgraded to ntlmv2 for cifs (it was already ntlmv2 for smb2)" * 'for-next' of git://git.samba.org/sfrench/cifs-2.6: (43 commits) CIFS: Fix write after setting a read lock for read oplock files cifs: parse the device name into UNC and prepath cifs: fix up handling of prefixpath= option cifs: clean up handling of unc= option cifs: fix SID binary to string conversion fix "disabling echoes and oplocks" on SMB2 mounts Do not send SMB2 signatures for SMB3 frames cifs: deal with id_to_sid embedded sid reply corner case cifs: fix hardcoded default security descriptor length cifs: extra sanity checking for cifs.idmap keys cifs: avoid extra allocation for small cifs.idmap keys cifs: simplify id_to_sid and sid_to_id mapping code CIFS: Fix possible data coherency problem after oplock break to None CIFS: Do not permit write to a range mandatory locked with a read lock cifs: rename cifs_readdir_lookup to cifs_prime_dcache and make it void return cifs: Add CONFIG_CIFS_DEBUG and rename use of CIFS_DEBUG cifs: Make CIFS_DEBUG possible to undefine SMB3 mounts fail with access denied to some servers cifs: Remove unused cEVENT macro cifs: always zero out smb_vol before parsing options ...
-rw-r--r--fs/cifs/Kconfig10
-rw-r--r--fs/cifs/cifs_debug.h72
-rw-r--r--fs/cifs/cifsacl.c746
-rw-r--r--fs/cifs/cifsacl.h66
-rw-r--r--fs/cifs/cifsfs.c17
-rw-r--r--fs/cifs/cifsglob.h36
-rw-r--r--fs/cifs/cifsproto.h10
-rw-r--r--fs/cifs/connect.c310
-rw-r--r--fs/cifs/dir.c32
-rw-r--r--fs/cifs/file.c200
-rw-r--r--fs/cifs/inode.c7
-rw-r--r--fs/cifs/netmisc.c14
-rw-r--r--fs/cifs/readdir.c52
-rw-r--r--fs/cifs/smb1ops.c32
-rw-r--r--fs/cifs/smb2file.c12
-rw-r--r--fs/cifs/smb2ops.c103
-rw-r--r--fs/cifs/smb2pdu.c5
-rw-r--r--fs/cifs/smb2proto.h4
-rw-r--r--fs/cifs/smb2transport.c13
19 files changed, 787 insertions, 954 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 2075ddfffa73..21ff76c22a17 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -122,9 +122,17 @@ config CIFS_ACL
122 Allows fetching CIFS/NTFS ACL from the server. The DACL blob 122 Allows fetching CIFS/NTFS ACL from the server. The DACL blob
123 is handed over to the application/caller. 123 is handed over to the application/caller.
124 124
125config CIFS_DEBUG
126 bool "Enable CIFS debugging routines"
127 default y
128 depends on CIFS
129 help
130 Enabling this option adds helpful debugging messages to
131 the cifs code which increases the size of the cifs module.
132 If unsure, say Y.
125config CIFS_DEBUG2 133config CIFS_DEBUG2
126 bool "Enable additional CIFS debugging routines" 134 bool "Enable additional CIFS debugging routines"
127 depends on CIFS 135 depends on CIFS_DEBUG
128 help 136 help
129 Enabling this option adds a few more debugging routines 137 Enabling this option adds a few more debugging routines
130 to the cifs code which slightly increases the size of 138 to the cifs code which slightly increases the size of
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index c0c68bb492d7..86e92ef2abc1 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -18,7 +18,6 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 19 *
20*/ 20*/
21#define CIFS_DEBUG /* BB temporary */
22 21
23#ifndef _H_CIFS_DEBUG 22#ifndef _H_CIFS_DEBUG
24#define _H_CIFS_DEBUG 23#define _H_CIFS_DEBUG
@@ -37,49 +36,43 @@ void dump_smb(void *, int);
37#define CIFS_RC 0x02 36#define CIFS_RC 0x02
38#define CIFS_TIMER 0x04 37#define CIFS_TIMER 0x04
39 38
39extern int cifsFYI;
40extern int cifsERROR;
41
40/* 42/*
41 * debug ON 43 * debug ON
42 * -------- 44 * --------
43 */ 45 */
44#ifdef CIFS_DEBUG 46#ifdef CONFIG_CIFS_DEBUG
45 47
46/* information message: e.g., configuration, major event */ 48/* information message: e.g., configuration, major event */
47extern int cifsFYI; 49#define cifsfyi(fmt, ...) \
48#define cifsfyi(fmt, arg...) \
49do { \ 50do { \
50 if (cifsFYI & CIFS_INFO) \ 51 if (cifsFYI & CIFS_INFO) \
51 printk(KERN_DEBUG "%s: " fmt "\n", __FILE__, ##arg); \ 52 printk(KERN_DEBUG "%s: " fmt "\n", \
53 __FILE__, ##__VA_ARGS__); \
52} while (0) 54} while (0)
53 55
54#define cFYI(set, fmt, arg...) \ 56#define cFYI(set, fmt, ...) \
55do { \ 57do { \
56 if (set) \ 58 if (set) \
57 cifsfyi(fmt, ##arg); \ 59 cifsfyi(fmt, ##__VA_ARGS__); \
58} while (0) 60} while (0)
59 61
60#define cifswarn(fmt, arg...) \ 62#define cifswarn(fmt, ...) \
61 printk(KERN_WARNING fmt "\n", ##arg) 63 printk(KERN_WARNING fmt "\n", ##__VA_ARGS__)
62 64
63/* debug event message: */ 65/* error event message: e.g., i/o error */
64extern int cifsERROR; 66#define cifserror(fmt, ...) \
65
66#define cEVENT(fmt, arg...) \
67do { \ 67do { \
68 if (cifsERROR) \ 68 if (cifsERROR) \
69 printk(KERN_EVENT "%s: " fmt "\n", __FILE__, ##arg); \ 69 printk(KERN_ERR "CIFS VFS: " fmt "\n", ##__VA_ARGS__); \
70} while (0)
71
72/* error event message: e.g., i/o error */
73#define cifserror(fmt, arg...) \
74do { \
75 if (cifsERROR) \
76 printk(KERN_ERR "CIFS VFS: " fmt "\n", ##arg); \
77} while (0) 70} while (0)
78 71
79#define cERROR(set, fmt, arg...) \ 72#define cERROR(set, fmt, ...) \
80do { \ 73do { \
81 if (set) \ 74 if (set) \
82 cifserror(fmt, ##arg); \ 75 cifserror(fmt, ##__VA_ARGS__); \
83} while (0) 76} while (0)
84 77
85/* 78/*
@@ -87,10 +80,27 @@ do { \
87 * --------- 80 * ---------
88 */ 81 */
89#else /* _CIFS_DEBUG */ 82#else /* _CIFS_DEBUG */
90#define cERROR(set, fmt, arg...) 83#define cifsfyi(fmt, ...) \
91#define cEVENT(fmt, arg...) 84do { \
92#define cFYI(set, fmt, arg...) 85 if (0) \
93#define cifserror(fmt, arg...) 86 printk(KERN_DEBUG "%s: " fmt "\n", \
87 __FILE__, ##__VA_ARGS__); \
88} while (0)
89#define cFYI(set, fmt, ...) \
90do { \
91 if (0 && set) \
92 cifsfyi(fmt, ##__VA_ARGS__); \
93} while (0)
94#define cifserror(fmt, ...) \
95do { \
96 if (0) \
97 printk(KERN_ERR "CIFS VFS: " fmt "\n", ##__VA_ARGS__); \
98} while (0)
99#define cERROR(set, fmt, ...) \
100do { \
101 if (0 && set) \
102 cifserror(fmt, ##__VA_ARGS__); \
103} while (0)
94#endif /* _CIFS_DEBUG */ 104#endif /* _CIFS_DEBUG */
95 105
96#endif /* _H_CIFS_DEBUG */ 106#endif /* _H_CIFS_DEBUG */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 0fb15bbbe43c..75c1ee699143 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -42,135 +42,27 @@ static const struct cifs_sid sid_authusers = {
42/* group users */ 42/* group users */
43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; 43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44 44
45const struct cred *root_cred; 45static const struct cred *root_cred;
46
47static void
48shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem,
49 int *nr_del)
50{
51 struct rb_node *node;
52 struct rb_node *tmp;
53 struct cifs_sid_id *psidid;
54
55 node = rb_first(root);
56 while (node) {
57 tmp = node;
58 node = rb_next(tmp);
59 psidid = rb_entry(tmp, struct cifs_sid_id, rbnode);
60 if (nr_to_scan == 0 || *nr_del == nr_to_scan)
61 ++(*nr_rem);
62 else {
63 if (time_after(jiffies, psidid->time + SID_MAP_EXPIRE)
64 && psidid->refcount == 0) {
65 rb_erase(tmp, root);
66 ++(*nr_del);
67 } else
68 ++(*nr_rem);
69 }
70 }
71}
72
73/*
74 * Run idmap cache shrinker.
75 */
76static int
77cifs_idmap_shrinker(struct shrinker *shrink, struct shrink_control *sc)
78{
79 int nr_to_scan = sc->nr_to_scan;
80 int nr_del = 0;
81 int nr_rem = 0;
82 struct rb_root *root;
83
84 root = &uidtree;
85 spin_lock(&siduidlock);
86 shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
87 spin_unlock(&siduidlock);
88
89 root = &gidtree;
90 spin_lock(&sidgidlock);
91 shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
92 spin_unlock(&sidgidlock);
93
94 root = &siduidtree;
95 spin_lock(&uidsidlock);
96 shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
97 spin_unlock(&uidsidlock);
98
99 root = &sidgidtree;
100 spin_lock(&gidsidlock);
101 shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
102 spin_unlock(&gidsidlock);
103
104 return nr_rem;
105}
106
107static void
108sid_rb_insert(struct rb_root *root, unsigned long cid,
109 struct cifs_sid_id **psidid, char *typestr)
110{
111 char *strptr;
112 struct rb_node *node = root->rb_node;
113 struct rb_node *parent = NULL;
114 struct rb_node **linkto = &(root->rb_node);
115 struct cifs_sid_id *lsidid;
116
117 while (node) {
118 lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
119 parent = node;
120 if (cid > lsidid->id) {
121 linkto = &(node->rb_left);
122 node = node->rb_left;
123 }
124 if (cid < lsidid->id) {
125 linkto = &(node->rb_right);
126 node = node->rb_right;
127 }
128 }
129
130 (*psidid)->id = cid;
131 (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
132 (*psidid)->refcount = 0;
133
134 sprintf((*psidid)->sidstr, "%s", typestr);
135 strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
136 sprintf(strptr, "%ld", cid);
137
138 clear_bit(SID_ID_PENDING, &(*psidid)->state);
139 clear_bit(SID_ID_MAPPED, &(*psidid)->state);
140
141 rb_link_node(&(*psidid)->rbnode, parent, linkto);
142 rb_insert_color(&(*psidid)->rbnode, root);
143}
144
145static struct cifs_sid_id *
146sid_rb_search(struct rb_root *root, unsigned long cid)
147{
148 struct rb_node *node = root->rb_node;
149 struct cifs_sid_id *lsidid;
150
151 while (node) {
152 lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
153 if (cid > lsidid->id)
154 node = node->rb_left;
155 else if (cid < lsidid->id)
156 node = node->rb_right;
157 else /* node found */
158 return lsidid;
159 }
160
161 return NULL;
162}
163
164static struct shrinker cifs_shrinker = {
165 .shrink = cifs_idmap_shrinker,
166 .seeks = DEFAULT_SEEKS,
167};
168 46
169static int 47static int
170cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 48cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
171{ 49{
172 char *payload; 50 char *payload;
173 51
52 /*
53 * If the payload is less than or equal to the size of a pointer, then
54 * an allocation here is wasteful. Just copy the data directly to the
55 * payload.value union member instead.
56 *
57 * With this however, you must check the datalen before trying to
58 * dereference payload.data!
59 */
60 if (prep->datalen <= sizeof(key->payload)) {
61 key->payload.value = 0;
62 memcpy(&key->payload.value, prep->data, prep->datalen);
63 key->datalen = prep->datalen;
64 return 0;
65 }
174 payload = kmalloc(prep->datalen, GFP_KERNEL); 66 payload = kmalloc(prep->datalen, GFP_KERNEL);
175 if (!payload) 67 if (!payload)
176 return -ENOMEM; 68 return -ENOMEM;
@@ -184,10 +76,11 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
184static inline void 76static inline void
185cifs_idmap_key_destroy(struct key *key) 77cifs_idmap_key_destroy(struct key *key)
186{ 78{
187 kfree(key->payload.data); 79 if (key->datalen > sizeof(key->payload))
80 kfree(key->payload.data);
188} 81}
189 82
190struct key_type cifs_idmap_key_type = { 83static struct key_type cifs_idmap_key_type = {
191 .name = "cifs.idmap", 84 .name = "cifs.idmap",
192 .instantiate = cifs_idmap_key_instantiate, 85 .instantiate = cifs_idmap_key_instantiate,
193 .destroy = cifs_idmap_key_destroy, 86 .destroy = cifs_idmap_key_destroy,
@@ -195,221 +88,174 @@ struct key_type cifs_idmap_key_type = {
195 .match = user_match, 88 .match = user_match,
196}; 89};
197 90
198static void 91static char *
199sid_to_str(struct cifs_sid *sidptr, char *sidstr) 92sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
200{ 93{
201 int i; 94 int i, len;
202 unsigned long saval; 95 unsigned int saval;
203 char *strptr; 96 char *sidstr, *strptr;
97 unsigned long long id_auth_val;
98
99 /* 3 bytes for prefix */
100 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
101 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
102 GFP_KERNEL);
103 if (!sidstr)
104 return sidstr;
204 105
205 strptr = sidstr; 106 strptr = sidstr;
107 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
108 sidptr->revision);
109 strptr += len;
110
111 /* The authority field is a single 48-bit number */
112 id_auth_val = (unsigned long long)sidptr->authority[5];
113 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
114 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
115 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
116 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
117 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
206 118
207 sprintf(strptr, "%s", "S"); 119 /*
208 strptr = sidstr + strlen(sidstr); 120 * MS-DTYP states that if the authority is >= 2^32, then it should be
209 121 * expressed as a hex value.
210 sprintf(strptr, "-%d", sidptr->revision); 122 */
211 strptr = sidstr + strlen(sidstr); 123 if (id_auth_val <= UINT_MAX)
124 len = sprintf(strptr, "-%llu", id_auth_val);
125 else
126 len = sprintf(strptr, "-0x%llx", id_auth_val);
212 127
213 for (i = 0; i < 6; ++i) { 128 strptr += len;
214 if (sidptr->authority[i]) {
215 sprintf(strptr, "-%d", sidptr->authority[i]);
216 strptr = sidstr + strlen(sidstr);
217 }
218 }
219 129
220 for (i = 0; i < sidptr->num_subauth; ++i) { 130 for (i = 0; i < sidptr->num_subauth; ++i) {
221 saval = le32_to_cpu(sidptr->sub_auth[i]); 131 saval = le32_to_cpu(sidptr->sub_auth[i]);
222 sprintf(strptr, "-%ld", saval); 132 len = sprintf(strptr, "-%u", saval);
223 strptr = sidstr + strlen(sidstr); 133 strptr += len;
224 } 134 }
225}
226 135
227static void 136 return sidstr;
228cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
229{
230 memcpy(dst, src, sizeof(*dst));
231 dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
232} 137}
233 138
234static void 139/*
235id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, 140 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
236 struct cifs_sid_id **psidid, char *typestr) 141 * the same returns zero, if they do not match returns non-zero.
142 */
143static int
144compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
237{ 145{
238 int rc; 146 int i;
239 char *strptr; 147 int num_subauth, num_sat, num_saw;
240 struct rb_node *node = root->rb_node;
241 struct rb_node *parent = NULL;
242 struct rb_node **linkto = &(root->rb_node);
243 struct cifs_sid_id *lsidid;
244
245 while (node) {
246 lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
247 parent = node;
248 rc = compare_sids(sidptr, &((lsidid)->sid));
249 if (rc > 0) {
250 linkto = &(node->rb_left);
251 node = node->rb_left;
252 } else if (rc < 0) {
253 linkto = &(node->rb_right);
254 node = node->rb_right;
255 }
256 }
257
258 cifs_copy_sid(&(*psidid)->sid, sidptr);
259 (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
260 (*psidid)->refcount = 0;
261 148
262 sprintf((*psidid)->sidstr, "%s", typestr); 149 if ((!ctsid) || (!cwsid))
263 strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr); 150 return 1;
264 sid_to_str(&(*psidid)->sid, strptr);
265 151
266 clear_bit(SID_ID_PENDING, &(*psidid)->state); 152 /* compare the revision */
267 clear_bit(SID_ID_MAPPED, &(*psidid)->state); 153 if (ctsid->revision != cwsid->revision) {
154 if (ctsid->revision > cwsid->revision)
155 return 1;
156 else
157 return -1;
158 }
268 159
269 rb_link_node(&(*psidid)->rbnode, parent, linkto); 160 /* compare all of the six auth values */
270 rb_insert_color(&(*psidid)->rbnode, root); 161 for (i = 0; i < NUM_AUTHS; ++i) {
271} 162 if (ctsid->authority[i] != cwsid->authority[i]) {
163 if (ctsid->authority[i] > cwsid->authority[i])
164 return 1;
165 else
166 return -1;
167 }
168 }
272 169
273static struct cifs_sid_id * 170 /* compare all of the subauth values if any */
274id_rb_search(struct rb_root *root, struct cifs_sid *sidptr) 171 num_sat = ctsid->num_subauth;
275{ 172 num_saw = cwsid->num_subauth;
276 int rc; 173 num_subauth = num_sat < num_saw ? num_sat : num_saw;
277 struct rb_node *node = root->rb_node; 174 if (num_subauth) {
278 struct cifs_sid_id *lsidid; 175 for (i = 0; i < num_subauth; ++i) {
279 176 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
280 while (node) { 177 if (le32_to_cpu(ctsid->sub_auth[i]) >
281 lsidid = rb_entry(node, struct cifs_sid_id, rbnode); 178 le32_to_cpu(cwsid->sub_auth[i]))
282 rc = compare_sids(sidptr, &((lsidid)->sid)); 179 return 1;
283 if (rc > 0) { 180 else
284 node = node->rb_left; 181 return -1;
285 } else if (rc < 0) { 182 }
286 node = node->rb_right; 183 }
287 } else /* node found */
288 return lsidid;
289 } 184 }
290 185
291 return NULL; 186 return 0; /* sids compare/match */
292} 187}
293 188
294static int 189static void
295sidid_pending_wait(void *unused) 190cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
296{ 191{
297 schedule(); 192 int i;
298 return signal_pending(current) ? -ERESTARTSYS : 0; 193
194 dst->revision = src->revision;
195 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
196 for (i = 0; i < NUM_AUTHS; ++i)
197 dst->authority[i] = src->authority[i];
198 for (i = 0; i < dst->num_subauth; ++i)
199 dst->sub_auth[i] = src->sub_auth[i];
299} 200}
300 201
301static int 202static int
302id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) 203id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
303{ 204{
304 int rc = 0; 205 int rc;
305 struct key *sidkey; 206 struct key *sidkey;
207 struct cifs_sid *ksid;
208 unsigned int ksid_size;
209 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
306 const struct cred *saved_cred; 210 const struct cred *saved_cred;
307 struct cifs_sid *lsid;
308 struct cifs_sid_id *psidid, *npsidid;
309 struct rb_root *cidtree;
310 spinlock_t *cidlock;
311
312 if (sidtype == SIDOWNER) {
313 cidlock = &siduidlock;
314 cidtree = &uidtree;
315 } else if (sidtype == SIDGROUP) {
316 cidlock = &sidgidlock;
317 cidtree = &gidtree;
318 } else
319 return -EINVAL;
320
321 spin_lock(cidlock);
322 psidid = sid_rb_search(cidtree, cid);
323 211
324 if (!psidid) { /* node does not exist, allocate one & attempt adding */ 212 rc = snprintf(desc, sizeof(desc), "%ci:%u",
325 spin_unlock(cidlock); 213 sidtype == SIDOWNER ? 'o' : 'g', cid);
326 npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL); 214 if (rc >= sizeof(desc))
327 if (!npsidid) 215 return -EINVAL;
328 return -ENOMEM;
329
330 npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
331 if (!npsidid->sidstr) {
332 kfree(npsidid);
333 return -ENOMEM;
334 }
335 216
336 spin_lock(cidlock); 217 rc = 0;
337 psidid = sid_rb_search(cidtree, cid); 218 saved_cred = override_creds(root_cred);
338 if (psidid) { /* node happened to get inserted meanwhile */ 219 sidkey = request_key(&cifs_idmap_key_type, desc, "");
339 ++psidid->refcount; 220 if (IS_ERR(sidkey)) {
340 spin_unlock(cidlock); 221 rc = -EINVAL;
341 kfree(npsidid->sidstr); 222 cFYI(1, "%s: Can't map %cid %u to a SID", __func__,
342 kfree(npsidid); 223 sidtype == SIDOWNER ? 'u' : 'g', cid);
343 } else { 224 goto out_revert_creds;
344 psidid = npsidid; 225 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
345 sid_rb_insert(cidtree, cid, &psidid, 226 rc = -EIO;
346 sidtype == SIDOWNER ? "oi:" : "gi:"); 227 cFYI(1, "%s: Downcall contained malformed key "
347 ++psidid->refcount; 228 "(datalen=%hu)", __func__, sidkey->datalen);
348 spin_unlock(cidlock); 229 goto invalidate_key;
349 }
350 } else {
351 ++psidid->refcount;
352 spin_unlock(cidlock);
353 } 230 }
354 231
355 /* 232 /*
356 * If we are here, it is safe to access psidid and its fields 233 * A sid is usually too large to be embedded in payload.value, but if
357 * since a reference was taken earlier while holding the spinlock. 234 * there are no subauthorities and the host has 8-byte pointers, then
358 * A reference on the node is put without holding the spinlock 235 * it could be.
359 * and it is OK to do so in this case, shrinker will not erase
360 * this node until all references are put and we do not access
361 * any fields of the node after a reference is put .
362 */ 236 */
363 if (test_bit(SID_ID_MAPPED, &psidid->state)) { 237 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
364 cifs_copy_sid(ssid, &psidid->sid); 238 (struct cifs_sid *)&sidkey->payload.value :
365 psidid->time = jiffies; /* update ts for accessing */ 239 (struct cifs_sid *)sidkey->payload.data;
366 goto id_sid_out; 240
241 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
242 if (ksid_size > sidkey->datalen) {
243 rc = -EIO;
244 cFYI(1, "%s: Downcall contained malformed key (datalen=%hu, "
245 "ksid_size=%u)", __func__, sidkey->datalen, ksid_size);
246 goto invalidate_key;
367 } 247 }
368 248
369 if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) { 249 cifs_copy_sid(ssid, ksid);
370 rc = -EINVAL; 250out_key_put:
371 goto id_sid_out; 251 key_put(sidkey);
372 } 252out_revert_creds:
373 253 revert_creds(saved_cred);
374 if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
375 saved_cred = override_creds(root_cred);
376 sidkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
377 if (IS_ERR(sidkey)) {
378 rc = -EINVAL;
379 cFYI(1, "%s: Can't map and id to a SID", __func__);
380 } else if (sidkey->datalen < sizeof(struct cifs_sid)) {
381 rc = -EIO;
382 cFYI(1, "%s: Downcall contained malformed key "
383 "(datalen=%hu)", __func__, sidkey->datalen);
384 } else {
385 lsid = (struct cifs_sid *)sidkey->payload.data;
386 cifs_copy_sid(&psidid->sid, lsid);
387 cifs_copy_sid(ssid, &psidid->sid);
388 set_bit(SID_ID_MAPPED, &psidid->state);
389 key_put(sidkey);
390 kfree(psidid->sidstr);
391 }
392 psidid->time = jiffies; /* update ts for accessing */
393 revert_creds(saved_cred);
394 clear_bit(SID_ID_PENDING, &psidid->state);
395 wake_up_bit(&psidid->state, SID_ID_PENDING);
396 } else {
397 rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
398 sidid_pending_wait, TASK_INTERRUPTIBLE);
399 if (rc) {
400 cFYI(1, "%s: sidid_pending_wait interrupted %d",
401 __func__, rc);
402 --psidid->refcount;
403 return rc;
404 }
405 if (test_bit(SID_ID_MAPPED, &psidid->state))
406 cifs_copy_sid(ssid, &psidid->sid);
407 else
408 rc = -EINVAL;
409 }
410id_sid_out:
411 --psidid->refcount;
412 return rc; 254 return rc;
255
256invalidate_key:
257 key_invalidate(sidkey);
258 goto out_key_put;
413} 259}
414 260
415static int 261static int
@@ -417,111 +263,67 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
417 struct cifs_fattr *fattr, uint sidtype) 263 struct cifs_fattr *fattr, uint sidtype)
418{ 264{
419 int rc; 265 int rc;
420 unsigned long cid; 266 struct key *sidkey;
421 struct key *idkey; 267 char *sidstr;
422 const struct cred *saved_cred; 268 const struct cred *saved_cred;
423 struct cifs_sid_id *psidid, *npsidid; 269 uid_t fuid = cifs_sb->mnt_uid;
424 struct rb_root *cidtree; 270 gid_t fgid = cifs_sb->mnt_gid;
425 spinlock_t *cidlock;
426
427 if (sidtype == SIDOWNER) {
428 cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */
429 cidlock = &siduidlock;
430 cidtree = &uidtree;
431 } else if (sidtype == SIDGROUP) {
432 cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */
433 cidlock = &sidgidlock;
434 cidtree = &gidtree;
435 } else
436 return -ENOENT;
437
438 spin_lock(cidlock);
439 psidid = id_rb_search(cidtree, psid);
440
441 if (!psidid) { /* node does not exist, allocate one & attempt adding */
442 spin_unlock(cidlock);
443 npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
444 if (!npsidid)
445 return -ENOMEM;
446
447 npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
448 if (!npsidid->sidstr) {
449 kfree(npsidid);
450 return -ENOMEM;
451 }
452
453 spin_lock(cidlock);
454 psidid = id_rb_search(cidtree, psid);
455 if (psidid) { /* node happened to get inserted meanwhile */
456 ++psidid->refcount;
457 spin_unlock(cidlock);
458 kfree(npsidid->sidstr);
459 kfree(npsidid);
460 } else {
461 psidid = npsidid;
462 id_rb_insert(cidtree, psid, &psidid,
463 sidtype == SIDOWNER ? "os:" : "gs:");
464 ++psidid->refcount;
465 spin_unlock(cidlock);
466 }
467 } else {
468 ++psidid->refcount;
469 spin_unlock(cidlock);
470 }
471 271
472 /* 272 /*
473 * If we are here, it is safe to access psidid and its fields 273 * If we have too many subauthorities, then something is really wrong.
474 * since a reference was taken earlier while holding the spinlock. 274 * Just return an error.
475 * A reference on the node is put without holding the spinlock
476 * and it is OK to do so in this case, shrinker will not erase
477 * this node until all references are put and we do not access
478 * any fields of the node after a reference is put .
479 */ 275 */
480 if (test_bit(SID_ID_MAPPED, &psidid->state)) { 276 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
481 cid = psidid->id; 277 cFYI(1, "%s: %u subauthorities is too many!", __func__,
482 psidid->time = jiffies; /* update ts for accessing */ 278 psid->num_subauth);
483 goto sid_to_id_out; 279 return -EIO;
484 } 280 }
485 281
486 if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) 282 sidstr = sid_to_key_str(psid, sidtype);
487 goto sid_to_id_out; 283 if (!sidstr)
488 284 return -ENOMEM;
489 if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) { 285
490 saved_cred = override_creds(root_cred); 286 saved_cred = override_creds(root_cred);
491 idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, ""); 287 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
492 if (IS_ERR(idkey)) 288 if (IS_ERR(sidkey)) {
493 cFYI(1, "%s: Can't map SID to an id", __func__); 289 rc = -EINVAL;
494 else { 290 cFYI(1, "%s: Can't map SID %s to a %cid", __func__, sidstr,
495 cid = *(unsigned long *)idkey->payload.value; 291 sidtype == SIDOWNER ? 'u' : 'g');
496 psidid->id = cid; 292 goto out_revert_creds;
497 set_bit(SID_ID_MAPPED, &psidid->state); 293 }
498 key_put(idkey); 294
499 kfree(psidid->sidstr); 295 /*
500 } 296 * FIXME: Here we assume that uid_t and gid_t are same size. It's
501 revert_creds(saved_cred); 297 * probably a safe assumption but might be better to check based on
502 psidid->time = jiffies; /* update ts for accessing */ 298 * sidtype.
503 clear_bit(SID_ID_PENDING, &psidid->state); 299 */
504 wake_up_bit(&psidid->state, SID_ID_PENDING); 300 if (sidkey->datalen != sizeof(uid_t)) {
505 } else { 301 rc = -EIO;
506 rc = wait_on_bit(&psidid->state, SID_ID_PENDING, 302 cFYI(1, "%s: Downcall contained malformed key "
507 sidid_pending_wait, TASK_INTERRUPTIBLE); 303 "(datalen=%hu)", __func__, sidkey->datalen);
508 if (rc) { 304 key_invalidate(sidkey);
509 cFYI(1, "%s: sidid_pending_wait interrupted %d", 305 goto out_key_put;
510 __func__, rc);
511 --psidid->refcount; /* decremented without spinlock */
512 return rc;
513 }
514 if (test_bit(SID_ID_MAPPED, &psidid->state))
515 cid = psidid->id;
516 } 306 }
517 307
518sid_to_id_out:
519 --psidid->refcount; /* decremented without spinlock */
520 if (sidtype == SIDOWNER) 308 if (sidtype == SIDOWNER)
521 fattr->cf_uid = cid; 309 memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
522 else 310 else
523 fattr->cf_gid = cid; 311 memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t));
312
313out_key_put:
314 key_put(sidkey);
315out_revert_creds:
316 revert_creds(saved_cred);
317 kfree(sidstr);
524 318
319 /*
320 * Note that we return 0 here unconditionally. If the mapping
321 * fails then we just fall back to using the mnt_uid/mnt_gid.
322 */
323 if (sidtype == SIDOWNER)
324 fattr->cf_uid = fuid;
325 else
326 fattr->cf_gid = fgid;
525 return 0; 327 return 0;
526} 328}
527 329
@@ -568,17 +370,6 @@ init_cifs_idmap(void)
568 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 370 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
569 root_cred = cred; 371 root_cred = cred;
570 372
571 spin_lock_init(&siduidlock);
572 uidtree = RB_ROOT;
573 spin_lock_init(&sidgidlock);
574 gidtree = RB_ROOT;
575
576 spin_lock_init(&uidsidlock);
577 siduidtree = RB_ROOT;
578 spin_lock_init(&gidsidlock);
579 sidgidtree = RB_ROOT;
580 register_shrinker(&cifs_shrinker);
581
582 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring)); 373 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
583 return 0; 374 return 0;
584 375
@@ -595,89 +386,9 @@ exit_cifs_idmap(void)
595 key_revoke(root_cred->thread_keyring); 386 key_revoke(root_cred->thread_keyring);
596 unregister_key_type(&cifs_idmap_key_type); 387 unregister_key_type(&cifs_idmap_key_type);
597 put_cred(root_cred); 388 put_cred(root_cred);
598 unregister_shrinker(&cifs_shrinker);
599 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name); 389 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
600} 390}
601 391
602void
603cifs_destroy_idmaptrees(void)
604{
605 struct rb_root *root;
606 struct rb_node *node;
607
608 root = &uidtree;
609 spin_lock(&siduidlock);
610 while ((node = rb_first(root)))
611 rb_erase(node, root);
612 spin_unlock(&siduidlock);
613
614 root = &gidtree;
615 spin_lock(&sidgidlock);
616 while ((node = rb_first(root)))
617 rb_erase(node, root);
618 spin_unlock(&sidgidlock);
619
620 root = &siduidtree;
621 spin_lock(&uidsidlock);
622 while ((node = rb_first(root)))
623 rb_erase(node, root);
624 spin_unlock(&uidsidlock);
625
626 root = &sidgidtree;
627 spin_lock(&gidsidlock);
628 while ((node = rb_first(root)))
629 rb_erase(node, root);
630 spin_unlock(&gidsidlock);
631}
632
633/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
634 the same returns 1, if they do not match returns 0 */
635int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
636{
637 int i;
638 int num_subauth, num_sat, num_saw;
639
640 if ((!ctsid) || (!cwsid))
641 return 1;
642
643 /* compare the revision */
644 if (ctsid->revision != cwsid->revision) {
645 if (ctsid->revision > cwsid->revision)
646 return 1;
647 else
648 return -1;
649 }
650
651 /* compare all of the six auth values */
652 for (i = 0; i < 6; ++i) {
653 if (ctsid->authority[i] != cwsid->authority[i]) {
654 if (ctsid->authority[i] > cwsid->authority[i])
655 return 1;
656 else
657 return -1;
658 }
659 }
660
661 /* compare all of the subauth values if any */
662 num_sat = ctsid->num_subauth;
663 num_saw = cwsid->num_subauth;
664 num_subauth = num_sat < num_saw ? num_sat : num_saw;
665 if (num_subauth) {
666 for (i = 0; i < num_subauth; ++i) {
667 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
668 if (le32_to_cpu(ctsid->sub_auth[i]) >
669 le32_to_cpu(cwsid->sub_auth[i]))
670 return 1;
671 else
672 return -1;
673 }
674 }
675 }
676
677 return 0; /* sids compare/match */
678}
679
680
681/* copy ntsd, owner sid, and group sid from a security descriptor to another */ 392/* copy ntsd, owner sid, and group sid from a security descriptor to another */
682static void copy_sec_desc(const struct cifs_ntsd *pntsd, 393static void copy_sec_desc(const struct cifs_ntsd *pntsd,
683 struct cifs_ntsd *pnntsd, __u32 sidsoffset) 394 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
@@ -811,7 +522,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
811 522
812 pntace->sid.revision = psid->revision; 523 pntace->sid.revision = psid->revision;
813 pntace->sid.num_subauth = psid->num_subauth; 524 pntace->sid.num_subauth = psid->num_subauth;
814 for (i = 0; i < 6; i++) 525 for (i = 0; i < NUM_AUTHS; i++)
815 pntace->sid.authority[i] = psid->authority[i]; 526 pntace->sid.authority[i] = psid->authority[i];
816 for (i = 0; i < psid->num_subauth; i++) 527 for (i = 0; i < psid->num_subauth; i++)
817 pntace->sid.sub_auth[i] = psid->sub_auth[i]; 528 pntace->sid.sub_auth[i] = psid->sub_auth[i];
@@ -987,8 +698,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
987 return -EINVAL; 698 return -EINVAL;
988 } 699 }
989 700
990 if (psid->num_subauth) {
991#ifdef CONFIG_CIFS_DEBUG2 701#ifdef CONFIG_CIFS_DEBUG2
702 if (psid->num_subauth) {
992 int i; 703 int i;
993 cFYI(1, "SID revision %d num_auth %d", 704 cFYI(1, "SID revision %d num_auth %d",
994 psid->revision, psid->num_subauth); 705 psid->revision, psid->num_subauth);
@@ -1002,8 +713,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1002 num auths and therefore go off the end */ 713 num auths and therefore go off the end */
1003 cFYI(1, "RID 0x%x", 714 cFYI(1, "RID 0x%x",
1004 le32_to_cpu(psid->sub_auth[psid->num_subauth-1])); 715 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1005#endif
1006 } 716 }
717#endif
1007 718
1008 return 0; 719 return 0;
1009} 720}
@@ -1307,42 +1018,39 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1307 1018
1308 /* Get the security descriptor */ 1019 /* Get the security descriptor */
1309 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); 1020 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1310
1311 /* Add three ACEs for owner, group, everyone getting rid of
1312 other ACEs as chmod disables ACEs and set the security descriptor */
1313
1314 if (IS_ERR(pntsd)) { 1021 if (IS_ERR(pntsd)) {
1315 rc = PTR_ERR(pntsd); 1022 rc = PTR_ERR(pntsd);
1316 cERROR(1, "%s: error %d getting sec desc", __func__, rc); 1023 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1317 } else { 1024 goto out;
1318 /* allocate memory for the smb header, 1025 }
1319 set security descriptor request security descriptor
1320 parameters, and secuirty descriptor itself */
1321
1322 secdesclen = secdesclen < DEFSECDESCLEN ?
1323 DEFSECDESCLEN : secdesclen;
1324 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1325 if (!pnntsd) {
1326 cERROR(1, "Unable to allocate security descriptor");
1327 kfree(pntsd);
1328 return -ENOMEM;
1329 }
1330 1026
1331 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, 1027 /*
1332 &aclflag); 1028 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1029 * as chmod disables ACEs and set the security descriptor. Allocate
1030 * memory for the smb header, set security descriptor request security
1031 * descriptor parameters, and secuirty descriptor itself
1032 */
1033 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1034 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1035 if (!pnntsd) {
1036 cERROR(1, "Unable to allocate security descriptor");
1037 kfree(pntsd);
1038 return -ENOMEM;
1039 }
1333 1040
1334 cFYI(DBG2, "build_sec_desc rc: %d", rc); 1041 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1042 &aclflag);
1335 1043
1336 if (!rc) { 1044 cFYI(DBG2, "build_sec_desc rc: %d", rc);
1337 /* Set the security descriptor */
1338 rc = set_cifs_acl(pnntsd, secdesclen, inode,
1339 path, aclflag);
1340 cFYI(DBG2, "set_cifs_acl rc: %d", rc);
1341 }
1342 1045
1343 kfree(pnntsd); 1046 if (!rc) {
1344 kfree(pntsd); 1047 /* Set the security descriptor */
1048 rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
1049 cFYI(DBG2, "set_cifs_acl rc: %d", rc);
1345 } 1050 }
1346 1051
1052 kfree(pnntsd);
1053 kfree(pntsd);
1054out:
1347 return rc; 1055 return rc;
1348} 1056}
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 5c902c7ce524..4f3884835267 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -23,11 +23,8 @@
23#define _CIFSACL_H 23#define _CIFSACL_H
24 24
25 25
26#define NUM_AUTHS 6 /* number of authority fields */ 26#define NUM_AUTHS (6) /* number of authority fields */
27#define NUM_SUBAUTHS 5 /* number of sub authority fields */ 27#define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */
28#define NUM_WK_SIDS 7 /* number of well known sids */
29#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
30#define DEFSECDESCLEN 192 /* sec desc len contaiting a dacl with three aces */
31 28
32#define READ_BIT 0x4 29#define READ_BIT 0x4
33#define WRITE_BIT 0x2 30#define WRITE_BIT 0x2
@@ -41,12 +38,32 @@
41 38
42#define SIDOWNER 1 39#define SIDOWNER 1
43#define SIDGROUP 2 40#define SIDGROUP 2
44#define SIDLEN 150 /* S- 1 revision- 6 authorities- max 5 sub authorities */
45 41
46#define SID_ID_MAPPED 0 42/*
47#define SID_ID_PENDING 1 43 * Security Descriptor length containing DACL with 3 ACEs (one each for
48#define SID_MAP_EXPIRE (3600 * HZ) /* map entry expires after one hour */ 44 * owner, group and world).
49#define SID_MAP_RETRY (300 * HZ) /* wait 5 minutes for next attempt to map */ 45 */
46#define DEFAULT_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + \
47 sizeof(struct cifs_acl) + \
48 (sizeof(struct cifs_ace) * 3))
49
50/*
51 * Maximum size of a string representation of a SID:
52 *
53 * The fields are unsigned values in decimal. So:
54 *
55 * u8: max 3 bytes in decimal
56 * u32: max 10 bytes in decimal
57 *
58 * "S-" + 3 bytes for version field + 15 for authority field + NULL terminator
59 *
60 * For authority field, max is when all 6 values are non-zero and it must be
61 * represented in hex. So "-0x" + 12 hex digits.
62 *
63 * Add 11 bytes for each subauthority field (10 bytes each + 1 for '-')
64 */
65#define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1)
66#define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */
50 67
51struct cifs_ntsd { 68struct cifs_ntsd {
52 __le16 revision; /* revision level */ 69 __le16 revision; /* revision level */
@@ -60,10 +77,13 @@ struct cifs_ntsd {
60struct cifs_sid { 77struct cifs_sid {
61 __u8 revision; /* revision level */ 78 __u8 revision; /* revision level */
62 __u8 num_subauth; 79 __u8 num_subauth;
63 __u8 authority[6]; 80 __u8 authority[NUM_AUTHS];
64 __le32 sub_auth[5]; /* sub_auth[num_subauth] */ 81 __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */
65} __attribute__((packed)); 82} __attribute__((packed));
66 83
84/* size of a struct cifs_sid, sans sub_auth array */
85#define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS)
86
67struct cifs_acl { 87struct cifs_acl {
68 __le16 revision; /* revision level */ 88 __le16 revision; /* revision level */
69 __le16 size; 89 __le16 size;
@@ -78,26 +98,4 @@ struct cifs_ace {
78 struct cifs_sid sid; /* ie UUID of user or group who gets these perms */ 98 struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
79} __attribute__((packed)); 99} __attribute__((packed));
80 100
81struct cifs_wksid {
82 struct cifs_sid cifssid;
83 char sidname[SIDNAMELENGTH];
84} __attribute__((packed));
85
86struct cifs_sid_id {
87 unsigned int refcount; /* increment with spinlock, decrement without */
88 unsigned long id;
89 unsigned long time;
90 unsigned long state;
91 char *sidstr;
92 struct rb_node rbnode;
93 struct cifs_sid sid;
94};
95
96#ifdef __KERNEL__
97extern struct key_type cifs_idmap_key_type;
98extern const struct cred *root_cred;
99#endif /* KERNEL */
100
101extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
102
103#endif /* _CIFSACL_H */ 101#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index e7931cc55d0c..210f0af83fc4 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -64,24 +64,23 @@ unsigned int global_secflags = CIFSSEC_DEF;
64unsigned int sign_CIFS_PDUs = 1; 64unsigned int sign_CIFS_PDUs = 1;
65static const struct super_operations cifs_super_ops; 65static const struct super_operations cifs_super_ops;
66unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 66unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
67module_param(CIFSMaxBufSize, int, 0); 67module_param(CIFSMaxBufSize, uint, 0);
68MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). " 68MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
69 "Default: 16384 Range: 8192 to 130048"); 69 "Default: 16384 Range: 8192 to 130048");
70unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; 70unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
71module_param(cifs_min_rcv, int, 0); 71module_param(cifs_min_rcv, uint, 0);
72MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: " 72MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
73 "1 to 64"); 73 "1 to 64");
74unsigned int cifs_min_small = 30; 74unsigned int cifs_min_small = 30;
75module_param(cifs_min_small, int, 0); 75module_param(cifs_min_small, uint, 0);
76MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 " 76MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
77 "Range: 2 to 256"); 77 "Range: 2 to 256");
78unsigned int cifs_max_pending = CIFS_MAX_REQ; 78unsigned int cifs_max_pending = CIFS_MAX_REQ;
79module_param(cifs_max_pending, int, 0444); 79module_param(cifs_max_pending, uint, 0444);
80MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " 80MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
81 "Default: 32767 Range: 2 to 32767."); 81 "Default: 32767 Range: 2 to 32767.");
82module_param(enable_oplocks, bool, 0644); 82module_param(enable_oplocks, bool, 0644);
83MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks (bool). Default:" 83MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1");
84 "y/Y/1");
85 84
86extern mempool_t *cifs_sm_req_poolp; 85extern mempool_t *cifs_sm_req_poolp;
87extern mempool_t *cifs_req_poolp; 86extern mempool_t *cifs_req_poolp;
@@ -230,6 +229,7 @@ cifs_alloc_inode(struct super_block *sb)
230 cifs_set_oplock_level(cifs_inode, 0); 229 cifs_set_oplock_level(cifs_inode, 0);
231 cifs_inode->delete_pending = false; 230 cifs_inode->delete_pending = false;
232 cifs_inode->invalid_mapping = false; 231 cifs_inode->invalid_mapping = false;
232 cifs_inode->leave_pages_clean = false;
233 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 233 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
234 cifs_inode->server_eof = 0; 234 cifs_inode->server_eof = 0;
235 cifs_inode->uniqueid = 0; 235 cifs_inode->uniqueid = 0;
@@ -540,8 +540,8 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
540 char *s, *p; 540 char *s, *p;
541 char sep; 541 char sep;
542 542
543 full_path = build_path_to_root(vol, cifs_sb, 543 full_path = cifs_build_path_to_root(vol, cifs_sb,
544 cifs_sb_master_tcon(cifs_sb)); 544 cifs_sb_master_tcon(cifs_sb));
545 if (full_path == NULL) 545 if (full_path == NULL)
546 return ERR_PTR(-ENOMEM); 546 return ERR_PTR(-ENOMEM);
547 547
@@ -1205,7 +1205,6 @@ exit_cifs(void)
1205 unregister_filesystem(&cifs_fs_type); 1205 unregister_filesystem(&cifs_fs_type);
1206 cifs_dfs_release_automount_timer(); 1206 cifs_dfs_release_automount_timer();
1207#ifdef CONFIG_CIFS_ACL 1207#ifdef CONFIG_CIFS_ACL
1208 cifs_destroy_idmaptrees();
1209 exit_cifs_idmap(); 1208 exit_cifs_idmap();
1210#endif 1209#endif
1211#ifdef CONFIG_CIFS_UPCALL 1210#ifdef CONFIG_CIFS_UPCALL
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index f5af2527fc69..aea1eec64911 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -178,6 +178,7 @@ struct smb_rqst {
178 178
179enum smb_version { 179enum smb_version {
180 Smb_1 = 1, 180 Smb_1 = 1,
181 Smb_20,
181 Smb_21, 182 Smb_21,
182 Smb_30, 183 Smb_30,
183}; 184};
@@ -280,9 +281,6 @@ struct smb_version_operations {
280 /* set attributes */ 281 /* set attributes */
281 int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *, 282 int (*set_file_info)(struct inode *, const char *, FILE_BASIC_INFO *,
282 const unsigned int); 283 const unsigned int);
283 /* build a full path to the root of the mount */
284 char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *,
285 struct cifs_tcon *);
286 /* check if we can send an echo or nor */ 284 /* check if we can send an echo or nor */
287 bool (*can_echo)(struct TCP_Server_Info *); 285 bool (*can_echo)(struct TCP_Server_Info *);
288 /* send echo request */ 286 /* send echo request */
@@ -369,6 +367,8 @@ struct smb_version_operations {
369 void (*set_lease_key)(struct inode *, struct cifs_fid *fid); 367 void (*set_lease_key)(struct inode *, struct cifs_fid *fid);
370 /* generate new lease key */ 368 /* generate new lease key */
371 void (*new_lease_key)(struct cifs_fid *fid); 369 void (*new_lease_key)(struct cifs_fid *fid);
370 int (*calc_signature)(struct smb_rqst *rqst,
371 struct TCP_Server_Info *server);
372}; 372};
373 373
374struct smb_version_values { 374struct smb_version_values {
@@ -396,7 +396,6 @@ struct smb_vol {
396 char *password; 396 char *password;
397 char *domainname; 397 char *domainname;
398 char *UNC; 398 char *UNC;
399 char *UNCip;
400 char *iocharset; /* local code page for mapping to and from Unicode */ 399 char *iocharset; /* local code page for mapping to and from Unicode */
401 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ 400 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
402 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ 401 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
@@ -444,11 +443,11 @@ struct smb_vol {
444 unsigned int rsize; 443 unsigned int rsize;
445 unsigned int wsize; 444 unsigned int wsize;
446 bool sockopt_tcp_nodelay:1; 445 bool sockopt_tcp_nodelay:1;
447 unsigned short int port;
448 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 446 unsigned long actimeo; /* attribute cache timeout (jiffies) */
449 struct smb_version_operations *ops; 447 struct smb_version_operations *ops;
450 struct smb_version_values *vals; 448 struct smb_version_values *vals;
451 char *prepath; 449 char *prepath;
450 struct sockaddr_storage dstaddr; /* destination address */
452 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 451 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
453 struct nls_table *local_nls; 452 struct nls_table *local_nls;
454}; 453};
@@ -1031,6 +1030,7 @@ struct cifsInodeInfo {
1031 bool clientCanCacheAll; /* read and writebehind oplock */ 1030 bool clientCanCacheAll; /* read and writebehind oplock */
1032 bool delete_pending; /* DELETE_ON_CLOSE is set */ 1031 bool delete_pending; /* DELETE_ON_CLOSE is set */
1033 bool invalid_mapping; /* pagecache is invalid */ 1032 bool invalid_mapping; /* pagecache is invalid */
1033 bool leave_pages_clean; /* protected by i_mutex, not set pages dirty */
1034 unsigned long time; /* jiffies of last update of inode */ 1034 unsigned long time; /* jiffies of last update of inode */
1035 u64 server_eof; /* current file size on server -- protected by i_lock */ 1035 u64 server_eof; /* current file size on server -- protected by i_lock */
1036 u64 uniqueid; /* server inode number */ 1036 u64 uniqueid; /* server inode number */
@@ -1067,30 +1067,16 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
1067static inline void 1067static inline void
1068convert_delimiter(char *path, char delim) 1068convert_delimiter(char *path, char delim)
1069{ 1069{
1070 int i; 1070 char old_delim, *pos;
1071 char old_delim;
1072
1073 if (path == NULL)
1074 return;
1075 1071
1076 if (delim == '/') 1072 if (delim == '/')
1077 old_delim = '\\'; 1073 old_delim = '\\';
1078 else 1074 else
1079 old_delim = '/'; 1075 old_delim = '/';
1080 1076
1081 for (i = 0; path[i] != '\0'; i++) { 1077 pos = path;
1082 if (path[i] == old_delim) 1078 while ((pos = strchr(pos, old_delim)))
1083 path[i] = delim; 1079 *pos = delim;
1084 }
1085}
1086
1087static inline char *
1088build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
1089 struct cifs_tcon *tcon)
1090{
1091 if (!vol->ops->build_path_to_root)
1092 return NULL;
1093 return vol->ops->build_path_to_root(vol, cifs_sb, tcon);
1094} 1080}
1095 1081
1096#ifdef CONFIG_CIFS_STATS 1082#ifdef CONFIG_CIFS_STATS
@@ -1362,7 +1348,7 @@ require use of the stronger protocol */
1362#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ 1348#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
1363#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */ 1349#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
1364 1350
1365#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP) 1351#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMSSP)
1366#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2) 1352#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
1367#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP) 1353#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
1368/* 1354/*
@@ -1506,6 +1492,6 @@ extern struct smb_version_values smb20_values;
1506extern struct smb_version_operations smb21_operations; 1492extern struct smb_version_operations smb21_operations;
1507extern struct smb_version_values smb21_values; 1493extern struct smb_version_values smb21_values;
1508#define SMB30_VERSION_STRING "3.0" 1494#define SMB30_VERSION_STRING "3.0"
1509/*extern struct smb_version_operations smb30_operations; */ /* not needed yet */ 1495extern struct smb_version_operations smb30_operations;
1510extern struct smb_version_values smb30_values; 1496extern struct smb_version_values smb30_values;
1511#endif /* _CIFS_GLOB_H */ 1497#endif /* _CIFS_GLOB_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 5144e9fbeb8c..1988c1baa224 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -58,8 +58,10 @@ do { \
58} while (0) 58} while (0)
59extern int init_cifs_idmap(void); 59extern int init_cifs_idmap(void);
60extern void exit_cifs_idmap(void); 60extern void exit_cifs_idmap(void);
61extern void cifs_destroy_idmaptrees(void);
62extern char *build_path_from_dentry(struct dentry *); 61extern char *build_path_from_dentry(struct dentry *);
62extern char *cifs_build_path_to_root(struct smb_vol *vol,
63 struct cifs_sb_info *cifs_sb,
64 struct cifs_tcon *tcon);
63extern char *build_wildcard_path_from_dentry(struct dentry *direntry); 65extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
64extern char *cifs_compose_mount_options(const char *sb_mountdata, 66extern char *cifs_compose_mount_options(const char *sb_mountdata,
65 const char *fullpath, const struct dfs_info3_param *ref, 67 const char *fullpath, const struct dfs_info3_param *ref,
@@ -107,9 +109,7 @@ extern unsigned int smbCalcSize(void *buf);
107extern int decode_negTokenInit(unsigned char *security_blob, int length, 109extern int decode_negTokenInit(unsigned char *security_blob, int length,
108 struct TCP_Server_Info *server); 110 struct TCP_Server_Info *server);
109extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); 111extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
110extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); 112extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
111extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
112 const unsigned short int port);
113extern int map_smb_to_linux_error(char *buf, bool logErr); 113extern int map_smb_to_linux_error(char *buf, bool logErr);
114extern void header_assemble(struct smb_hdr *, char /* command */ , 114extern void header_assemble(struct smb_hdr *, char /* command */ ,
115 const struct cifs_tcon *, int /* length of 115 const struct cifs_tcon *, int /* length of
@@ -185,7 +185,7 @@ extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
185extern bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, 185extern bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset,
186 __u64 length, __u8 type, 186 __u64 length, __u8 type,
187 struct cifsLockInfo **conf_lock, 187 struct cifsLockInfo **conf_lock,
188 bool rw_check); 188 int rw_check);
189extern void cifs_add_pending_open(struct cifs_fid *fid, 189extern void cifs_add_pending_open(struct cifs_fid *fid,
190 struct tcon_link *tlink, 190 struct tcon_link *tlink,
191 struct cifs_pending_open *open); 191 struct cifs_pending_open *open);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5c670b998ffb..7635b5db26a7 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -186,6 +186,7 @@ static const match_table_t cifs_mount_option_tokens = {
186 { Opt_user, "user=%s" }, 186 { Opt_user, "user=%s" },
187 { Opt_user, "username=%s" }, 187 { Opt_user, "username=%s" },
188 { Opt_blank_pass, "pass=" }, 188 { Opt_blank_pass, "pass=" },
189 { Opt_blank_pass, "password=" },
189 { Opt_pass, "pass=%s" }, 190 { Opt_pass, "pass=%s" },
190 { Opt_pass, "password=%s" }, 191 { Opt_pass, "password=%s" },
191 { Opt_blank_ip, "ip=" }, 192 { Opt_blank_ip, "ip=" },
@@ -274,6 +275,7 @@ static const match_table_t cifs_cacheflavor_tokens = {
274 275
275static const match_table_t cifs_smb_version_tokens = { 276static const match_table_t cifs_smb_version_tokens = {
276 { Smb_1, SMB1_VERSION_STRING }, 277 { Smb_1, SMB1_VERSION_STRING },
278 { Smb_20, SMB20_VERSION_STRING},
277 { Smb_21, SMB21_VERSION_STRING }, 279 { Smb_21, SMB21_VERSION_STRING },
278 { Smb_30, SMB30_VERSION_STRING }, 280 { Smb_30, SMB30_VERSION_STRING },
279}; 281};
@@ -1074,12 +1076,16 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol)
1074 vol->vals = &smb1_values; 1076 vol->vals = &smb1_values;
1075 break; 1077 break;
1076#ifdef CONFIG_CIFS_SMB2 1078#ifdef CONFIG_CIFS_SMB2
1079 case Smb_20:
1080 vol->ops = &smb21_operations; /* currently identical with 2.1 */
1081 vol->vals = &smb20_values;
1082 break;
1077 case Smb_21: 1083 case Smb_21:
1078 vol->ops = &smb21_operations; 1084 vol->ops = &smb21_operations;
1079 vol->vals = &smb21_values; 1085 vol->vals = &smb21_values;
1080 break; 1086 break;
1081 case Smb_30: 1087 case Smb_30:
1082 vol->ops = &smb21_operations; /* currently identical with 2.1 */ 1088 vol->ops = &smb30_operations;
1083 vol->vals = &smb30_values; 1089 vol->vals = &smb30_values;
1084 break; 1090 break;
1085#endif 1091#endif
@@ -1090,6 +1096,52 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol)
1090 return 0; 1096 return 0;
1091} 1097}
1092 1098
1099/*
1100 * Parse a devname into substrings and populate the vol->UNC and vol->prepath
1101 * fields with the result. Returns 0 on success and an error otherwise.
1102 */
1103static int
1104cifs_parse_devname(const char *devname, struct smb_vol *vol)
1105{
1106 char *pos;
1107 const char *delims = "/\\";
1108 size_t len;
1109
1110 /* make sure we have a valid UNC double delimiter prefix */
1111 len = strspn(devname, delims);
1112 if (len != 2)
1113 return -EINVAL;
1114
1115 /* find delimiter between host and sharename */
1116 pos = strpbrk(devname + 2, delims);
1117 if (!pos)
1118 return -EINVAL;
1119
1120 /* skip past delimiter */
1121 ++pos;
1122
1123 /* now go until next delimiter or end of string */
1124 len = strcspn(pos, delims);
1125
1126 /* move "pos" up to delimiter or NULL */
1127 pos += len;
1128 vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
1129 if (!vol->UNC)
1130 return -ENOMEM;
1131
1132 convert_delimiter(vol->UNC, '\\');
1133
1134 /* If pos is NULL, or is a bogus trailing delimiter then no prepath */
1135 if (!*pos++ || !*pos)
1136 return 0;
1137
1138 vol->prepath = kstrdup(pos, GFP_KERNEL);
1139 if (!vol->prepath)
1140 return -ENOMEM;
1141
1142 return 0;
1143}
1144
1093static int 1145static int
1094cifs_parse_mount_options(const char *mountdata, const char *devname, 1146cifs_parse_mount_options(const char *mountdata, const char *devname,
1095 struct smb_vol *vol) 1147 struct smb_vol *vol)
@@ -1108,11 +1160,17 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1108 char *string = NULL; 1160 char *string = NULL;
1109 char *tmp_end, *value; 1161 char *tmp_end, *value;
1110 char delim; 1162 char delim;
1163 bool got_ip = false;
1164 unsigned short port = 0;
1165 struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
1111 1166
1112 separator[0] = ','; 1167 separator[0] = ',';
1113 separator[1] = 0; 1168 separator[1] = 0;
1114 delim = separator[0]; 1169 delim = separator[0];
1115 1170
1171 /* ensure we always start with zeroed-out smb_vol */
1172 memset(vol, 0, sizeof(*vol));
1173
1116 /* 1174 /*
1117 * does not have to be perfect mapping since field is 1175 * does not have to be perfect mapping since field is
1118 * informational, only used for servers that do not support 1176 * informational, only used for servers that do not support
@@ -1169,6 +1227,16 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1169 vol->backupuid_specified = false; /* no backup intent for a user */ 1227 vol->backupuid_specified = false; /* no backup intent for a user */
1170 vol->backupgid_specified = false; /* no backup intent for a group */ 1228 vol->backupgid_specified = false; /* no backup intent for a group */
1171 1229
1230 /*
1231 * For now, we ignore -EINVAL errors under the assumption that the
1232 * unc= and prefixpath= options will be usable.
1233 */
1234 if (cifs_parse_devname(devname, vol) == -ENOMEM) {
1235 printk(KERN_ERR "CIFS: Unable to allocate memory to parse "
1236 "device string.\n");
1237 goto out_nomem;
1238 }
1239
1172 while ((data = strsep(&options, separator)) != NULL) { 1240 while ((data = strsep(&options, separator)) != NULL) {
1173 substring_t args[MAX_OPT_ARGS]; 1241 substring_t args[MAX_OPT_ARGS];
1174 unsigned long option; 1242 unsigned long option;
@@ -1416,12 +1484,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1416 vol->dir_mode = option; 1484 vol->dir_mode = option;
1417 break; 1485 break;
1418 case Opt_port: 1486 case Opt_port:
1419 if (get_option_ul(args, &option)) { 1487 if (get_option_ul(args, &option) ||
1420 cERROR(1, "%s: Invalid port value", 1488 option > USHRT_MAX) {
1421 __func__); 1489 cERROR(1, "%s: Invalid port value", __func__);
1422 goto cifs_parse_mount_err; 1490 goto cifs_parse_mount_err;
1423 } 1491 }
1424 vol->port = option; 1492 port = (unsigned short)option;
1425 break; 1493 break;
1426 case Opt_rsize: 1494 case Opt_rsize:
1427 if (get_option_ul(args, &option)) { 1495 if (get_option_ul(args, &option)) {
@@ -1537,53 +1605,48 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1537 vol->password[j] = '\0'; 1605 vol->password[j] = '\0';
1538 break; 1606 break;
1539 case Opt_blank_ip: 1607 case Opt_blank_ip:
1540 vol->UNCip = NULL; 1608 /* FIXME: should this be an error instead? */
1609 got_ip = false;
1541 break; 1610 break;
1542 case Opt_ip: 1611 case Opt_ip:
1543 string = match_strdup(args); 1612 string = match_strdup(args);
1544 if (string == NULL) 1613 if (string == NULL)
1545 goto out_nomem; 1614 goto out_nomem;
1546 1615
1547 if (strnlen(string, INET6_ADDRSTRLEN) > 1616 if (!cifs_convert_address(dstaddr, string,
1548 INET6_ADDRSTRLEN) { 1617 strlen(string))) {
1549 printk(KERN_WARNING "CIFS: ip address " 1618 printk(KERN_ERR "CIFS: bad ip= option (%s).\n",
1550 "too long\n"); 1619 string);
1551 goto cifs_parse_mount_err;
1552 }
1553 vol->UNCip = kstrdup(string, GFP_KERNEL);
1554 if (!vol->UNCip) {
1555 printk(KERN_WARNING "CIFS: no memory "
1556 "for UNC IP\n");
1557 goto cifs_parse_mount_err; 1620 goto cifs_parse_mount_err;
1558 } 1621 }
1622 got_ip = true;
1559 break; 1623 break;
1560 case Opt_unc: 1624 case Opt_unc:
1561 string = match_strdup(args); 1625 string = vol->UNC;
1562 if (string == NULL) 1626 vol->UNC = match_strdup(args);
1627 if (vol->UNC == NULL) {
1628 kfree(string);
1563 goto out_nomem; 1629 goto out_nomem;
1564
1565 temp_len = strnlen(string, 300);
1566 if (temp_len == 300) {
1567 printk(KERN_WARNING "CIFS: UNC name too long\n");
1568 goto cifs_parse_mount_err;
1569 } 1630 }
1570 1631
1571 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); 1632 convert_delimiter(vol->UNC, '\\');
1572 if (vol->UNC == NULL) { 1633 if (vol->UNC[0] != '\\' || vol->UNC[1] != '\\') {
1573 printk(KERN_WARNING "CIFS: no memory for UNC\n"); 1634 kfree(string);
1574 goto cifs_parse_mount_err; 1635 printk(KERN_ERR "CIFS: UNC Path does not "
1575 } 1636 "begin with // or \\\\\n");
1576 strcpy(vol->UNC, string);
1577
1578 if (strncmp(string, "//", 2) == 0) {
1579 vol->UNC[0] = '\\';
1580 vol->UNC[1] = '\\';
1581 } else if (strncmp(string, "\\\\", 2) != 0) {
1582 printk(KERN_WARNING "CIFS: UNC Path does not "
1583 "begin with // or \\\\\n");
1584 goto cifs_parse_mount_err; 1637 goto cifs_parse_mount_err;
1585 } 1638 }
1586 1639
1640 /* Compare old unc= option to new one */
1641 if (!string || strcmp(string, vol->UNC))
1642 printk(KERN_WARNING "CIFS: the value of the "
1643 "unc= mount option does not match the "
1644 "device string. Using the unc= option "
1645 "for now. In 3.10, that option will "
1646 "be ignored and the contents of the "
1647 "device string will be used "
1648 "instead. (%s != %s)\n", string,
1649 vol->UNC);
1587 break; 1650 break;
1588 case Opt_domain: 1651 case Opt_domain:
1589 string = match_strdup(args); 1652 string = match_strdup(args);
@@ -1618,31 +1681,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1618 } 1681 }
1619 break; 1682 break;
1620 case Opt_prefixpath: 1683 case Opt_prefixpath:
1621 string = match_strdup(args); 1684 /* skip over any leading delimiter */
1622 if (string == NULL) 1685 if (*args[0].from == '/' || *args[0].from == '\\')
1623 goto out_nomem; 1686 args[0].from++;
1624
1625 temp_len = strnlen(string, 1024);
1626 if (string[0] != '/')
1627 temp_len++; /* missing leading slash */
1628 if (temp_len > 1024) {
1629 printk(KERN_WARNING "CIFS: prefix too long\n");
1630 goto cifs_parse_mount_err;
1631 }
1632 1687
1633 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL); 1688 string = vol->prepath;
1689 vol->prepath = match_strdup(args);
1634 if (vol->prepath == NULL) { 1690 if (vol->prepath == NULL) {
1635 printk(KERN_WARNING "CIFS: no memory " 1691 kfree(string);
1636 "for path prefix\n"); 1692 goto out_nomem;
1637 goto cifs_parse_mount_err;
1638 } 1693 }
1639 1694 /* Compare old prefixpath= option to new one */
1640 if (string[0] != '/') { 1695 if (!string || strcmp(string, vol->prepath))
1641 vol->prepath[0] = '/'; 1696 printk(KERN_WARNING "CIFS: the value of the "
1642 strcpy(vol->prepath+1, string); 1697 "prefixpath= mount option does not "
1643 } else 1698 "match the device string. Using the "
1644 strcpy(vol->prepath, string); 1699 "prefixpath= option for now. In 3.10, "
1645 1700 "that option will be ignored and the "
1701 "contents of the device string will be "
1702 "used instead.(%s != %s)\n", string,
1703 vol->prepath);
1646 break; 1704 break;
1647 case Opt_iocharset: 1705 case Opt_iocharset:
1648 string = match_strdup(args); 1706 string = match_strdup(args);
@@ -1799,9 +1857,30 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1799 goto cifs_parse_mount_err; 1857 goto cifs_parse_mount_err;
1800 } 1858 }
1801#endif 1859#endif
1860 if (!vol->UNC) {
1861 cERROR(1, "CIFS mount error: No usable UNC path provided in "
1862 "device string or in unc= option!");
1863 goto cifs_parse_mount_err;
1864 }
1802 1865
1803 if (vol->UNCip == NULL) 1866 /* make sure UNC has a share name */
1804 vol->UNCip = &vol->UNC[2]; 1867 if (!strchr(vol->UNC + 3, '\\')) {
1868 cERROR(1, "Malformed UNC. Unable to find share name.");
1869 goto cifs_parse_mount_err;
1870 }
1871
1872 if (!got_ip) {
1873 /* No ip= option specified? Try to get it from UNC */
1874 if (!cifs_convert_address(dstaddr, &vol->UNC[2],
1875 strlen(&vol->UNC[2]))) {
1876 printk(KERN_ERR "Unable to determine destination "
1877 "address.\n");
1878 goto cifs_parse_mount_err;
1879 }
1880 }
1881
1882 /* set the port that we got earlier */
1883 cifs_set_port(dstaddr, port);
1805 1884
1806 if (uid_specified) 1885 if (uid_specified)
1807 vol->override_uid = override_uid; 1886 vol->override_uid = override_uid;
@@ -1972,9 +2051,10 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1972 return true; 2051 return true;
1973} 2052}
1974 2053
1975static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr, 2054static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
1976 struct smb_vol *vol)
1977{ 2055{
2056 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr;
2057
1978 if ((server->vals != vol->vals) || (server->ops != vol->ops)) 2058 if ((server->vals != vol->vals) || (server->ops != vol->ops))
1979 return 0; 2059 return 0;
1980 2060
@@ -1995,13 +2075,13 @@ static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
1995} 2075}
1996 2076
1997static struct TCP_Server_Info * 2077static struct TCP_Server_Info *
1998cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) 2078cifs_find_tcp_session(struct smb_vol *vol)
1999{ 2079{
2000 struct TCP_Server_Info *server; 2080 struct TCP_Server_Info *server;
2001 2081
2002 spin_lock(&cifs_tcp_ses_lock); 2082 spin_lock(&cifs_tcp_ses_lock);
2003 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 2083 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
2004 if (!match_server(server, addr, vol)) 2084 if (!match_server(server, vol))
2005 continue; 2085 continue;
2006 2086
2007 ++server->srv_count; 2087 ++server->srv_count;
@@ -2051,40 +2131,12 @@ static struct TCP_Server_Info *
2051cifs_get_tcp_session(struct smb_vol *volume_info) 2131cifs_get_tcp_session(struct smb_vol *volume_info)
2052{ 2132{
2053 struct TCP_Server_Info *tcp_ses = NULL; 2133 struct TCP_Server_Info *tcp_ses = NULL;
2054 struct sockaddr_storage addr;
2055 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
2056 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
2057 int rc; 2134 int rc;
2058 2135
2059 memset(&addr, 0, sizeof(struct sockaddr_storage)); 2136 cFYI(1, "UNC: %s", volume_info->UNC);
2060
2061 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
2062
2063 if (volume_info->UNCip && volume_info->UNC) {
2064 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
2065 volume_info->UNCip,
2066 strlen(volume_info->UNCip),
2067 volume_info->port);
2068 if (!rc) {
2069 /* we failed translating address */
2070 rc = -EINVAL;
2071 goto out_err;
2072 }
2073 } else if (volume_info->UNCip) {
2074 /* BB using ip addr as tcp_ses name to connect to the
2075 DFS root below */
2076 cERROR(1, "Connecting to DFS root not implemented yet");
2077 rc = -EINVAL;
2078 goto out_err;
2079 } else /* which tcp_sess DFS root would we conect to */ {
2080 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
2081 "unc=//192.168.1.100/public) specified");
2082 rc = -EINVAL;
2083 goto out_err;
2084 }
2085 2137
2086 /* see if we already have a matching tcp_ses */ 2138 /* see if we already have a matching tcp_ses */
2087 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info); 2139 tcp_ses = cifs_find_tcp_session(volume_info);
2088 if (tcp_ses) 2140 if (tcp_ses)
2089 return tcp_ses; 2141 return tcp_ses;
2090 2142
@@ -2129,27 +2181,18 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2129 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 2181 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
2130 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 2182 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
2131 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); 2183 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
2132 2184 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
2185 sizeof(tcp_ses->srcaddr));
2186 memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
2187 sizeof(tcp_ses->dstaddr));
2133 /* 2188 /*
2134 * at this point we are the only ones with the pointer 2189 * at this point we are the only ones with the pointer
2135 * to the struct since the kernel thread not created yet 2190 * to the struct since the kernel thread not created yet
2136 * no need to spinlock this init of tcpStatus or srv_count 2191 * no need to spinlock this init of tcpStatus or srv_count
2137 */ 2192 */
2138 tcp_ses->tcpStatus = CifsNew; 2193 tcp_ses->tcpStatus = CifsNew;
2139 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
2140 sizeof(tcp_ses->srcaddr));
2141 ++tcp_ses->srv_count; 2194 ++tcp_ses->srv_count;
2142 2195
2143 if (addr.ss_family == AF_INET6) {
2144 cFYI(1, "attempting ipv6 connect");
2145 /* BB should we allow ipv6 on port 139? */
2146 /* other OS never observed in Wild doing 139 with v6 */
2147 memcpy(&tcp_ses->dstaddr, sin_server6,
2148 sizeof(struct sockaddr_in6));
2149 } else
2150 memcpy(&tcp_ses->dstaddr, sin_server,
2151 sizeof(struct sockaddr_in));
2152
2153 rc = ip_connect(tcp_ses); 2196 rc = ip_connect(tcp_ses);
2154 if (rc < 0) { 2197 if (rc < 0) {
2155 cERROR(1, "Error connecting to socket. Aborting operation"); 2198 cERROR(1, "Error connecting to socket. Aborting operation");
@@ -2397,8 +2440,6 @@ cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
2397} 2440}
2398#endif /* CONFIG_KEYS */ 2441#endif /* CONFIG_KEYS */
2399 2442
2400static bool warned_on_ntlm; /* globals init to false automatically */
2401
2402static struct cifs_ses * 2443static struct cifs_ses *
2403cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) 2444cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2404{ 2445{
@@ -2475,14 +2516,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2475 ses->cred_uid = volume_info->cred_uid; 2516 ses->cred_uid = volume_info->cred_uid;
2476 ses->linux_uid = volume_info->linux_uid; 2517 ses->linux_uid = volume_info->linux_uid;
2477 2518
2478 /* ntlmv2 is much stronger than ntlm security, and has been broadly
2479 supported for many years, time to update default security mechanism */
2480 if ((volume_info->secFlg == 0) && warned_on_ntlm == false) {
2481 warned_on_ntlm = true;
2482 cERROR(1, "default security mechanism requested. The default "
2483 "security mechanism will be upgraded from ntlm to "
2484 "ntlmv2 in kernel release 3.3");
2485 }
2486 ses->overrideSecFlg = volume_info->secFlg; 2519 ses->overrideSecFlg = volume_info->secFlg;
2487 2520
2488 mutex_lock(&ses->session_mutex); 2521 mutex_lock(&ses->session_mutex);
@@ -2598,13 +2631,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2598 } 2631 }
2599 } 2632 }
2600 2633
2601 if (strchr(volume_info->UNC + 3, '\\') == NULL
2602 && strchr(volume_info->UNC + 3, '/') == NULL) {
2603 cERROR(1, "Missing share name");
2604 rc = -ENODEV;
2605 goto out_fail;
2606 }
2607
2608 /* 2634 /*
2609 * BB Do we need to wrap session_mutex around this TCon call and Unix 2635 * BB Do we need to wrap session_mutex around this TCon call and Unix
2610 * SetFS as we do on SessSetup and reconnect? 2636 * SetFS as we do on SessSetup and reconnect?
@@ -2718,11 +2744,8 @@ cifs_match_super(struct super_block *sb, void *data)
2718 struct cifs_ses *ses; 2744 struct cifs_ses *ses;
2719 struct cifs_tcon *tcon; 2745 struct cifs_tcon *tcon;
2720 struct tcon_link *tlink; 2746 struct tcon_link *tlink;
2721 struct sockaddr_storage addr;
2722 int rc = 0; 2747 int rc = 0;
2723 2748
2724 memset(&addr, 0, sizeof(struct sockaddr_storage));
2725
2726 spin_lock(&cifs_tcp_ses_lock); 2749 spin_lock(&cifs_tcp_ses_lock);
2727 cifs_sb = CIFS_SB(sb); 2750 cifs_sb = CIFS_SB(sb);
2728 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); 2751 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
@@ -2736,17 +2759,7 @@ cifs_match_super(struct super_block *sb, void *data)
2736 2759
2737 volume_info = mnt_data->vol; 2760 volume_info = mnt_data->vol;
2738 2761
2739 if (!volume_info->UNCip || !volume_info->UNC) 2762 if (!match_server(tcp_srv, volume_info) ||
2740 goto out;
2741
2742 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
2743 volume_info->UNCip,
2744 strlen(volume_info->UNCip),
2745 volume_info->port);
2746 if (!rc)
2747 goto out;
2748
2749 if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
2750 !match_session(ses, volume_info) || 2763 !match_session(ses, volume_info) ||
2751 !match_tcon(tcon, volume_info->UNC)) { 2764 !match_tcon(tcon, volume_info->UNC)) {
2752 rc = 0; 2765 rc = 0;
@@ -3261,8 +3274,6 @@ cleanup_volume_info_contents(struct smb_vol *volume_info)
3261{ 3274{
3262 kfree(volume_info->username); 3275 kfree(volume_info->username);
3263 kzfree(volume_info->password); 3276 kzfree(volume_info->password);
3264 if (volume_info->UNCip != volume_info->UNC + 2)
3265 kfree(volume_info->UNCip);
3266 kfree(volume_info->UNC); 3277 kfree(volume_info->UNC);
3267 kfree(volume_info->domainname); 3278 kfree(volume_info->domainname);
3268 kfree(volume_info->iocharset); 3279 kfree(volume_info->iocharset);
@@ -3280,14 +3291,16 @@ cifs_cleanup_volume_info(struct smb_vol *volume_info)
3280 3291
3281 3292
3282#ifdef CONFIG_CIFS_DFS_UPCALL 3293#ifdef CONFIG_CIFS_DFS_UPCALL
3283/* build_path_to_root returns full path to root when 3294/*
3284 * we do not have an exiting connection (tcon) */ 3295 * cifs_build_path_to_root returns full path to root when we do not have an
3296 * exiting connection (tcon)
3297 */
3285static char * 3298static char *
3286build_unc_path_to_root(const struct smb_vol *vol, 3299build_unc_path_to_root(const struct smb_vol *vol,
3287 const struct cifs_sb_info *cifs_sb) 3300 const struct cifs_sb_info *cifs_sb)
3288{ 3301{
3289 char *full_path, *pos; 3302 char *full_path, *pos;
3290 unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0; 3303 unsigned int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
3291 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); 3304 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
3292 3305
3293 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); 3306 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
@@ -3298,6 +3311,7 @@ build_unc_path_to_root(const struct smb_vol *vol,
3298 pos = full_path + unc_len; 3311 pos = full_path + unc_len;
3299 3312
3300 if (pplen) { 3313 if (pplen) {
3314 *pos++ = CIFS_DIR_SEP(cifs_sb);
3301 strncpy(pos, vol->prepath, pplen); 3315 strncpy(pos, vol->prepath, pplen);
3302 pos += pplen; 3316 pos += pplen;
3303 } 3317 }
@@ -3353,7 +3367,6 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
3353 mdata = NULL; 3367 mdata = NULL;
3354 } else { 3368 } else {
3355 cleanup_volume_info_contents(volume_info); 3369 cleanup_volume_info_contents(volume_info);
3356 memset(volume_info, '\0', sizeof(*volume_info));
3357 rc = cifs_setup_volume_info(volume_info, mdata, 3370 rc = cifs_setup_volume_info(volume_info, mdata,
3358 fake_devname); 3371 fake_devname);
3359 } 3372 }
@@ -3375,7 +3388,6 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
3375 if (cifs_parse_mount_options(mount_data, devname, volume_info)) 3388 if (cifs_parse_mount_options(mount_data, devname, volume_info))
3376 return -EINVAL; 3389 return -EINVAL;
3377 3390
3378
3379 if (volume_info->nullauth) { 3391 if (volume_info->nullauth) {
3380 cFYI(1, "Anonymous login"); 3392 cFYI(1, "Anonymous login");
3381 kfree(volume_info->username); 3393 kfree(volume_info->username);
@@ -3412,7 +3424,7 @@ cifs_get_volume_info(char *mount_data, const char *devname)
3412 int rc; 3424 int rc;
3413 struct smb_vol *volume_info; 3425 struct smb_vol *volume_info;
3414 3426
3415 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); 3427 volume_info = kmalloc(sizeof(struct smb_vol), GFP_KERNEL);
3416 if (!volume_info) 3428 if (!volume_info)
3417 return ERR_PTR(-ENOMEM); 3429 return ERR_PTR(-ENOMEM);
3418 3430
@@ -3537,8 +3549,10 @@ remote_path_check:
3537 rc = -ENOSYS; 3549 rc = -ENOSYS;
3538 goto mount_fail_check; 3550 goto mount_fail_check;
3539 } 3551 }
3540 /* build_path_to_root works only when we have a valid tcon */ 3552 /*
3541 full_path = build_path_to_root(volume_info, cifs_sb, tcon); 3553 * cifs_build_path_to_root works only when we have a valid tcon
3554 */
3555 full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
3542 if (full_path == NULL) { 3556 if (full_path == NULL) {
3543 rc = -ENOMEM; 3557 rc = -ENOMEM;
3544 goto mount_fail_check; 3558 goto mount_fail_check;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d3671f2acb29..8719bbe0dcc3 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -44,6 +44,38 @@ renew_parental_timestamps(struct dentry *direntry)
44 } while (!IS_ROOT(direntry)); 44 } while (!IS_ROOT(direntry));
45} 45}
46 46
47char *
48cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
49 struct cifs_tcon *tcon)
50{
51 int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
52 int dfsplen;
53 char *full_path = NULL;
54
55 /* if no prefix path, simply set path to the root of share to "" */
56 if (pplen == 0) {
57 full_path = kzalloc(1, GFP_KERNEL);
58 return full_path;
59 }
60
61 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
62 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
63 else
64 dfsplen = 0;
65
66 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
67 if (full_path == NULL)
68 return full_path;
69
70 if (dfsplen)
71 strncpy(full_path, tcon->treeName, dfsplen);
72 full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
73 strncpy(full_path + dfsplen + 1, vol->prepath, pplen);
74 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
75 full_path[dfsplen + pplen] = 0; /* add trailing null */
76 return full_path;
77}
78
47/* Note: caller must free return buffer */ 79/* Note: caller must free return buffer */
48char * 80char *
49build_path_from_dentry(struct dentry *direntry) 81build_path_from_dentry(struct dentry *direntry)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 70b6f4c3a0c1..0a6677ba212b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -505,16 +505,36 @@ out:
505 return rc; 505 return rc;
506} 506}
507 507
508static int cifs_push_posix_locks(struct cifsFileInfo *cfile);
509
508/* 510/*
509 * Try to reacquire byte range locks that were released when session 511 * Try to reacquire byte range locks that were released when session
510 * to server was lost 512 * to server was lost.
511 */ 513 */
512static int cifs_relock_file(struct cifsFileInfo *cifsFile) 514static int
515cifs_relock_file(struct cifsFileInfo *cfile)
513{ 516{
517 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
518 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
519 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
514 int rc = 0; 520 int rc = 0;
515 521
516 /* BB list all locks open on this file and relock */ 522 /* we are going to update can_cache_brlcks here - need a write access */
523 down_write(&cinode->lock_sem);
524 if (cinode->can_cache_brlcks) {
525 /* can cache locks - no need to push them */
526 up_write(&cinode->lock_sem);
527 return rc;
528 }
517 529
530 if (cap_unix(tcon->ses) &&
531 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
532 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
533 rc = cifs_push_posix_locks(cfile);
534 else
535 rc = tcon->ses->server->ops->push_mand_locks(cfile);
536
537 up_write(&cinode->lock_sem);
518 return rc; 538 return rc;
519} 539}
520 540
@@ -739,10 +759,15 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock)
739 } 759 }
740} 760}
741 761
762#define CIFS_LOCK_OP 0
763#define CIFS_READ_OP 1
764#define CIFS_WRITE_OP 2
765
766/* @rw_check : 0 - no op, 1 - read, 2 - write */
742static bool 767static bool
743cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, 768cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
744 __u64 length, __u8 type, struct cifsFileInfo *cfile, 769 __u64 length, __u8 type, struct cifsFileInfo *cfile,
745 struct cifsLockInfo **conf_lock, bool rw_check) 770 struct cifsLockInfo **conf_lock, int rw_check)
746{ 771{
747 struct cifsLockInfo *li; 772 struct cifsLockInfo *li;
748 struct cifsFileInfo *cur_cfile = fdlocks->cfile; 773 struct cifsFileInfo *cur_cfile = fdlocks->cfile;
@@ -752,9 +777,13 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
752 if (offset + length <= li->offset || 777 if (offset + length <= li->offset ||
753 offset >= li->offset + li->length) 778 offset >= li->offset + li->length)
754 continue; 779 continue;
755 if (rw_check && server->ops->compare_fids(cfile, cur_cfile) && 780 if (rw_check != CIFS_LOCK_OP && current->tgid == li->pid &&
756 current->tgid == li->pid) 781 server->ops->compare_fids(cfile, cur_cfile)) {
757 continue; 782 /* shared lock prevents write op through the same fid */
783 if (!(li->type & server->vals->shared_lock_type) ||
784 rw_check != CIFS_WRITE_OP)
785 continue;
786 }
758 if ((type & server->vals->shared_lock_type) && 787 if ((type & server->vals->shared_lock_type) &&
759 ((server->ops->compare_fids(cfile, cur_cfile) && 788 ((server->ops->compare_fids(cfile, cur_cfile) &&
760 current->tgid == li->pid) || type == li->type)) 789 current->tgid == li->pid) || type == li->type))
@@ -769,7 +798,7 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
769bool 798bool
770cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length, 799cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
771 __u8 type, struct cifsLockInfo **conf_lock, 800 __u8 type, struct cifsLockInfo **conf_lock,
772 bool rw_check) 801 int rw_check)
773{ 802{
774 bool rc = false; 803 bool rc = false;
775 struct cifs_fid_locks *cur; 804 struct cifs_fid_locks *cur;
@@ -805,7 +834,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
805 down_read(&cinode->lock_sem); 834 down_read(&cinode->lock_sem);
806 835
807 exist = cifs_find_lock_conflict(cfile, offset, length, type, 836 exist = cifs_find_lock_conflict(cfile, offset, length, type,
808 &conf_lock, false); 837 &conf_lock, CIFS_LOCK_OP);
809 if (exist) { 838 if (exist) {
810 flock->fl_start = conf_lock->offset; 839 flock->fl_start = conf_lock->offset;
811 flock->fl_end = conf_lock->offset + conf_lock->length - 1; 840 flock->fl_end = conf_lock->offset + conf_lock->length - 1;
@@ -852,7 +881,7 @@ try_again:
852 down_write(&cinode->lock_sem); 881 down_write(&cinode->lock_sem);
853 882
854 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, 883 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length,
855 lock->type, &conf_lock, false); 884 lock->type, &conf_lock, CIFS_LOCK_OP);
856 if (!exist && cinode->can_cache_brlcks) { 885 if (!exist && cinode->can_cache_brlcks) {
857 list_add_tail(&lock->llist, &cfile->llist->locks); 886 list_add_tail(&lock->llist, &cfile->llist->locks);
858 up_write(&cinode->lock_sem); 887 up_write(&cinode->lock_sem);
@@ -948,7 +977,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
948 int rc = 0, stored_rc; 977 int rc = 0, stored_rc;
949 struct cifsLockInfo *li, *tmp; 978 struct cifsLockInfo *li, *tmp;
950 struct cifs_tcon *tcon; 979 struct cifs_tcon *tcon;
951 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
952 unsigned int num, max_num, max_buf; 980 unsigned int num, max_num, max_buf;
953 LOCKING_ANDX_RANGE *buf, *cur; 981 LOCKING_ANDX_RANGE *buf, *cur;
954 int types[] = {LOCKING_ANDX_LARGE_FILES, 982 int types[] = {LOCKING_ANDX_LARGE_FILES,
@@ -958,21 +986,12 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
958 xid = get_xid(); 986 xid = get_xid();
959 tcon = tlink_tcon(cfile->tlink); 987 tcon = tlink_tcon(cfile->tlink);
960 988
961 /* we are going to update can_cache_brlcks here - need a write access */
962 down_write(&cinode->lock_sem);
963 if (!cinode->can_cache_brlcks) {
964 up_write(&cinode->lock_sem);
965 free_xid(xid);
966 return rc;
967 }
968
969 /* 989 /*
970 * Accessing maxBuf is racy with cifs_reconnect - need to store value 990 * Accessing maxBuf is racy with cifs_reconnect - need to store value
971 * and check it for zero before using. 991 * and check it for zero before using.
972 */ 992 */
973 max_buf = tcon->ses->server->maxBuf; 993 max_buf = tcon->ses->server->maxBuf;
974 if (!max_buf) { 994 if (!max_buf) {
975 up_write(&cinode->lock_sem);
976 free_xid(xid); 995 free_xid(xid);
977 return -EINVAL; 996 return -EINVAL;
978 } 997 }
@@ -981,7 +1000,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
981 sizeof(LOCKING_ANDX_RANGE); 1000 sizeof(LOCKING_ANDX_RANGE);
982 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 1001 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
983 if (!buf) { 1002 if (!buf) {
984 up_write(&cinode->lock_sem);
985 free_xid(xid); 1003 free_xid(xid);
986 return -ENOMEM; 1004 return -ENOMEM;
987 } 1005 }
@@ -1018,9 +1036,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
1018 } 1036 }
1019 } 1037 }
1020 1038
1021 cinode->can_cache_brlcks = false;
1022 up_write(&cinode->lock_sem);
1023
1024 kfree(buf); 1039 kfree(buf);
1025 free_xid(xid); 1040 free_xid(xid);
1026 return rc; 1041 return rc;
@@ -1043,7 +1058,6 @@ struct lock_to_push {
1043static int 1058static int
1044cifs_push_posix_locks(struct cifsFileInfo *cfile) 1059cifs_push_posix_locks(struct cifsFileInfo *cfile)
1045{ 1060{
1046 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
1047 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1061 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1048 struct file_lock *flock, **before; 1062 struct file_lock *flock, **before;
1049 unsigned int count = 0, i = 0; 1063 unsigned int count = 0, i = 0;
@@ -1054,14 +1068,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1054 1068
1055 xid = get_xid(); 1069 xid = get_xid();
1056 1070
1057 /* we are going to update can_cache_brlcks here - need a write access */
1058 down_write(&cinode->lock_sem);
1059 if (!cinode->can_cache_brlcks) {
1060 up_write(&cinode->lock_sem);
1061 free_xid(xid);
1062 return rc;
1063 }
1064
1065 lock_flocks(); 1071 lock_flocks();
1066 cifs_for_each_lock(cfile->dentry->d_inode, before) { 1072 cifs_for_each_lock(cfile->dentry->d_inode, before) {
1067 if ((*before)->fl_flags & FL_POSIX) 1073 if ((*before)->fl_flags & FL_POSIX)
@@ -1127,9 +1133,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1127 } 1133 }
1128 1134
1129out: 1135out:
1130 cinode->can_cache_brlcks = false;
1131 up_write(&cinode->lock_sem);
1132
1133 free_xid(xid); 1136 free_xid(xid);
1134 return rc; 1137 return rc;
1135err_out: 1138err_out:
@@ -1144,14 +1147,27 @@ static int
1144cifs_push_locks(struct cifsFileInfo *cfile) 1147cifs_push_locks(struct cifsFileInfo *cfile)
1145{ 1148{
1146 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); 1149 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
1150 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
1147 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1151 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1152 int rc = 0;
1153
1154 /* we are going to update can_cache_brlcks here - need a write access */
1155 down_write(&cinode->lock_sem);
1156 if (!cinode->can_cache_brlcks) {
1157 up_write(&cinode->lock_sem);
1158 return rc;
1159 }
1148 1160
1149 if (cap_unix(tcon->ses) && 1161 if (cap_unix(tcon->ses) &&
1150 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && 1162 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
1151 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) 1163 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
1152 return cifs_push_posix_locks(cfile); 1164 rc = cifs_push_posix_locks(cfile);
1165 else
1166 rc = tcon->ses->server->ops->push_mand_locks(cfile);
1153 1167
1154 return tcon->ses->server->ops->push_mand_locks(cfile); 1168 cinode->can_cache_brlcks = false;
1169 up_write(&cinode->lock_sem);
1170 return rc;
1155} 1171}
1156 1172
1157static void 1173static void
@@ -1436,16 +1452,18 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1436 return -ENOMEM; 1452 return -ENOMEM;
1437 1453
1438 rc = cifs_lock_add_if(cfile, lock, wait_flag); 1454 rc = cifs_lock_add_if(cfile, lock, wait_flag);
1439 if (rc < 0) 1455 if (rc < 0) {
1440 kfree(lock); 1456 kfree(lock);
1441 if (rc <= 0) 1457 return rc;
1458 }
1459 if (!rc)
1442 goto out; 1460 goto out;
1443 1461
1444 rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, 1462 rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length,
1445 type, 1, 0, wait_flag); 1463 type, 1, 0, wait_flag);
1446 if (rc) { 1464 if (rc) {
1447 kfree(lock); 1465 kfree(lock);
1448 goto out; 1466 return rc;
1449 } 1467 }
1450 1468
1451 cifs_lock_add(cfile, lock); 1469 cifs_lock_add(cfile, lock);
@@ -2085,7 +2103,15 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
2085 } else { 2103 } else {
2086 rc = copied; 2104 rc = copied;
2087 pos += copied; 2105 pos += copied;
2088 set_page_dirty(page); 2106 /*
2107 * When we use strict cache mode and cifs_strict_writev was run
2108 * with level II oplock (indicated by leave_pages_clean field of
2109 * CIFS_I(inode)), we can leave pages clean - cifs_strict_writev
2110 * sent the data to the server itself.
2111 */
2112 if (!CIFS_I(inode)->leave_pages_clean ||
2113 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO))
2114 set_page_dirty(page);
2089 } 2115 }
2090 2116
2091 if (rc > 0) { 2117 if (rc > 0) {
@@ -2436,8 +2462,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
2436} 2462}
2437 2463
2438static ssize_t 2464static ssize_t
2439cifs_writev(struct kiocb *iocb, const struct iovec *iov, 2465cifs_pagecache_writev(struct kiocb *iocb, const struct iovec *iov,
2440 unsigned long nr_segs, loff_t pos) 2466 unsigned long nr_segs, loff_t pos, bool cache_ex)
2441{ 2467{
2442 struct file *file = iocb->ki_filp; 2468 struct file *file = iocb->ki_filp;
2443 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 2469 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
@@ -2457,10 +2483,14 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
2457 down_read(&cinode->lock_sem); 2483 down_read(&cinode->lock_sem);
2458 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), 2484 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs),
2459 server->vals->exclusive_lock_type, NULL, 2485 server->vals->exclusive_lock_type, NULL,
2460 true)) { 2486 CIFS_WRITE_OP)) {
2461 mutex_lock(&inode->i_mutex); 2487 mutex_lock(&inode->i_mutex);
2488 if (!cache_ex)
2489 cinode->leave_pages_clean = true;
2462 rc = __generic_file_aio_write(iocb, iov, nr_segs, 2490 rc = __generic_file_aio_write(iocb, iov, nr_segs,
2463 &iocb->ki_pos); 2491 &iocb->ki_pos);
2492 if (!cache_ex)
2493 cinode->leave_pages_clean = false;
2464 mutex_unlock(&inode->i_mutex); 2494 mutex_unlock(&inode->i_mutex);
2465 } 2495 }
2466 2496
@@ -2487,42 +2517,62 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
2487 struct cifsFileInfo *cfile = (struct cifsFileInfo *) 2517 struct cifsFileInfo *cfile = (struct cifsFileInfo *)
2488 iocb->ki_filp->private_data; 2518 iocb->ki_filp->private_data;
2489 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 2519 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
2490 2520 ssize_t written, written2;
2491#ifdef CONFIG_CIFS_SMB2
2492 /* 2521 /*
2493 * If we have an oplock for read and want to write a data to the file 2522 * We need to store clientCanCacheAll here to prevent race
2494 * we need to store it in the page cache and then push it to the server 2523 * conditions - this value can be changed during an execution
2495 * to be sure the next read will get a valid data. 2524 * of generic_file_aio_write. For CIFS it can be changed from
2525 * true to false only, but for SMB2 it can be changed both from
2526 * true to false and vice versa. So, we can end up with a data
2527 * stored in the cache, not marked dirty and not sent to the
2528 * server if this value changes its state from false to true
2529 * after cifs_write_end.
2496 */ 2530 */
2497 if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead) { 2531 bool cache_ex = cinode->clientCanCacheAll;
2498 ssize_t written; 2532 bool cache_read = cinode->clientCanCacheRead;
2499 int rc; 2533 int rc;
2500 2534 loff_t saved_pos;
2501 written = generic_file_aio_write(iocb, iov, nr_segs, pos);
2502 rc = filemap_fdatawrite(inode->i_mapping);
2503 if (rc)
2504 return (ssize_t)rc;
2505 2535
2506 return written; 2536 if (cache_ex) {
2537 if (cap_unix(tcon->ses) &&
2538 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) &&
2539 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(
2540 tcon->fsUnixInfo.Capability)))
2541 return generic_file_aio_write(iocb, iov, nr_segs, pos);
2542 return cifs_pagecache_writev(iocb, iov, nr_segs, pos, cache_ex);
2507 } 2543 }
2508#endif
2509 2544
2510 /* 2545 /*
2511 * For non-oplocked files in strict cache mode we need to write the data 2546 * For files without exclusive oplock in strict cache mode we need to
2512 * to the server exactly from the pos to pos+len-1 rather than flush all 2547 * write the data to the server exactly from the pos to pos+len-1 rather
2513 * affected pages because it may cause a error with mandatory locks on 2548 * than flush all affected pages because it may cause a error with
2514 * these pages but not on the region from pos to ppos+len-1. 2549 * mandatory locks on these pages but not on the region from pos to
2550 * ppos+len-1.
2515 */ 2551 */
2552 written = cifs_user_writev(iocb, iov, nr_segs, pos);
2553 if (!cache_read || written <= 0)
2554 return written;
2516 2555
2517 if (!cinode->clientCanCacheAll) 2556 saved_pos = iocb->ki_pos;
2518 return cifs_user_writev(iocb, iov, nr_segs, pos); 2557 iocb->ki_pos = pos;
2519 2558 /* we have a read oplock - need to store a data in the page cache */
2520 if (cap_unix(tcon->ses) && 2559 if (cap_unix(tcon->ses) &&
2521 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && 2560 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) &&
2522 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) 2561 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(
2523 return generic_file_aio_write(iocb, iov, nr_segs, pos); 2562 tcon->fsUnixInfo.Capability)))
2524 2563 written2 = generic_file_aio_write(iocb, iov, nr_segs, pos);
2525 return cifs_writev(iocb, iov, nr_segs, pos); 2564 else
2565 written2 = cifs_pagecache_writev(iocb, iov, nr_segs, pos,
2566 cache_ex);
2567 /* errors occured during writing - invalidate the page cache */
2568 if (written2 < 0) {
2569 rc = cifs_invalidate_mapping(inode);
2570 if (rc)
2571 written = (ssize_t)rc;
2572 else
2573 iocb->ki_pos = saved_pos;
2574 }
2575 return written;
2526} 2576}
2527 2577
2528static struct cifs_readdata * 2578static struct cifs_readdata *
@@ -2892,7 +2942,7 @@ cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
2892 down_read(&cinode->lock_sem); 2942 down_read(&cinode->lock_sem);
2893 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), 2943 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs),
2894 tcon->ses->server->vals->shared_lock_type, 2944 tcon->ses->server->vals->shared_lock_type,
2895 NULL, true)) 2945 NULL, CIFS_READ_OP))
2896 rc = generic_file_aio_read(iocb, iov, nr_segs, pos); 2946 rc = generic_file_aio_read(iocb, iov, nr_segs, pos);
2897 up_read(&cinode->lock_sem); 2947 up_read(&cinode->lock_sem);
2898 return rc; 2948 return rc;
@@ -3536,7 +3586,7 @@ void cifs_oplock_break(struct work_struct *work)
3536 if (cinode->clientCanCacheRead == 0) { 3586 if (cinode->clientCanCacheRead == 0) {
3537 rc = filemap_fdatawait(inode->i_mapping); 3587 rc = filemap_fdatawait(inode->i_mapping);
3538 mapping_set_error(inode->i_mapping, rc); 3588 mapping_set_error(inode->i_mapping, rc);
3539 invalidate_remote_inode(inode); 3589 cifs_invalidate_mapping(inode);
3540 } 3590 }
3541 cFYI(1, "Oplock flush inode %p rc %d", inode, rc); 3591 cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
3542 } 3592 }
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index afdff79651f1..ed6208ff85a7 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1791,11 +1791,12 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1791 stat->ino = CIFS_I(inode)->uniqueid; 1791 stat->ino = CIFS_I(inode)->uniqueid;
1792 1792
1793 /* 1793 /*
1794 * If on a multiuser mount without unix extensions, and the admin hasn't 1794 * If on a multiuser mount without unix extensions or cifsacl being
1795 * overridden them, set the ownership to the fsuid/fsgid of the current 1795 * enabled, and the admin hasn't overridden them, set the ownership
1796 * process. 1796 * to the fsuid/fsgid of the current process.
1797 */ 1797 */
1798 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && 1798 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1799 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1799 !tcon->unix_ext) { 1800 !tcon->unix_ext) {
1800 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) 1801 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1801 stat->uid = current_fsuid(); 1802 stat->uid = current_fsuid();
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index d5ce9e26696c..a82bc51fdc82 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -204,7 +204,7 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len)
204 return rc; 204 return rc;
205} 205}
206 206
207int 207void
208cifs_set_port(struct sockaddr *addr, const unsigned short int port) 208cifs_set_port(struct sockaddr *addr, const unsigned short int port)
209{ 209{
210 switch (addr->sa_family) { 210 switch (addr->sa_family) {
@@ -214,19 +214,7 @@ cifs_set_port(struct sockaddr *addr, const unsigned short int port)
214 case AF_INET6: 214 case AF_INET6:
215 ((struct sockaddr_in6 *)addr)->sin6_port = htons(port); 215 ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
216 break; 216 break;
217 default:
218 return 0;
219 } 217 }
220 return 1;
221}
222
223int
224cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
225 const unsigned short int port)
226{
227 if (!cifs_convert_address(dst, src, len))
228 return 0;
229 return cifs_set_port(dst, port);
230} 218}
231 219
232/***************************************************************************** 220/*****************************************************************************
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 1c576e871366..6002fdc920ae 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -66,18 +66,20 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
66#endif /* DEBUG2 */ 66#endif /* DEBUG2 */
67 67
68/* 68/*
69 * Attempt to preload the dcache with the results from the FIND_FIRST/NEXT
70 *
69 * Find the dentry that matches "name". If there isn't one, create one. If it's 71 * Find the dentry that matches "name". If there isn't one, create one. If it's
70 * a negative dentry or the uniqueid changed, then drop it and recreate it. 72 * a negative dentry or the uniqueid changed, then drop it and recreate it.
71 */ 73 */
72static struct dentry * 74static void
73cifs_readdir_lookup(struct dentry *parent, struct qstr *name, 75cifs_prime_dcache(struct dentry *parent, struct qstr *name,
74 struct cifs_fattr *fattr) 76 struct cifs_fattr *fattr)
75{ 77{
76 struct dentry *dentry, *alias; 78 struct dentry *dentry, *alias;
77 struct inode *inode; 79 struct inode *inode;
78 struct super_block *sb = parent->d_inode->i_sb; 80 struct super_block *sb = parent->d_inode->i_sb;
79 81
80 cFYI(1, "For %s", name->name); 82 cFYI(1, "%s: for %s", __func__, name->name);
81 83
82 if (parent->d_op && parent->d_op->d_hash) 84 if (parent->d_op && parent->d_op->d_hash)
83 parent->d_op->d_hash(parent, parent->d_inode, name); 85 parent->d_op->d_hash(parent, parent->d_inode, name);
@@ -87,37 +89,32 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
87 dentry = d_lookup(parent, name); 89 dentry = d_lookup(parent, name);
88 if (dentry) { 90 if (dentry) {
89 int err; 91 int err;
92
90 inode = dentry->d_inode; 93 inode = dentry->d_inode;
91 /* update inode in place if i_ino didn't change */ 94 /* update inode in place if i_ino didn't change */
92 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { 95 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
93 cifs_fattr_to_inode(inode, fattr); 96 cifs_fattr_to_inode(inode, fattr);
94 return dentry; 97 goto out;
95 } 98 }
96 err = d_invalidate(dentry); 99 err = d_invalidate(dentry);
97 dput(dentry); 100 dput(dentry);
98 if (err) 101 if (err)
99 return NULL; 102 return;
100 } 103 }
101 104
102 dentry = d_alloc(parent, name); 105 dentry = d_alloc(parent, name);
103 if (dentry == NULL) 106 if (!dentry)
104 return NULL; 107 return;
105 108
106 inode = cifs_iget(sb, fattr); 109 inode = cifs_iget(sb, fattr);
107 if (!inode) { 110 if (!inode)
108 dput(dentry); 111 goto out;
109 return NULL;
110 }
111 112
112 alias = d_materialise_unique(dentry, inode); 113 alias = d_materialise_unique(dentry, inode);
113 if (alias != NULL) { 114 if (alias && !IS_ERR(alias))
114 dput(dentry); 115 dput(alias);
115 if (IS_ERR(alias)) 116out:
116 return NULL; 117 dput(dentry);
117 dentry = alias;
118 }
119
120 return dentry;
121} 118}
122 119
123static void 120static void
@@ -137,6 +134,16 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
137 if (fattr->cf_cifsattrs & ATTR_READONLY) 134 if (fattr->cf_cifsattrs & ATTR_READONLY)
138 fattr->cf_mode &= ~S_IWUGO; 135 fattr->cf_mode &= ~S_IWUGO;
139 136
137 /*
138 * We of course don't get ACL info in FIND_FIRST/NEXT results, so
139 * mark it for revalidation so that "ls -l" will look right. It might
140 * be super-slow, but if we don't do this then the ownership of files
141 * may look wrong since the inodes may not have timed out by the time
142 * "ls" does a stat() call on them.
143 */
144 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
145 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
146
140 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && 147 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
141 fattr->cf_cifsattrs & ATTR_SYSTEM) { 148 fattr->cf_cifsattrs & ATTR_SYSTEM) {
142 if (fattr->cf_eof == 0) { 149 if (fattr->cf_eof == 0) {
@@ -652,7 +659,6 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
652 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 659 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
653 struct cifs_dirent de = { NULL, }; 660 struct cifs_dirent de = { NULL, };
654 struct cifs_fattr fattr; 661 struct cifs_fattr fattr;
655 struct dentry *dentry;
656 struct qstr name; 662 struct qstr name;
657 int rc = 0; 663 int rc = 0;
658 ino_t ino; 664 ino_t ino;
@@ -723,13 +729,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
723 */ 729 */
724 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; 730 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
725 731
726 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 732 cifs_prime_dcache(file->f_dentry, &name, &fattr);
727 dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
728 733
734 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
729 rc = filldir(dirent, name.name, name.len, file->f_pos, ino, 735 rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
730 fattr.cf_dtype); 736 fattr.cf_dtype);
731
732 dput(dentry);
733 return rc; 737 return rc;
734} 738}
735 739
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 34cea2798333..a5d234c8d5d9 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -575,37 +575,6 @@ cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
575 return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data); 575 return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data);
576} 576}
577 577
578static char *
579cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
580 struct cifs_tcon *tcon)
581{
582 int pplen = vol->prepath ? strlen(vol->prepath) : 0;
583 int dfsplen;
584 char *full_path = NULL;
585
586 /* if no prefix path, simply set path to the root of share to "" */
587 if (pplen == 0) {
588 full_path = kzalloc(1, GFP_KERNEL);
589 return full_path;
590 }
591
592 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
593 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
594 else
595 dfsplen = 0;
596
597 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
598 if (full_path == NULL)
599 return full_path;
600
601 if (dfsplen)
602 strncpy(full_path, tcon->treeName, dfsplen);
603 strncpy(full_path + dfsplen, vol->prepath, pplen);
604 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
605 full_path[dfsplen + pplen] = 0; /* add trailing null */
606 return full_path;
607}
608
609static void 578static void
610cifs_clear_stats(struct cifs_tcon *tcon) 579cifs_clear_stats(struct cifs_tcon *tcon)
611{ 580{
@@ -943,7 +912,6 @@ struct smb_version_operations smb1_operations = {
943 .set_path_size = CIFSSMBSetEOF, 912 .set_path_size = CIFSSMBSetEOF,
944 .set_file_size = CIFSSMBSetFileSize, 913 .set_file_size = CIFSSMBSetFileSize,
945 .set_file_info = smb_set_file_info, 914 .set_file_info = smb_set_file_info,
946 .build_path_to_root = cifs_build_path_to_root,
947 .echo = CIFSSMBEcho, 915 .echo = CIFSSMBEcho,
948 .mkdir = CIFSSMBMkDir, 916 .mkdir = CIFSSMBMkDir,
949 .mkdir_setinfo = cifs_mkdir_setinfo, 917 .mkdir_setinfo = cifs_mkdir_setinfo,
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
index a93eec30a50d..71e6aed4b382 100644
--- a/fs/cifs/smb2file.c
+++ b/fs/cifs/smb2file.c
@@ -260,13 +260,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
260 struct cifs_fid_locks *fdlocks; 260 struct cifs_fid_locks *fdlocks;
261 261
262 xid = get_xid(); 262 xid = get_xid();
263 /* we are going to update can_cache_brlcks here - need a write access */
264 down_write(&cinode->lock_sem);
265 if (!cinode->can_cache_brlcks) {
266 up_write(&cinode->lock_sem);
267 free_xid(xid);
268 return rc;
269 }
270 263
271 /* 264 /*
272 * Accessing maxBuf is racy with cifs_reconnect - need to store value 265 * Accessing maxBuf is racy with cifs_reconnect - need to store value
@@ -274,7 +267,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
274 */ 267 */
275 max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; 268 max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
276 if (!max_buf) { 269 if (!max_buf) {
277 up_write(&cinode->lock_sem);
278 free_xid(xid); 270 free_xid(xid);
279 return -EINVAL; 271 return -EINVAL;
280 } 272 }
@@ -282,7 +274,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
282 max_num = max_buf / sizeof(struct smb2_lock_element); 274 max_num = max_buf / sizeof(struct smb2_lock_element);
283 buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL); 275 buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL);
284 if (!buf) { 276 if (!buf) {
285 up_write(&cinode->lock_sem);
286 free_xid(xid); 277 free_xid(xid);
287 return -ENOMEM; 278 return -ENOMEM;
288 } 279 }
@@ -293,10 +284,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
293 rc = stored_rc; 284 rc = stored_rc;
294 } 285 }
295 286
296 cinode->can_cache_brlcks = false;
297 kfree(buf); 287 kfree(buf);
298
299 up_write(&cinode->lock_sem);
300 free_xid(xid); 288 free_xid(xid);
301 return rc; 289 return rc;
302} 290}
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 4d9dbe0b7385..d79de7bc4435 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -262,23 +262,6 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
262 return rc; 262 return rc;
263} 263}
264 264
265static char *
266smb2_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
267 struct cifs_tcon *tcon)
268{
269 int pplen = vol->prepath ? strlen(vol->prepath) : 0;
270 char *full_path = NULL;
271
272 /* if no prefix path, simply set path to the root of share to "" */
273 if (pplen == 0) {
274 full_path = kzalloc(2, GFP_KERNEL);
275 return full_path;
276 }
277
278 cERROR(1, "prefixpath is not supported for SMB2 now");
279 return NULL;
280}
281
282static bool 265static bool
283smb2_can_echo(struct TCP_Server_Info *server) 266smb2_can_echo(struct TCP_Server_Info *server)
284{ 267{
@@ -613,7 +596,6 @@ struct smb_version_operations smb21_operations = {
613 .set_path_size = smb2_set_path_size, 596 .set_path_size = smb2_set_path_size,
614 .set_file_size = smb2_set_file_size, 597 .set_file_size = smb2_set_file_size,
615 .set_file_info = smb2_set_file_info, 598 .set_file_info = smb2_set_file_info,
616 .build_path_to_root = smb2_build_path_to_root,
617 .mkdir = smb2_mkdir, 599 .mkdir = smb2_mkdir,
618 .mkdir_setinfo = smb2_mkdir_setinfo, 600 .mkdir_setinfo = smb2_mkdir_setinfo,
619 .rmdir = smb2_rmdir, 601 .rmdir = smb2_rmdir,
@@ -641,6 +623,91 @@ struct smb_version_operations smb21_operations = {
641 .get_lease_key = smb2_get_lease_key, 623 .get_lease_key = smb2_get_lease_key,
642 .set_lease_key = smb2_set_lease_key, 624 .set_lease_key = smb2_set_lease_key,
643 .new_lease_key = smb2_new_lease_key, 625 .new_lease_key = smb2_new_lease_key,
626 .calc_signature = smb2_calc_signature,
627};
628
629
630struct smb_version_operations smb30_operations = {
631 .compare_fids = smb2_compare_fids,
632 .setup_request = smb2_setup_request,
633 .setup_async_request = smb2_setup_async_request,
634 .check_receive = smb2_check_receive,
635 .add_credits = smb2_add_credits,
636 .set_credits = smb2_set_credits,
637 .get_credits_field = smb2_get_credits_field,
638 .get_credits = smb2_get_credits,
639 .get_next_mid = smb2_get_next_mid,
640 .read_data_offset = smb2_read_data_offset,
641 .read_data_length = smb2_read_data_length,
642 .map_error = map_smb2_to_linux_error,
643 .find_mid = smb2_find_mid,
644 .check_message = smb2_check_message,
645 .dump_detail = smb2_dump_detail,
646 .clear_stats = smb2_clear_stats,
647 .print_stats = smb2_print_stats,
648 .is_oplock_break = smb2_is_valid_oplock_break,
649 .need_neg = smb2_need_neg,
650 .negotiate = smb2_negotiate,
651 .negotiate_wsize = smb2_negotiate_wsize,
652 .negotiate_rsize = smb2_negotiate_rsize,
653 .sess_setup = SMB2_sess_setup,
654 .logoff = SMB2_logoff,
655 .tree_connect = SMB2_tcon,
656 .tree_disconnect = SMB2_tdis,
657 .is_path_accessible = smb2_is_path_accessible,
658 .can_echo = smb2_can_echo,
659 .echo = SMB2_echo,
660 .query_path_info = smb2_query_path_info,
661 .get_srv_inum = smb2_get_srv_inum,
662 .query_file_info = smb2_query_file_info,
663 .set_path_size = smb2_set_path_size,
664 .set_file_size = smb2_set_file_size,
665 .set_file_info = smb2_set_file_info,
666 .mkdir = smb2_mkdir,
667 .mkdir_setinfo = smb2_mkdir_setinfo,
668 .rmdir = smb2_rmdir,
669 .unlink = smb2_unlink,
670 .rename = smb2_rename_path,
671 .create_hardlink = smb2_create_hardlink,
672 .open = smb2_open_file,
673 .set_fid = smb2_set_fid,
674 .close = smb2_close_file,
675 .flush = smb2_flush_file,
676 .async_readv = smb2_async_readv,
677 .async_writev = smb2_async_writev,
678 .sync_read = smb2_sync_read,
679 .sync_write = smb2_sync_write,
680 .query_dir_first = smb2_query_dir_first,
681 .query_dir_next = smb2_query_dir_next,
682 .close_dir = smb2_close_dir,
683 .calc_smb_size = smb2_calc_size,
684 .is_status_pending = smb2_is_status_pending,
685 .oplock_response = smb2_oplock_response,
686 .queryfs = smb2_queryfs,
687 .mand_lock = smb2_mand_lock,
688 .mand_unlock_range = smb2_unlock_range,
689 .push_mand_locks = smb2_push_mandatory_locks,
690 .get_lease_key = smb2_get_lease_key,
691 .set_lease_key = smb2_set_lease_key,
692 .new_lease_key = smb2_new_lease_key,
693 .calc_signature = smb3_calc_signature,
694};
695
696struct smb_version_values smb20_values = {
697 .version_string = SMB20_VERSION_STRING,
698 .protocol_id = SMB20_PROT_ID,
699 .req_capabilities = 0, /* MBZ */
700 .large_lock_type = 0,
701 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
702 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
703 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
704 .header_size = sizeof(struct smb2_hdr),
705 .max_header_size = MAX_SMB2_HDR_SIZE,
706 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
707 .lock_cmd = SMB2_LOCK,
708 .cap_unix = 0,
709 .cap_nt_find = SMB2_NT_FIND,
710 .cap_large_files = SMB2_LARGE_FILES,
644}; 711};
645 712
646struct smb_version_values smb21_values = { 713struct smb_version_values smb21_values = {
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index cf33622cdac8..41d9d0725f0f 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -425,7 +425,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
425 } 425 }
426 426
427 cFYI(1, "sec_flags 0x%x", sec_flags); 427 cFYI(1, "sec_flags 0x%x", sec_flags);
428 if (sec_flags & CIFSSEC_MUST_SIGN) { 428 if ((sec_flags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
429 cFYI(1, "Signing required"); 429 cFYI(1, "Signing required");
430 if (!(server->sec_mode & (SMB2_NEGOTIATE_SIGNING_REQUIRED | 430 if (!(server->sec_mode & (SMB2_NEGOTIATE_SIGNING_REQUIRED |
431 SMB2_NEGOTIATE_SIGNING_ENABLED))) { 431 SMB2_NEGOTIATE_SIGNING_ENABLED))) {
@@ -612,7 +612,8 @@ ssetup_ntlmssp_authenticate:
612 612
613 /* BB add code to build os and lm fields */ 613 /* BB add code to build os and lm fields */
614 614
615 rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, CIFS_LOG_ERROR); 615 rc = SendReceive2(xid, ses, iov, 2, &resp_buftype,
616 CIFS_LOG_ERROR | CIFS_NEG_OP);
616 617
617 kfree(security_blob); 618 kfree(security_blob);
618 rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base; 619 rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base;
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 7d25f8b14f93..2aa3535e38ce 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
47 struct smb_rqst *rqst); 47 struct smb_rqst *rqst);
48extern struct mid_q_entry *smb2_setup_async_request( 48extern struct mid_q_entry *smb2_setup_async_request(
49 struct TCP_Server_Info *server, struct smb_rqst *rqst); 49 struct TCP_Server_Info *server, struct smb_rqst *rqst);
50extern int smb2_calc_signature(struct smb_rqst *rqst,
51 struct TCP_Server_Info *server);
52extern int smb3_calc_signature(struct smb_rqst *rqst,
53 struct TCP_Server_Info *server);
50extern void smb2_echo_request(struct work_struct *work); 54extern void smb2_echo_request(struct work_struct *work);
51extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode); 55extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode);
52extern __u8 smb2_map_lease_to_oplock(__le32 lease_state); 56extern __u8 smb2_map_lease_to_oplock(__le32 lease_state);
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 2a5fdf26f79f..8dd73e61d762 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -39,7 +39,7 @@
39#include "smb2status.h" 39#include "smb2status.h"
40#include "smb2glob.h" 40#include "smb2glob.h"
41 41
42static int 42int
43smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) 43smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
44{ 44{
45 int i, rc; 45 int i, rc;
@@ -116,6 +116,13 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
116 return rc; 116 return rc;
117} 117}
118 118
119int
120smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
121{
122 cFYI(1, "smb3 signatures not supported yet");
123 return -EOPNOTSUPP;
124}
125
119/* must be called with server->srv_mutex held */ 126/* must be called with server->srv_mutex held */
120static int 127static int
121smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) 128smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
@@ -132,7 +139,7 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
132 return rc; 139 return rc;
133 } 140 }
134 141
135 rc = smb2_calc_signature(rqst, server); 142 rc = server->ops->calc_signature(rqst, server);
136 143
137 return rc; 144 return rc;
138} 145}
@@ -168,7 +175,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
168 memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE); 175 memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
169 176
170 mutex_lock(&server->srv_mutex); 177 mutex_lock(&server->srv_mutex);
171 rc = smb2_calc_signature(rqst, server); 178 rc = server->ops->calc_signature(rqst, server);
172 mutex_unlock(&server->srv_mutex); 179 mutex_unlock(&server->srv_mutex);
173 180
174 if (rc) 181 if (rc)