aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/Kconfig10
-rw-r--r--fs/cifs/cifs_debug.h72
-rw-r--r--fs/cifs/cifsacl.c765
-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.c43
-rw-r--r--fs/cifs/file.c206
-rw-r--r--fs/cifs/inode.c7
-rw-r--r--fs/cifs/netmisc.c14
-rw-r--r--fs/cifs/readdir.c55
-rw-r--r--fs/cifs/smb1ops.c35
-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, 809 insertions, 974 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 fc783e264420..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,214 +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 }
135
136 return sidstr;
225} 137}
226 138
227static void 139/*
228id_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
229 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)
230{ 145{
231 int rc; 146 int i;
232 char *strptr; 147 int num_subauth, num_sat, num_saw;
233 struct rb_node *node = root->rb_node;
234 struct rb_node *parent = NULL;
235 struct rb_node **linkto = &(root->rb_node);
236 struct cifs_sid_id *lsidid;
237
238 while (node) {
239 lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
240 parent = node;
241 rc = compare_sids(sidptr, &((lsidid)->sid));
242 if (rc > 0) {
243 linkto = &(node->rb_left);
244 node = node->rb_left;
245 } else if (rc < 0) {
246 linkto = &(node->rb_right);
247 node = node->rb_right;
248 }
249 }
250
251 memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
252 (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
253 (*psidid)->refcount = 0;
254 148
255 sprintf((*psidid)->sidstr, "%s", typestr); 149 if ((!ctsid) || (!cwsid))
256 strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr); 150 return 1;
257 sid_to_str(&(*psidid)->sid, strptr);
258 151
259 clear_bit(SID_ID_PENDING, &(*psidid)->state); 152 /* compare the revision */
260 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 }
261 159
262 rb_link_node(&(*psidid)->rbnode, parent, linkto); 160 /* compare all of the six auth values */
263 rb_insert_color(&(*psidid)->rbnode, root); 161 for (i = 0; i < NUM_AUTHS; ++i) {
264} 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 }
265 169
266static struct cifs_sid_id * 170 /* compare all of the subauth values if any */
267id_rb_search(struct rb_root *root, struct cifs_sid *sidptr) 171 num_sat = ctsid->num_subauth;
268{ 172 num_saw = cwsid->num_subauth;
269 int rc; 173 num_subauth = num_sat < num_saw ? num_sat : num_saw;
270 struct rb_node *node = root->rb_node; 174 if (num_subauth) {
271 struct cifs_sid_id *lsidid; 175 for (i = 0; i < num_subauth; ++i) {
272 176 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
273 while (node) { 177 if (le32_to_cpu(ctsid->sub_auth[i]) >
274 lsidid = rb_entry(node, struct cifs_sid_id, rbnode); 178 le32_to_cpu(cwsid->sub_auth[i]))
275 rc = compare_sids(sidptr, &((lsidid)->sid)); 179 return 1;
276 if (rc > 0) { 180 else
277 node = node->rb_left; 181 return -1;
278 } else if (rc < 0) { 182 }
279 node = node->rb_right; 183 }
280 } else /* node found */
281 return lsidid;
282 } 184 }
283 185
284 return NULL; 186 return 0; /* sids compare/match */
285} 187}
286 188
287static int 189static void
288sidid_pending_wait(void *unused) 190cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
289{ 191{
290 schedule(); 192 int i;
291 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];
292} 200}
293 201
294static int 202static int
295id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) 203id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
296{ 204{
297 int rc = 0; 205 int rc;
298 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 */
299 const struct cred *saved_cred; 210 const struct cred *saved_cred;
300 struct cifs_sid *lsid;
301 struct cifs_sid_id *psidid, *npsidid;
302 struct rb_root *cidtree;
303 spinlock_t *cidlock;
304
305 if (sidtype == SIDOWNER) {
306 cidlock = &siduidlock;
307 cidtree = &uidtree;
308 } else if (sidtype == SIDGROUP) {
309 cidlock = &sidgidlock;
310 cidtree = &gidtree;
311 } else
312 return -EINVAL;
313 211
314 spin_lock(cidlock); 212 rc = snprintf(desc, sizeof(desc), "%ci:%u",
315 psidid = sid_rb_search(cidtree, cid); 213 sidtype == SIDOWNER ? 'o' : 'g', cid);
316 214 if (rc >= sizeof(desc))
317 if (!psidid) { /* node does not exist, allocate one & attempt adding */ 215 return -EINVAL;
318 spin_unlock(cidlock);
319 npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
320 if (!npsidid)
321 return -ENOMEM;
322
323 npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
324 if (!npsidid->sidstr) {
325 kfree(npsidid);
326 return -ENOMEM;
327 }
328 216
329 spin_lock(cidlock); 217 rc = 0;
330 psidid = sid_rb_search(cidtree, cid); 218 saved_cred = override_creds(root_cred);
331 if (psidid) { /* node happened to get inserted meanwhile */ 219 sidkey = request_key(&cifs_idmap_key_type, desc, "");
332 ++psidid->refcount; 220 if (IS_ERR(sidkey)) {
333 spin_unlock(cidlock); 221 rc = -EINVAL;
334 kfree(npsidid->sidstr); 222 cFYI(1, "%s: Can't map %cid %u to a SID", __func__,
335 kfree(npsidid); 223 sidtype == SIDOWNER ? 'u' : 'g', cid);
336 } else { 224 goto out_revert_creds;
337 psidid = npsidid; 225 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
338 sid_rb_insert(cidtree, cid, &psidid, 226 rc = -EIO;
339 sidtype == SIDOWNER ? "oi:" : "gi:"); 227 cFYI(1, "%s: Downcall contained malformed key "
340 ++psidid->refcount; 228 "(datalen=%hu)", __func__, sidkey->datalen);
341 spin_unlock(cidlock); 229 goto invalidate_key;
342 }
343 } else {
344 ++psidid->refcount;
345 spin_unlock(cidlock);
346 } 230 }
347 231
348 /* 232 /*
349 * 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
350 * since a reference was taken earlier while holding the spinlock. 234 * there are no subauthorities and the host has 8-byte pointers, then
351 * A reference on the node is put without holding the spinlock 235 * it could be.
352 * and it is OK to do so in this case, shrinker will not erase
353 * this node until all references are put and we do not access
354 * any fields of the node after a reference is put .
355 */ 236 */
356 if (test_bit(SID_ID_MAPPED, &psidid->state)) { 237 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
357 memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); 238 (struct cifs_sid *)&sidkey->payload.value :
358 psidid->time = jiffies; /* update ts for accessing */ 239 (struct cifs_sid *)sidkey->payload.data;
359 goto id_sid_out; 240
360 } 241 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
361 242 if (ksid_size > sidkey->datalen) {
362 if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) { 243 rc = -EIO;
363 rc = -EINVAL; 244 cFYI(1, "%s: Downcall contained malformed key (datalen=%hu, "
364 goto id_sid_out; 245 "ksid_size=%u)", __func__, sidkey->datalen, ksid_size);
246 goto invalidate_key;
365 } 247 }
366 248
367 if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) { 249 cifs_copy_sid(ssid, ksid);
368 saved_cred = override_creds(root_cred); 250out_key_put:
369 sidkey = request_key(&cifs_idmap_key_type, psidid->sidstr, ""); 251 key_put(sidkey);
370 if (IS_ERR(sidkey)) { 252out_revert_creds:
371 rc = -EINVAL; 253 revert_creds(saved_cred);
372 cFYI(1, "%s: Can't map and id to a SID", __func__);
373 } else {
374 lsid = (struct cifs_sid *)sidkey->payload.data;
375 memcpy(&psidid->sid, lsid,
376 sidkey->datalen < sizeof(struct cifs_sid) ?
377 sidkey->datalen : sizeof(struct cifs_sid));
378 memcpy(ssid, &psidid->sid,
379 sidkey->datalen < sizeof(struct cifs_sid) ?
380 sidkey->datalen : sizeof(struct cifs_sid));
381 set_bit(SID_ID_MAPPED, &psidid->state);
382 key_put(sidkey);
383 kfree(psidid->sidstr);
384 }
385 psidid->time = jiffies; /* update ts for accessing */
386 revert_creds(saved_cred);
387 clear_bit(SID_ID_PENDING, &psidid->state);
388 wake_up_bit(&psidid->state, SID_ID_PENDING);
389 } else {
390 rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
391 sidid_pending_wait, TASK_INTERRUPTIBLE);
392 if (rc) {
393 cFYI(1, "%s: sidid_pending_wait interrupted %d",
394 __func__, rc);
395 --psidid->refcount;
396 return rc;
397 }
398 if (test_bit(SID_ID_MAPPED, &psidid->state))
399 memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
400 else
401 rc = -EINVAL;
402 }
403id_sid_out:
404 --psidid->refcount;
405 return rc; 254 return rc;
255
256invalidate_key:
257 key_invalidate(sidkey);
258 goto out_key_put;
406} 259}
407 260
408static int 261static int
@@ -410,111 +263,67 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
410 struct cifs_fattr *fattr, uint sidtype) 263 struct cifs_fattr *fattr, uint sidtype)
411{ 264{
412 int rc; 265 int rc;
413 unsigned long cid; 266 struct key *sidkey;
414 struct key *idkey; 267 char *sidstr;
415 const struct cred *saved_cred; 268 const struct cred *saved_cred;
416 struct cifs_sid_id *psidid, *npsidid; 269 uid_t fuid = cifs_sb->mnt_uid;
417 struct rb_root *cidtree; 270 gid_t fgid = cifs_sb->mnt_gid;
418 spinlock_t *cidlock;
419
420 if (sidtype == SIDOWNER) {
421 cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */
422 cidlock = &siduidlock;
423 cidtree = &uidtree;
424 } else if (sidtype == SIDGROUP) {
425 cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */
426 cidlock = &sidgidlock;
427 cidtree = &gidtree;
428 } else
429 return -ENOENT;
430
431 spin_lock(cidlock);
432 psidid = id_rb_search(cidtree, psid);
433
434 if (!psidid) { /* node does not exist, allocate one & attempt adding */
435 spin_unlock(cidlock);
436 npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
437 if (!npsidid)
438 return -ENOMEM;
439
440 npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
441 if (!npsidid->sidstr) {
442 kfree(npsidid);
443 return -ENOMEM;
444 }
445
446 spin_lock(cidlock);
447 psidid = id_rb_search(cidtree, psid);
448 if (psidid) { /* node happened to get inserted meanwhile */
449 ++psidid->refcount;
450 spin_unlock(cidlock);
451 kfree(npsidid->sidstr);
452 kfree(npsidid);
453 } else {
454 psidid = npsidid;
455 id_rb_insert(cidtree, psid, &psidid,
456 sidtype == SIDOWNER ? "os:" : "gs:");
457 ++psidid->refcount;
458 spin_unlock(cidlock);
459 }
460 } else {
461 ++psidid->refcount;
462 spin_unlock(cidlock);
463 }
464 271
465 /* 272 /*
466 * 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.
467 * since a reference was taken earlier while holding the spinlock. 274 * Just return an error.
468 * A reference on the node is put without holding the spinlock
469 * and it is OK to do so in this case, shrinker will not erase
470 * this node until all references are put and we do not access
471 * any fields of the node after a reference is put .
472 */ 275 */
473 if (test_bit(SID_ID_MAPPED, &psidid->state)) { 276 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
474 cid = psidid->id; 277 cFYI(1, "%s: %u subauthorities is too many!", __func__,
475 psidid->time = jiffies; /* update ts for accessing */ 278 psid->num_subauth);
476 goto sid_to_id_out; 279 return -EIO;
477 } 280 }
478 281
479 if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) 282 sidstr = sid_to_key_str(psid, sidtype);
480 goto sid_to_id_out; 283 if (!sidstr)
481 284 return -ENOMEM;
482 if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) { 285
483 saved_cred = override_creds(root_cred); 286 saved_cred = override_creds(root_cred);
484 idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, ""); 287 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
485 if (IS_ERR(idkey)) 288 if (IS_ERR(sidkey)) {
486 cFYI(1, "%s: Can't map SID to an id", __func__); 289 rc = -EINVAL;
487 else { 290 cFYI(1, "%s: Can't map SID %s to a %cid", __func__, sidstr,
488 cid = *(unsigned long *)idkey->payload.value; 291 sidtype == SIDOWNER ? 'u' : 'g');
489 psidid->id = cid; 292 goto out_revert_creds;
490 set_bit(SID_ID_MAPPED, &psidid->state); 293 }
491 key_put(idkey); 294
492 kfree(psidid->sidstr); 295 /*
493 } 296 * FIXME: Here we assume that uid_t and gid_t are same size. It's
494 revert_creds(saved_cred); 297 * probably a safe assumption but might be better to check based on
495 psidid->time = jiffies; /* update ts for accessing */ 298 * sidtype.
496 clear_bit(SID_ID_PENDING, &psidid->state); 299 */
497 wake_up_bit(&psidid->state, SID_ID_PENDING); 300 if (sidkey->datalen != sizeof(uid_t)) {
498 } else { 301 rc = -EIO;
499 rc = wait_on_bit(&psidid->state, SID_ID_PENDING, 302 cFYI(1, "%s: Downcall contained malformed key "
500 sidid_pending_wait, TASK_INTERRUPTIBLE); 303 "(datalen=%hu)", __func__, sidkey->datalen);
501 if (rc) { 304 key_invalidate(sidkey);
502 cFYI(1, "%s: sidid_pending_wait interrupted %d", 305 goto out_key_put;
503 __func__, rc);
504 --psidid->refcount; /* decremented without spinlock */
505 return rc;
506 }
507 if (test_bit(SID_ID_MAPPED, &psidid->state))
508 cid = psidid->id;
509 } 306 }
510 307
511sid_to_id_out:
512 --psidid->refcount; /* decremented without spinlock */
513 if (sidtype == SIDOWNER) 308 if (sidtype == SIDOWNER)
514 fattr->cf_uid = cid; 309 memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
515 else 310 else
516 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);
517 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;
518 return 0; 327 return 0;
519} 328}
520 329
@@ -561,17 +370,6 @@ init_cifs_idmap(void)
561 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 370 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
562 root_cred = cred; 371 root_cred = cred;
563 372
564 spin_lock_init(&siduidlock);
565 uidtree = RB_ROOT;
566 spin_lock_init(&sidgidlock);
567 gidtree = RB_ROOT;
568
569 spin_lock_init(&uidsidlock);
570 siduidtree = RB_ROOT;
571 spin_lock_init(&gidsidlock);
572 sidgidtree = RB_ROOT;
573 register_shrinker(&cifs_shrinker);
574
575 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring)); 373 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
576 return 0; 374 return 0;
577 375
@@ -588,95 +386,13 @@ exit_cifs_idmap(void)
588 key_revoke(root_cred->thread_keyring); 386 key_revoke(root_cred->thread_keyring);
589 unregister_key_type(&cifs_idmap_key_type); 387 unregister_key_type(&cifs_idmap_key_type);
590 put_cred(root_cred); 388 put_cred(root_cred);
591 unregister_shrinker(&cifs_shrinker);
592 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name); 389 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
593} 390}
594 391
595void
596cifs_destroy_idmaptrees(void)
597{
598 struct rb_root *root;
599 struct rb_node *node;
600
601 root = &uidtree;
602 spin_lock(&siduidlock);
603 while ((node = rb_first(root)))
604 rb_erase(node, root);
605 spin_unlock(&siduidlock);
606
607 root = &gidtree;
608 spin_lock(&sidgidlock);
609 while ((node = rb_first(root)))
610 rb_erase(node, root);
611 spin_unlock(&sidgidlock);
612
613 root = &siduidtree;
614 spin_lock(&uidsidlock);
615 while ((node = rb_first(root)))
616 rb_erase(node, root);
617 spin_unlock(&uidsidlock);
618
619 root = &sidgidtree;
620 spin_lock(&gidsidlock);
621 while ((node = rb_first(root)))
622 rb_erase(node, root);
623 spin_unlock(&gidsidlock);
624}
625
626/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
627 the same returns 1, if they do not match returns 0 */
628int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
629{
630 int i;
631 int num_subauth, num_sat, num_saw;
632
633 if ((!ctsid) || (!cwsid))
634 return 1;
635
636 /* compare the revision */
637 if (ctsid->revision != cwsid->revision) {
638 if (ctsid->revision > cwsid->revision)
639 return 1;
640 else
641 return -1;
642 }
643
644 /* compare all of the six auth values */
645 for (i = 0; i < 6; ++i) {
646 if (ctsid->authority[i] != cwsid->authority[i]) {
647 if (ctsid->authority[i] > cwsid->authority[i])
648 return 1;
649 else
650 return -1;
651 }
652 }
653
654 /* compare all of the subauth values if any */
655 num_sat = ctsid->num_subauth;
656 num_saw = cwsid->num_subauth;
657 num_subauth = num_sat < num_saw ? num_sat : num_saw;
658 if (num_subauth) {
659 for (i = 0; i < num_subauth; ++i) {
660 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
661 if (le32_to_cpu(ctsid->sub_auth[i]) >
662 le32_to_cpu(cwsid->sub_auth[i]))
663 return 1;
664 else
665 return -1;
666 }
667 }
668 }
669
670 return 0; /* sids compare/match */
671}
672
673
674/* 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 */
675static void copy_sec_desc(const struct cifs_ntsd *pntsd, 393static void copy_sec_desc(const struct cifs_ntsd *pntsd,
676 struct cifs_ntsd *pnntsd, __u32 sidsoffset) 394 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
677{ 395{
678 int i;
679
680 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; 396 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
681 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; 397 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
682 398
@@ -692,26 +408,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
692 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + 408 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
693 le32_to_cpu(pntsd->osidoffset)); 409 le32_to_cpu(pntsd->osidoffset));
694 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); 410 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
695 411 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
696 nowner_sid_ptr->revision = owner_sid_ptr->revision;
697 nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
698 for (i = 0; i < 6; i++)
699 nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
700 for (i = 0; i < 5; i++)
701 nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
702 412
703 /* copy group sid */ 413 /* copy group sid */
704 group_sid_ptr = (struct cifs_sid *)((char *)pntsd + 414 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
705 le32_to_cpu(pntsd->gsidoffset)); 415 le32_to_cpu(pntsd->gsidoffset));
706 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + 416 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
707 sizeof(struct cifs_sid)); 417 sizeof(struct cifs_sid));
708 418 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
709 ngroup_sid_ptr->revision = group_sid_ptr->revision;
710 ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
711 for (i = 0; i < 6; i++)
712 ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
713 for (i = 0; i < 5; i++)
714 ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
715 419
716 return; 420 return;
717} 421}
@@ -818,7 +522,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
818 522
819 pntace->sid.revision = psid->revision; 523 pntace->sid.revision = psid->revision;
820 pntace->sid.num_subauth = psid->num_subauth; 524 pntace->sid.num_subauth = psid->num_subauth;
821 for (i = 0; i < 6; i++) 525 for (i = 0; i < NUM_AUTHS; i++)
822 pntace->sid.authority[i] = psid->authority[i]; 526 pntace->sid.authority[i] = psid->authority[i];
823 for (i = 0; i < psid->num_subauth; i++) 527 for (i = 0; i < psid->num_subauth; i++)
824 pntace->sid.sub_auth[i] = psid->sub_auth[i]; 528 pntace->sid.sub_auth[i] = psid->sub_auth[i];
@@ -994,8 +698,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
994 return -EINVAL; 698 return -EINVAL;
995 } 699 }
996 700
997 if (psid->num_subauth) {
998#ifdef CONFIG_CIFS_DEBUG2 701#ifdef CONFIG_CIFS_DEBUG2
702 if (psid->num_subauth) {
999 int i; 703 int i;
1000 cFYI(1, "SID revision %d num_auth %d", 704 cFYI(1, "SID revision %d num_auth %d",
1001 psid->revision, psid->num_subauth); 705 psid->revision, psid->num_subauth);
@@ -1009,8 +713,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1009 num auths and therefore go off the end */ 713 num auths and therefore go off the end */
1010 cFYI(1, "RID 0x%x", 714 cFYI(1, "RID 0x%x",
1011 le32_to_cpu(psid->sub_auth[psid->num_subauth-1])); 715 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1012#endif
1013 } 716 }
717#endif
1014 718
1015 return 0; 719 return 0;
1016} 720}
@@ -1120,8 +824,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1120 kfree(nowner_sid_ptr); 824 kfree(nowner_sid_ptr);
1121 return rc; 825 return rc;
1122 } 826 }
1123 memcpy(owner_sid_ptr, nowner_sid_ptr, 827 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1124 sizeof(struct cifs_sid));
1125 kfree(nowner_sid_ptr); 828 kfree(nowner_sid_ptr);
1126 *aclflag = CIFS_ACL_OWNER; 829 *aclflag = CIFS_ACL_OWNER;
1127 } 830 }
@@ -1139,8 +842,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1139 kfree(ngroup_sid_ptr); 842 kfree(ngroup_sid_ptr);
1140 return rc; 843 return rc;
1141 } 844 }
1142 memcpy(group_sid_ptr, ngroup_sid_ptr, 845 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1143 sizeof(struct cifs_sid));
1144 kfree(ngroup_sid_ptr); 846 kfree(ngroup_sid_ptr);
1145 *aclflag = CIFS_ACL_GROUP; 847 *aclflag = CIFS_ACL_GROUP;
1146 } 848 }
@@ -1316,42 +1018,39 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1316 1018
1317 /* Get the security descriptor */ 1019 /* Get the security descriptor */
1318 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);
1319
1320 /* Add three ACEs for owner, group, everyone getting rid of
1321 other ACEs as chmod disables ACEs and set the security descriptor */
1322
1323 if (IS_ERR(pntsd)) { 1021 if (IS_ERR(pntsd)) {
1324 rc = PTR_ERR(pntsd); 1022 rc = PTR_ERR(pntsd);
1325 cERROR(1, "%s: error %d getting sec desc", __func__, rc); 1023 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1326 } else { 1024 goto out;
1327 /* allocate memory for the smb header, 1025 }
1328 set security descriptor request security descriptor
1329 parameters, and secuirty descriptor itself */
1330
1331 secdesclen = secdesclen < DEFSECDESCLEN ?
1332 DEFSECDESCLEN : secdesclen;
1333 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1334 if (!pnntsd) {
1335 cERROR(1, "Unable to allocate security descriptor");
1336 kfree(pntsd);
1337 return -ENOMEM;
1338 }
1339 1026
1340 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, 1027 /*
1341 &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 }
1342 1040
1343 cFYI(DBG2, "build_sec_desc rc: %d", rc); 1041 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1042 &aclflag);
1344 1043
1345 if (!rc) { 1044 cFYI(DBG2, "build_sec_desc rc: %d", rc);
1346 /* Set the security descriptor */
1347 rc = set_cifs_acl(pnntsd, secdesclen, inode,
1348 path, aclflag);
1349 cFYI(DBG2, "set_cifs_acl rc: %d", rc);
1350 }
1351 1045
1352 kfree(pnntsd); 1046 if (!rc) {
1353 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);
1354 } 1050 }
1355 1051
1052 kfree(pnntsd);
1053 kfree(pntsd);
1054out:
1356 return rc; 1055 return rc;
1357} 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 7c0a81283645..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)
@@ -398,7 +430,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
398 * in network traffic in the other paths. 430 * in network traffic in the other paths.
399 */ 431 */
400 if (!(oflags & O_CREAT)) { 432 if (!(oflags & O_CREAT)) {
401 struct dentry *res = cifs_lookup(inode, direntry, 0); 433 struct dentry *res;
434
435 /*
436 * Check for hashed negative dentry. We have already revalidated
437 * the dentry and it is fine. No need to perform another lookup.
438 */
439 if (!d_unhashed(direntry))
440 return -ENOENT;
441
442 res = cifs_lookup(inode, direntry, 0);
402 if (IS_ERR(res)) 443 if (IS_ERR(res))
403 return PTR_ERR(res); 444 return PTR_ERR(res);
404 445
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index edb25b4bbb95..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);
@@ -1794,7 +1812,6 @@ static int cifs_writepages(struct address_space *mapping,
1794 struct TCP_Server_Info *server; 1812 struct TCP_Server_Info *server;
1795 struct page *page; 1813 struct page *page;
1796 int rc = 0; 1814 int rc = 0;
1797 loff_t isize = i_size_read(mapping->host);
1798 1815
1799 /* 1816 /*
1800 * If wsize is smaller than the page cache size, default to writing 1817 * If wsize is smaller than the page cache size, default to writing
@@ -1899,7 +1916,7 @@ retry:
1899 */ 1916 */
1900 set_page_writeback(page); 1917 set_page_writeback(page);
1901 1918
1902 if (page_offset(page) >= isize) { 1919 if (page_offset(page) >= i_size_read(mapping->host)) {
1903 done = true; 1920 done = true;
1904 unlock_page(page); 1921 unlock_page(page);
1905 end_page_writeback(page); 1922 end_page_writeback(page);
@@ -1932,7 +1949,8 @@ retry:
1932 wdata->offset = page_offset(wdata->pages[0]); 1949 wdata->offset = page_offset(wdata->pages[0]);
1933 wdata->pagesz = PAGE_CACHE_SIZE; 1950 wdata->pagesz = PAGE_CACHE_SIZE;
1934 wdata->tailsz = 1951 wdata->tailsz =
1935 min(isize - page_offset(wdata->pages[nr_pages - 1]), 1952 min(i_size_read(mapping->host) -
1953 page_offset(wdata->pages[nr_pages - 1]),
1936 (loff_t)PAGE_CACHE_SIZE); 1954 (loff_t)PAGE_CACHE_SIZE);
1937 wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + 1955 wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) +
1938 wdata->tailsz; 1956 wdata->tailsz;
@@ -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 f9b5d3d6cf33..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);
@@ -86,35 +88,33 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
86 88
87 dentry = d_lookup(parent, name); 89 dentry = d_lookup(parent, name);
88 if (dentry) { 90 if (dentry) {
91 int err;
92
89 inode = dentry->d_inode; 93 inode = dentry->d_inode;
90 /* update inode in place if i_ino didn't change */ 94 /* update inode in place if i_ino didn't change */
91 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { 95 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
92 cifs_fattr_to_inode(inode, fattr); 96 cifs_fattr_to_inode(inode, fattr);
93 return dentry; 97 goto out;
94 } 98 }
95 d_drop(dentry); 99 err = d_invalidate(dentry);
96 dput(dentry); 100 dput(dentry);
101 if (err)
102 return;
97 } 103 }
98 104
99 dentry = d_alloc(parent, name); 105 dentry = d_alloc(parent, name);
100 if (dentry == NULL) 106 if (!dentry)
101 return NULL; 107 return;
102 108
103 inode = cifs_iget(sb, fattr); 109 inode = cifs_iget(sb, fattr);
104 if (!inode) { 110 if (!inode)
105 dput(dentry); 111 goto out;
106 return NULL;
107 }
108 112
109 alias = d_materialise_unique(dentry, inode); 113 alias = d_materialise_unique(dentry, inode);
110 if (alias != NULL) { 114 if (alias && !IS_ERR(alias))
111 dput(dentry); 115 dput(alias);
112 if (IS_ERR(alias)) 116out:
113 return NULL; 117 dput(dentry);
114 dentry = alias;
115 }
116
117 return dentry;
118} 118}
119 119
120static void 120static void
@@ -134,6 +134,16 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
134 if (fattr->cf_cifsattrs & ATTR_READONLY) 134 if (fattr->cf_cifsattrs & ATTR_READONLY)
135 fattr->cf_mode &= ~S_IWUGO; 135 fattr->cf_mode &= ~S_IWUGO;
136 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
137 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && 147 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
138 fattr->cf_cifsattrs & ATTR_SYSTEM) { 148 fattr->cf_cifsattrs & ATTR_SYSTEM) {
139 if (fattr->cf_eof == 0) { 149 if (fattr->cf_eof == 0) {
@@ -649,7 +659,6 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
649 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 659 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
650 struct cifs_dirent de = { NULL, }; 660 struct cifs_dirent de = { NULL, };
651 struct cifs_fattr fattr; 661 struct cifs_fattr fattr;
652 struct dentry *dentry;
653 struct qstr name; 662 struct qstr name;
654 int rc = 0; 663 int rc = 0;
655 ino_t ino; 664 ino_t ino;
@@ -720,13 +729,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
720 */ 729 */
721 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; 730 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
722 731
723 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 732 cifs_prime_dcache(file->f_dentry, &name, &fattr);
724 dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
725 733
734 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
726 rc = filldir(dirent, name.name, name.len, file->f_pos, ino, 735 rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
727 fattr.cf_dtype); 736 fattr.cf_dtype);
728
729 dput(dentry);
730 return rc; 737 return rc;
731} 738}
732 739
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 56cc4be87807..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{
@@ -766,7 +735,6 @@ smb_set_file_info(struct inode *inode, const char *full_path,
766 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 735 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
767 struct tcon_link *tlink = NULL; 736 struct tcon_link *tlink = NULL;
768 struct cifs_tcon *tcon; 737 struct cifs_tcon *tcon;
769 FILE_BASIC_INFO info_buf;
770 738
771 /* if the file is already open for write, just use that fileid */ 739 /* if the file is already open for write, just use that fileid */
772 open_file = find_writable_file(cinode, true); 740 open_file = find_writable_file(cinode, true);
@@ -817,7 +785,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
817 netpid = current->tgid; 785 netpid = current->tgid;
818 786
819set_via_filehandle: 787set_via_filehandle:
820 rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid); 788 rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid);
821 if (!rc) 789 if (!rc)
822 cinode->cifsAttrs = le32_to_cpu(buf->Attributes); 790 cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
823 791
@@ -944,7 +912,6 @@ struct smb_version_operations smb1_operations = {
944 .set_path_size = CIFSSMBSetEOF, 912 .set_path_size = CIFSSMBSetEOF,
945 .set_file_size = CIFSSMBSetFileSize, 913 .set_file_size = CIFSSMBSetFileSize,
946 .set_file_info = smb_set_file_info, 914 .set_file_info = smb_set_file_info,
947 .build_path_to_root = cifs_build_path_to_root,
948 .echo = CIFSSMBEcho, 915 .echo = CIFSSMBEcho,
949 .mkdir = CIFSSMBMkDir, 916 .mkdir = CIFSSMBMkDir,
950 .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)