aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2013-01-29 04:48:30 -0500
committerJiri Kosina <jkosina@suse.cz>2013-01-29 04:48:30 -0500
commit617677295b53a40d0e54aac4cbbc216ffbc755dd (patch)
tree51b9e87213243ed5efff252c8e8d8fec4eebc588 /fs/cifs
parent5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff)
parent6abb7c25775b7fb2225ad0508236d63ca710e65f (diff)
Merge branch 'master' into for-next
Conflicts: drivers/devfreq/exynos4_bus.c Sync with Linus' tree to be able to apply patches that are against newer code (mvneta).
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/Kconfig10
-rw-r--r--fs/cifs/cifs_debug.h72
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifsacl.c777
-rw-r--r--fs/cifs/cifsacl.h66
-rw-r--r--fs/cifs/cifsfs.c25
-rw-r--r--fs/cifs/cifsglob.h36
-rw-r--r--fs/cifs/cifsproto.h10
-rw-r--r--fs/cifs/connect.c313
-rw-r--r--fs/cifs/dir.c43
-rw-r--r--fs/cifs/file.c215
-rw-r--r--fs/cifs/inode.c7
-rw-r--r--fs/cifs/netmisc.c14
-rw-r--r--fs/cifs/readdir.c72
-rw-r--r--fs/cifs/smb1ops.c43
-rw-r--r--fs/cifs/smb2file.c12
-rw-r--r--fs/cifs/smb2ops.c105
-rw-r--r--fs/cifs/smb2pdu.c5
-rw-r--r--fs/cifs/smb2proto.h4
-rw-r--r--fs/cifs/smb2transport.c13
-rw-r--r--fs/cifs/transport.c6
21 files changed, 852 insertions, 998 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..69ae3d3c3b31 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,39 @@ 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;
40
40/* 41/*
41 * debug ON 42 * debug ON
42 * -------- 43 * --------
43 */ 44 */
44#ifdef CIFS_DEBUG 45#ifdef CONFIG_CIFS_DEBUG
45 46
46/* information message: e.g., configuration, major event */ 47/* information message: e.g., configuration, major event */
47extern int cifsFYI; 48#define cifsfyi(fmt, ...) \
48#define cifsfyi(fmt, arg...) \
49do { \ 49do { \
50 if (cifsFYI & CIFS_INFO) \ 50 if (cifsFYI & CIFS_INFO) \
51 printk(KERN_DEBUG "%s: " fmt "\n", __FILE__, ##arg); \ 51 printk(KERN_DEBUG "%s: " fmt "\n", \
52} while (0) 52 __FILE__, ##__VA_ARGS__); \
53
54#define cFYI(set, fmt, arg...) \
55do { \
56 if (set) \
57 cifsfyi(fmt, ##arg); \
58} while (0) 53} while (0)
59 54
60#define cifswarn(fmt, arg...) \ 55#define cFYI(set, fmt, ...) \
61 printk(KERN_WARNING fmt "\n", ##arg)
62
63/* debug event message: */
64extern int cifsERROR;
65
66#define cEVENT(fmt, arg...) \
67do { \ 56do { \
68 if (cifsERROR) \ 57 if (set) \
69 printk(KERN_EVENT "%s: " fmt "\n", __FILE__, ##arg); \ 58 cifsfyi(fmt, ##__VA_ARGS__); \
70} while (0) 59} while (0)
71 60
61#define cifswarn(fmt, ...) \
62 printk(KERN_WARNING fmt "\n", ##__VA_ARGS__)
63
72/* error event message: e.g., i/o error */ 64/* error event message: e.g., i/o error */
73#define cifserror(fmt, arg...) \ 65#define cifserror(fmt, ...) \
74do { \ 66 printk(KERN_ERR "CIFS VFS: " fmt "\n", ##__VA_ARGS__); \
75 if (cifsERROR) \
76 printk(KERN_ERR "CIFS VFS: " fmt "\n", ##arg); \
77} while (0)
78 67
79#define cERROR(set, fmt, arg...) \ 68#define cERROR(set, fmt, ...) \
80do { \ 69do { \
81 if (set) \ 70 if (set) \
82 cifserror(fmt, ##arg); \ 71 cifserror(fmt, ##__VA_ARGS__); \
83} while (0) 72} while (0)
84 73
85/* 74/*
@@ -87,10 +76,27 @@ do { \
87 * --------- 76 * ---------
88 */ 77 */
89#else /* _CIFS_DEBUG */ 78#else /* _CIFS_DEBUG */
90#define cERROR(set, fmt, arg...) 79#define cifsfyi(fmt, ...) \
91#define cEVENT(fmt, arg...) 80do { \
92#define cFYI(set, fmt, arg...) 81 if (0) \
93#define cifserror(fmt, arg...) 82 printk(KERN_DEBUG "%s: " fmt "\n", \
83 __FILE__, ##__VA_ARGS__); \
84} while (0)
85#define cFYI(set, fmt, ...) \
86do { \
87 if (0 && set) \
88 cifsfyi(fmt, ##__VA_ARGS__); \
89} while (0)
90#define cifserror(fmt, ...) \
91do { \
92 if (0) \
93 printk(KERN_ERR "CIFS VFS: " fmt "\n", ##__VA_ARGS__); \
94} while (0)
95#define cERROR(set, fmt, ...) \
96do { \
97 if (0 && set) \
98 cifserror(fmt, ##__VA_ARGS__); \
99} while (0)
94#endif /* _CIFS_DEBUG */ 100#endif /* _CIFS_DEBUG */
95 101
96#endif /* _H_CIFS_DEBUG */ 102#endif /* _H_CIFS_DEBUG */
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index ce5cbd717bfc..210fce2df308 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -226,6 +226,8 @@ compose_mount_options_out:
226compose_mount_options_err: 226compose_mount_options_err:
227 kfree(mountdata); 227 kfree(mountdata);
228 mountdata = ERR_PTR(rc); 228 mountdata = ERR_PTR(rc);
229 kfree(*devname);
230 *devname = NULL;
229 goto compose_mount_options_out; 231 goto compose_mount_options_out;
230} 232}
231 233
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index fc783e264420..5cbd00e74067 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
314 spin_lock(cidlock);
315 psidid = sid_rb_search(cidtree, cid);
316
317 if (!psidid) { /* node does not exist, allocate one & attempt adding */
318 spin_unlock(cidlock);
319 npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
320 if (!npsidid)
321 return -ENOMEM;
322 211
323 npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL); 212 rc = snprintf(desc, sizeof(desc), "%ci:%u",
324 if (!npsidid->sidstr) { 213 sidtype == SIDOWNER ? 'o' : 'g', cid);
325 kfree(npsidid); 214 if (rc >= sizeof(desc))
326 return -ENOMEM; 215 return -EINVAL;
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
@@ -537,19 +346,15 @@ init_cifs_idmap(void)
537 if (!cred) 346 if (!cred)
538 return -ENOMEM; 347 return -ENOMEM;
539 348
540 keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred, 349 keyring = keyring_alloc(".cifs_idmap", 0, 0, cred,
541 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 350 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
542 KEY_USR_VIEW | KEY_USR_READ, 351 KEY_USR_VIEW | KEY_USR_READ,
543 KEY_ALLOC_NOT_IN_QUOTA); 352 KEY_ALLOC_NOT_IN_QUOTA, NULL);
544 if (IS_ERR(keyring)) { 353 if (IS_ERR(keyring)) {
545 ret = PTR_ERR(keyring); 354 ret = PTR_ERR(keyring);
546 goto failed_put_cred; 355 goto failed_put_cred;
547 } 356 }
548 357
549 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
550 if (ret < 0)
551 goto failed_put_key;
552
553 ret = register_key_type(&cifs_idmap_key_type); 358 ret = register_key_type(&cifs_idmap_key_type);
554 if (ret < 0) 359 if (ret < 0)
555 goto failed_put_key; 360 goto failed_put_key;
@@ -561,17 +366,6 @@ init_cifs_idmap(void)
561 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 366 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
562 root_cred = cred; 367 root_cred = cred;
563 368
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)); 369 cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
576 return 0; 370 return 0;
577 371
@@ -588,95 +382,13 @@ exit_cifs_idmap(void)
588 key_revoke(root_cred->thread_keyring); 382 key_revoke(root_cred->thread_keyring);
589 unregister_key_type(&cifs_idmap_key_type); 383 unregister_key_type(&cifs_idmap_key_type);
590 put_cred(root_cred); 384 put_cred(root_cred);
591 unregister_shrinker(&cifs_shrinker);
592 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name); 385 cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
593} 386}
594 387
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 */ 388/* copy ntsd, owner sid, and group sid from a security descriptor to another */
675static void copy_sec_desc(const struct cifs_ntsd *pntsd, 389static void copy_sec_desc(const struct cifs_ntsd *pntsd,
676 struct cifs_ntsd *pnntsd, __u32 sidsoffset) 390 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
677{ 391{
678 int i;
679
680 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; 392 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
681 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; 393 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
682 394
@@ -692,26 +404,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
692 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + 404 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
693 le32_to_cpu(pntsd->osidoffset)); 405 le32_to_cpu(pntsd->osidoffset));
694 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); 406 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
695 407 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 408
703 /* copy group sid */ 409 /* copy group sid */
704 group_sid_ptr = (struct cifs_sid *)((char *)pntsd + 410 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
705 le32_to_cpu(pntsd->gsidoffset)); 411 le32_to_cpu(pntsd->gsidoffset));
706 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + 412 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
707 sizeof(struct cifs_sid)); 413 sizeof(struct cifs_sid));
708 414 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 415
716 return; 416 return;
717} 417}
@@ -818,7 +518,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
818 518
819 pntace->sid.revision = psid->revision; 519 pntace->sid.revision = psid->revision;
820 pntace->sid.num_subauth = psid->num_subauth; 520 pntace->sid.num_subauth = psid->num_subauth;
821 for (i = 0; i < 6; i++) 521 for (i = 0; i < NUM_AUTHS; i++)
822 pntace->sid.authority[i] = psid->authority[i]; 522 pntace->sid.authority[i] = psid->authority[i];
823 for (i = 0; i < psid->num_subauth; i++) 523 for (i = 0; i < psid->num_subauth; i++)
824 pntace->sid.sub_auth[i] = psid->sub_auth[i]; 524 pntace->sid.sub_auth[i] = psid->sub_auth[i];
@@ -994,8 +694,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
994 return -EINVAL; 694 return -EINVAL;
995 } 695 }
996 696
997 if (psid->num_subauth) {
998#ifdef CONFIG_CIFS_DEBUG2 697#ifdef CONFIG_CIFS_DEBUG2
698 if (psid->num_subauth) {
999 int i; 699 int i;
1000 cFYI(1, "SID revision %d num_auth %d", 700 cFYI(1, "SID revision %d num_auth %d",
1001 psid->revision, psid->num_subauth); 701 psid->revision, psid->num_subauth);
@@ -1009,8 +709,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
1009 num auths and therefore go off the end */ 709 num auths and therefore go off the end */
1010 cFYI(1, "RID 0x%x", 710 cFYI(1, "RID 0x%x",
1011 le32_to_cpu(psid->sub_auth[psid->num_subauth-1])); 711 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1012#endif
1013 } 712 }
713#endif
1014 714
1015 return 0; 715 return 0;
1016} 716}
@@ -1120,8 +820,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1120 kfree(nowner_sid_ptr); 820 kfree(nowner_sid_ptr);
1121 return rc; 821 return rc;
1122 } 822 }
1123 memcpy(owner_sid_ptr, nowner_sid_ptr, 823 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1124 sizeof(struct cifs_sid));
1125 kfree(nowner_sid_ptr); 824 kfree(nowner_sid_ptr);
1126 *aclflag = CIFS_ACL_OWNER; 825 *aclflag = CIFS_ACL_OWNER;
1127 } 826 }
@@ -1139,8 +838,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1139 kfree(ngroup_sid_ptr); 838 kfree(ngroup_sid_ptr);
1140 return rc; 839 return rc;
1141 } 840 }
1142 memcpy(group_sid_ptr, ngroup_sid_ptr, 841 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1143 sizeof(struct cifs_sid));
1144 kfree(ngroup_sid_ptr); 842 kfree(ngroup_sid_ptr);
1145 *aclflag = CIFS_ACL_GROUP; 843 *aclflag = CIFS_ACL_GROUP;
1146 } 844 }
@@ -1316,42 +1014,39 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1316 1014
1317 /* Get the security descriptor */ 1015 /* Get the security descriptor */
1318 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); 1016 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)) { 1017 if (IS_ERR(pntsd)) {
1324 rc = PTR_ERR(pntsd); 1018 rc = PTR_ERR(pntsd);
1325 cERROR(1, "%s: error %d getting sec desc", __func__, rc); 1019 cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1326 } else { 1020 goto out;
1327 /* allocate memory for the smb header, 1021 }
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 1022
1340 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, 1023 /*
1341 &aclflag); 1024 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1025 * as chmod disables ACEs and set the security descriptor. Allocate
1026 * memory for the smb header, set security descriptor request security
1027 * descriptor parameters, and secuirty descriptor itself
1028 */
1029 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1030 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1031 if (!pnntsd) {
1032 cERROR(1, "Unable to allocate security descriptor");
1033 kfree(pntsd);
1034 return -ENOMEM;
1035 }
1342 1036
1343 cFYI(DBG2, "build_sec_desc rc: %d", rc); 1037 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1038 &aclflag);
1344 1039
1345 if (!rc) { 1040 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 1041
1352 kfree(pnntsd); 1042 if (!rc) {
1353 kfree(pntsd); 1043 /* Set the security descriptor */
1044 rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
1045 cFYI(DBG2, "set_cifs_acl rc: %d", rc);
1354 } 1046 }
1355 1047
1048 kfree(pnntsd);
1049 kfree(pntsd);
1050out:
1356 return rc; 1051 return rc;
1357} 1052}
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..de7f9168a118 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -54,7 +54,6 @@
54#endif 54#endif
55 55
56int cifsFYI = 0; 56int cifsFYI = 0;
57int cifsERROR = 1;
58int traceSMB = 0; 57int traceSMB = 0;
59bool enable_oplocks = true; 58bool enable_oplocks = true;
60unsigned int linuxExtEnabled = 1; 59unsigned int linuxExtEnabled = 1;
@@ -64,24 +63,23 @@ unsigned int global_secflags = CIFSSEC_DEF;
64unsigned int sign_CIFS_PDUs = 1; 63unsigned int sign_CIFS_PDUs = 1;
65static const struct super_operations cifs_super_ops; 64static const struct super_operations cifs_super_ops;
66unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 65unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
67module_param(CIFSMaxBufSize, int, 0); 66module_param(CIFSMaxBufSize, uint, 0);
68MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). " 67MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
69 "Default: 16384 Range: 8192 to 130048"); 68 "Default: 16384 Range: 8192 to 130048");
70unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; 69unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
71module_param(cifs_min_rcv, int, 0); 70module_param(cifs_min_rcv, uint, 0);
72MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: " 71MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
73 "1 to 64"); 72 "1 to 64");
74unsigned int cifs_min_small = 30; 73unsigned int cifs_min_small = 30;
75module_param(cifs_min_small, int, 0); 74module_param(cifs_min_small, uint, 0);
76MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 " 75MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
77 "Range: 2 to 256"); 76 "Range: 2 to 256");
78unsigned int cifs_max_pending = CIFS_MAX_REQ; 77unsigned int cifs_max_pending = CIFS_MAX_REQ;
79module_param(cifs_max_pending, int, 0444); 78module_param(cifs_max_pending, uint, 0444);
80MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " 79MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
81 "Default: 32767 Range: 2 to 32767."); 80 "Default: 32767 Range: 2 to 32767.");
82module_param(enable_oplocks, bool, 0644); 81module_param(enable_oplocks, bool, 0644);
83MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks (bool). Default:" 82MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1");
84 "y/Y/1");
85 83
86extern mempool_t *cifs_sm_req_poolp; 84extern mempool_t *cifs_sm_req_poolp;
87extern mempool_t *cifs_req_poolp; 85extern mempool_t *cifs_req_poolp;
@@ -540,8 +538,8 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
540 char *s, *p; 538 char *s, *p;
541 char sep; 539 char sep;
542 540
543 full_path = build_path_to_root(vol, cifs_sb, 541 full_path = cifs_build_path_to_root(vol, cifs_sb,
544 cifs_sb_master_tcon(cifs_sb)); 542 cifs_sb_master_tcon(cifs_sb));
545 if (full_path == NULL) 543 if (full_path == NULL)
546 return ERR_PTR(-ENOMEM); 544 return ERR_PTR(-ENOMEM);
547 545
@@ -695,13 +693,13 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
695 return written; 693 return written;
696} 694}
697 695
698static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) 696static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
699{ 697{
700 /* 698 /*
701 * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate 699 * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
702 * the cached file length 700 * the cached file length
703 */ 701 */
704 if (origin != SEEK_SET && origin != SEEK_CUR) { 702 if (whence != SEEK_SET && whence != SEEK_CUR) {
705 int rc; 703 int rc;
706 struct inode *inode = file->f_path.dentry->d_inode; 704 struct inode *inode = file->f_path.dentry->d_inode;
707 705
@@ -728,7 +726,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
728 if (rc < 0) 726 if (rc < 0)
729 return (loff_t)rc; 727 return (loff_t)rc;
730 } 728 }
731 return generic_file_llseek(file, offset, origin); 729 return generic_file_llseek(file, offset, whence);
732} 730}
733 731
734static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) 732static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
@@ -1205,7 +1203,6 @@ exit_cifs(void)
1205 unregister_filesystem(&cifs_fs_type); 1203 unregister_filesystem(&cifs_fs_type);
1206 cifs_dfs_release_automount_timer(); 1204 cifs_dfs_release_automount_timer();
1207#ifdef CONFIG_CIFS_ACL 1205#ifdef CONFIG_CIFS_ACL
1208 cifs_destroy_idmaptrees();
1209 exit_cifs_idmap(); 1206 exit_cifs_idmap();
1210#endif 1207#endif
1211#ifdef CONFIG_CIFS_UPCALL 1208#ifdef CONFIG_CIFS_UPCALL
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index f5af2527fc69..e6899cea1c35 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 {
@@ -386,6 +386,7 @@ struct smb_version_values {
386 unsigned int cap_unix; 386 unsigned int cap_unix;
387 unsigned int cap_nt_find; 387 unsigned int cap_nt_find;
388 unsigned int cap_large_files; 388 unsigned int cap_large_files;
389 unsigned int oplock_read;
389}; 390};
390 391
391#define HEADER_SIZE(server) (server->vals->header_size) 392#define HEADER_SIZE(server) (server->vals->header_size)
@@ -396,7 +397,6 @@ struct smb_vol {
396 char *password; 397 char *password;
397 char *domainname; 398 char *domainname;
398 char *UNC; 399 char *UNC;
399 char *UNCip;
400 char *iocharset; /* local code page for mapping to and from Unicode */ 400 char *iocharset; /* local code page for mapping to and from Unicode */
401 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ 401 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 */ 402 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
@@ -444,11 +444,11 @@ struct smb_vol {
444 unsigned int rsize; 444 unsigned int rsize;
445 unsigned int wsize; 445 unsigned int wsize;
446 bool sockopt_tcp_nodelay:1; 446 bool sockopt_tcp_nodelay:1;
447 unsigned short int port;
448 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 447 unsigned long actimeo; /* attribute cache timeout (jiffies) */
449 struct smb_version_operations *ops; 448 struct smb_version_operations *ops;
450 struct smb_version_values *vals; 449 struct smb_version_values *vals;
451 char *prepath; 450 char *prepath;
451 struct sockaddr_storage dstaddr; /* destination address */
452 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 452 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
453 struct nls_table *local_nls; 453 struct nls_table *local_nls;
454}; 454};
@@ -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..12b3da39733b 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,45 @@ 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)
1563 goto out_nomem; 1628 goto out_nomem;
1564 1629
1565 temp_len = strnlen(string, 300); 1630 convert_delimiter(vol->UNC, '\\');
1566 if (temp_len == 300) { 1631 if (vol->UNC[0] != '\\' || vol->UNC[1] != '\\') {
1567 printk(KERN_WARNING "CIFS: UNC name too long\n"); 1632 printk(KERN_ERR "CIFS: UNC Path does not "
1568 goto cifs_parse_mount_err; 1633 "begin with // or \\\\\n");
1569 }
1570
1571 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1572 if (vol->UNC == NULL) {
1573 printk(KERN_WARNING "CIFS: no memory for UNC\n");
1574 goto cifs_parse_mount_err;
1575 }
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; 1634 goto cifs_parse_mount_err;
1585 } 1635 }
1586 1636
1637 /* Compare old unc= option to new one */
1638 if (!string || strcmp(string, vol->UNC))
1639 printk(KERN_WARNING "CIFS: the value of the "
1640 "unc= mount option does not match the "
1641 "device string. Using the unc= option "
1642 "for now. In 3.10, that option will "
1643 "be ignored and the contents of the "
1644 "device string will be used "
1645 "instead. (%s != %s)\n", string,
1646 vol->UNC);
1587 break; 1647 break;
1588 case Opt_domain: 1648 case Opt_domain:
1589 string = match_strdup(args); 1649 string = match_strdup(args);
@@ -1618,31 +1678,24 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1618 } 1678 }
1619 break; 1679 break;
1620 case Opt_prefixpath: 1680 case Opt_prefixpath:
1621 string = match_strdup(args); 1681 /* skip over any leading delimiter */
1622 if (string == NULL) 1682 if (*args[0].from == '/' || *args[0].from == '\\')
1623 goto out_nomem; 1683 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
1633 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1634 if (vol->prepath == NULL) {
1635 printk(KERN_WARNING "CIFS: no memory "
1636 "for path prefix\n");
1637 goto cifs_parse_mount_err;
1638 }
1639
1640 if (string[0] != '/') {
1641 vol->prepath[0] = '/';
1642 strcpy(vol->prepath+1, string);
1643 } else
1644 strcpy(vol->prepath, string);
1645 1684
1685 string = vol->prepath;
1686 vol->prepath = match_strdup(args);
1687 if (vol->prepath == NULL)
1688 goto out_nomem;
1689 /* Compare old prefixpath= option to new one */
1690 if (!string || strcmp(string, vol->prepath))
1691 printk(KERN_WARNING "CIFS: the value of the "
1692 "prefixpath= mount option does not "
1693 "match the device string. Using the "
1694 "prefixpath= option for now. In 3.10, "
1695 "that option will be ignored and the "
1696 "contents of the device string will be "
1697 "used instead.(%s != %s)\n", string,
1698 vol->prepath);
1646 break; 1699 break;
1647 case Opt_iocharset: 1700 case Opt_iocharset:
1648 string = match_strdup(args); 1701 string = match_strdup(args);
@@ -1799,9 +1852,30 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1799 goto cifs_parse_mount_err; 1852 goto cifs_parse_mount_err;
1800 } 1853 }
1801#endif 1854#endif
1855 if (!vol->UNC) {
1856 cERROR(1, "CIFS mount error: No usable UNC path provided in "
1857 "device string or in unc= option!");
1858 goto cifs_parse_mount_err;
1859 }
1802 1860
1803 if (vol->UNCip == NULL) 1861 /* make sure UNC has a share name */
1804 vol->UNCip = &vol->UNC[2]; 1862 if (!strchr(vol->UNC + 3, '\\')) {
1863 cERROR(1, "Malformed UNC. Unable to find share name.");
1864 goto cifs_parse_mount_err;
1865 }
1866
1867 if (!got_ip) {
1868 /* No ip= option specified? Try to get it from UNC */
1869 if (!cifs_convert_address(dstaddr, &vol->UNC[2],
1870 strlen(&vol->UNC[2]))) {
1871 printk(KERN_ERR "Unable to determine destination "
1872 "address.\n");
1873 goto cifs_parse_mount_err;
1874 }
1875 }
1876
1877 /* set the port that we got earlier */
1878 cifs_set_port(dstaddr, port);
1805 1879
1806 if (uid_specified) 1880 if (uid_specified)
1807 vol->override_uid = override_uid; 1881 vol->override_uid = override_uid;
@@ -1843,7 +1917,7 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1843 } 1917 }
1844 case AF_INET6: { 1918 case AF_INET6: {
1845 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr; 1919 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1846 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs; 1920 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
1847 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr); 1921 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1848 } 1922 }
1849 default: 1923 default:
@@ -1972,9 +2046,10 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1972 return true; 2046 return true;
1973} 2047}
1974 2048
1975static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr, 2049static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
1976 struct smb_vol *vol)
1977{ 2050{
2051 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr;
2052
1978 if ((server->vals != vol->vals) || (server->ops != vol->ops)) 2053 if ((server->vals != vol->vals) || (server->ops != vol->ops))
1979 return 0; 2054 return 0;
1980 2055
@@ -1995,13 +2070,13 @@ static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
1995} 2070}
1996 2071
1997static struct TCP_Server_Info * 2072static struct TCP_Server_Info *
1998cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) 2073cifs_find_tcp_session(struct smb_vol *vol)
1999{ 2074{
2000 struct TCP_Server_Info *server; 2075 struct TCP_Server_Info *server;
2001 2076
2002 spin_lock(&cifs_tcp_ses_lock); 2077 spin_lock(&cifs_tcp_ses_lock);
2003 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 2078 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
2004 if (!match_server(server, addr, vol)) 2079 if (!match_server(server, vol))
2005 continue; 2080 continue;
2006 2081
2007 ++server->srv_count; 2082 ++server->srv_count;
@@ -2051,40 +2126,12 @@ static struct TCP_Server_Info *
2051cifs_get_tcp_session(struct smb_vol *volume_info) 2126cifs_get_tcp_session(struct smb_vol *volume_info)
2052{ 2127{
2053 struct TCP_Server_Info *tcp_ses = NULL; 2128 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; 2129 int rc;
2058 2130
2059 memset(&addr, 0, sizeof(struct sockaddr_storage)); 2131 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 2132
2086 /* see if we already have a matching tcp_ses */ 2133 /* see if we already have a matching tcp_ses */
2087 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info); 2134 tcp_ses = cifs_find_tcp_session(volume_info);
2088 if (tcp_ses) 2135 if (tcp_ses)
2089 return tcp_ses; 2136 return tcp_ses;
2090 2137
@@ -2129,27 +2176,18 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2129 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 2176 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
2130 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 2177 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
2131 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); 2178 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
2132 2179 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
2180 sizeof(tcp_ses->srcaddr));
2181 memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
2182 sizeof(tcp_ses->dstaddr));
2133 /* 2183 /*
2134 * at this point we are the only ones with the pointer 2184 * at this point we are the only ones with the pointer
2135 * to the struct since the kernel thread not created yet 2185 * to the struct since the kernel thread not created yet
2136 * no need to spinlock this init of tcpStatus or srv_count 2186 * no need to spinlock this init of tcpStatus or srv_count
2137 */ 2187 */
2138 tcp_ses->tcpStatus = CifsNew; 2188 tcp_ses->tcpStatus = CifsNew;
2139 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
2140 sizeof(tcp_ses->srcaddr));
2141 ++tcp_ses->srv_count; 2189 ++tcp_ses->srv_count;
2142 2190
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); 2191 rc = ip_connect(tcp_ses);
2154 if (rc < 0) { 2192 if (rc < 0) {
2155 cERROR(1, "Error connecting to socket. Aborting operation"); 2193 cERROR(1, "Error connecting to socket. Aborting operation");
@@ -2397,8 +2435,6 @@ cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
2397} 2435}
2398#endif /* CONFIG_KEYS */ 2436#endif /* CONFIG_KEYS */
2399 2437
2400static bool warned_on_ntlm; /* globals init to false automatically */
2401
2402static struct cifs_ses * 2438static struct cifs_ses *
2403cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) 2439cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2404{ 2440{
@@ -2475,14 +2511,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2475 ses->cred_uid = volume_info->cred_uid; 2511 ses->cred_uid = volume_info->cred_uid;
2476 ses->linux_uid = volume_info->linux_uid; 2512 ses->linux_uid = volume_info->linux_uid;
2477 2513
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; 2514 ses->overrideSecFlg = volume_info->secFlg;
2487 2515
2488 mutex_lock(&ses->session_mutex); 2516 mutex_lock(&ses->session_mutex);
@@ -2598,13 +2626,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2598 } 2626 }
2599 } 2627 }
2600 2628
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 /* 2629 /*
2609 * BB Do we need to wrap session_mutex around this TCon call and Unix 2630 * BB Do we need to wrap session_mutex around this TCon call and Unix
2610 * SetFS as we do on SessSetup and reconnect? 2631 * SetFS as we do on SessSetup and reconnect?
@@ -2718,11 +2739,8 @@ cifs_match_super(struct super_block *sb, void *data)
2718 struct cifs_ses *ses; 2739 struct cifs_ses *ses;
2719 struct cifs_tcon *tcon; 2740 struct cifs_tcon *tcon;
2720 struct tcon_link *tlink; 2741 struct tcon_link *tlink;
2721 struct sockaddr_storage addr;
2722 int rc = 0; 2742 int rc = 0;
2723 2743
2724 memset(&addr, 0, sizeof(struct sockaddr_storage));
2725
2726 spin_lock(&cifs_tcp_ses_lock); 2744 spin_lock(&cifs_tcp_ses_lock);
2727 cifs_sb = CIFS_SB(sb); 2745 cifs_sb = CIFS_SB(sb);
2728 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); 2746 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
@@ -2736,17 +2754,7 @@ cifs_match_super(struct super_block *sb, void *data)
2736 2754
2737 volume_info = mnt_data->vol; 2755 volume_info = mnt_data->vol;
2738 2756
2739 if (!volume_info->UNCip || !volume_info->UNC) 2757 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) || 2758 !match_session(ses, volume_info) ||
2751 !match_tcon(tcon, volume_info->UNC)) { 2759 !match_tcon(tcon, volume_info->UNC)) {
2752 rc = 0; 2760 rc = 0;
@@ -3261,8 +3269,6 @@ cleanup_volume_info_contents(struct smb_vol *volume_info)
3261{ 3269{
3262 kfree(volume_info->username); 3270 kfree(volume_info->username);
3263 kzfree(volume_info->password); 3271 kzfree(volume_info->password);
3264 if (volume_info->UNCip != volume_info->UNC + 2)
3265 kfree(volume_info->UNCip);
3266 kfree(volume_info->UNC); 3272 kfree(volume_info->UNC);
3267 kfree(volume_info->domainname); 3273 kfree(volume_info->domainname);
3268 kfree(volume_info->iocharset); 3274 kfree(volume_info->iocharset);
@@ -3280,14 +3286,16 @@ cifs_cleanup_volume_info(struct smb_vol *volume_info)
3280 3286
3281 3287
3282#ifdef CONFIG_CIFS_DFS_UPCALL 3288#ifdef CONFIG_CIFS_DFS_UPCALL
3283/* build_path_to_root returns full path to root when 3289/*
3284 * we do not have an exiting connection (tcon) */ 3290 * cifs_build_path_to_root returns full path to root when we do not have an
3291 * exiting connection (tcon)
3292 */
3285static char * 3293static char *
3286build_unc_path_to_root(const struct smb_vol *vol, 3294build_unc_path_to_root(const struct smb_vol *vol,
3287 const struct cifs_sb_info *cifs_sb) 3295 const struct cifs_sb_info *cifs_sb)
3288{ 3296{
3289 char *full_path, *pos; 3297 char *full_path, *pos;
3290 unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0; 3298 unsigned int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
3291 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); 3299 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
3292 3300
3293 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); 3301 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
@@ -3298,6 +3306,7 @@ build_unc_path_to_root(const struct smb_vol *vol,
3298 pos = full_path + unc_len; 3306 pos = full_path + unc_len;
3299 3307
3300 if (pplen) { 3308 if (pplen) {
3309 *pos++ = CIFS_DIR_SEP(cifs_sb);
3301 strncpy(pos, vol->prepath, pplen); 3310 strncpy(pos, vol->prepath, pplen);
3302 pos += pplen; 3311 pos += pplen;
3303 } 3312 }
@@ -3353,7 +3362,6 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
3353 mdata = NULL; 3362 mdata = NULL;
3354 } else { 3363 } else {
3355 cleanup_volume_info_contents(volume_info); 3364 cleanup_volume_info_contents(volume_info);
3356 memset(volume_info, '\0', sizeof(*volume_info));
3357 rc = cifs_setup_volume_info(volume_info, mdata, 3365 rc = cifs_setup_volume_info(volume_info, mdata,
3358 fake_devname); 3366 fake_devname);
3359 } 3367 }
@@ -3375,7 +3383,6 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
3375 if (cifs_parse_mount_options(mount_data, devname, volume_info)) 3383 if (cifs_parse_mount_options(mount_data, devname, volume_info))
3376 return -EINVAL; 3384 return -EINVAL;
3377 3385
3378
3379 if (volume_info->nullauth) { 3386 if (volume_info->nullauth) {
3380 cFYI(1, "Anonymous login"); 3387 cFYI(1, "Anonymous login");
3381 kfree(volume_info->username); 3388 kfree(volume_info->username);
@@ -3412,7 +3419,7 @@ cifs_get_volume_info(char *mount_data, const char *devname)
3412 int rc; 3419 int rc;
3413 struct smb_vol *volume_info; 3420 struct smb_vol *volume_info;
3414 3421
3415 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); 3422 volume_info = kmalloc(sizeof(struct smb_vol), GFP_KERNEL);
3416 if (!volume_info) 3423 if (!volume_info)
3417 return ERR_PTR(-ENOMEM); 3424 return ERR_PTR(-ENOMEM);
3418 3425
@@ -3537,8 +3544,10 @@ remote_path_check:
3537 rc = -ENOSYS; 3544 rc = -ENOSYS;
3538 goto mount_fail_check; 3545 goto mount_fail_check;
3539 } 3546 }
3540 /* build_path_to_root works only when we have a valid tcon */ 3547 /*
3541 full_path = build_path_to_root(volume_info, cifs_sb, tcon); 3548 * cifs_build_path_to_root works only when we have a valid tcon
3549 */
3550 full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
3542 if (full_path == NULL) { 3551 if (full_path == NULL) {
3543 rc = -ENOMEM; 3552 rc = -ENOMEM;
3544 goto mount_fail_check; 3553 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..8ea6ca50a665 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -238,6 +238,23 @@ out:
238 return rc; 238 return rc;
239} 239}
240 240
241static bool
242cifs_has_mand_locks(struct cifsInodeInfo *cinode)
243{
244 struct cifs_fid_locks *cur;
245 bool has_locks = false;
246
247 down_read(&cinode->lock_sem);
248 list_for_each_entry(cur, &cinode->llist, llist) {
249 if (!list_empty(&cur->locks)) {
250 has_locks = true;
251 break;
252 }
253 }
254 up_read(&cinode->lock_sem);
255 return has_locks;
256}
257
241struct cifsFileInfo * 258struct cifsFileInfo *
242cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, 259cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
243 struct tcon_link *tlink, __u32 oplock) 260 struct tcon_link *tlink, __u32 oplock)
@@ -248,6 +265,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
248 struct cifsFileInfo *cfile; 265 struct cifsFileInfo *cfile;
249 struct cifs_fid_locks *fdlocks; 266 struct cifs_fid_locks *fdlocks;
250 struct cifs_tcon *tcon = tlink_tcon(tlink); 267 struct cifs_tcon *tcon = tlink_tcon(tlink);
268 struct TCP_Server_Info *server = tcon->ses->server;
251 269
252 cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 270 cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
253 if (cfile == NULL) 271 if (cfile == NULL)
@@ -276,12 +294,22 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
276 INIT_WORK(&cfile->oplock_break, cifs_oplock_break); 294 INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
277 mutex_init(&cfile->fh_mutex); 295 mutex_init(&cfile->fh_mutex);
278 296
297 /*
298 * If the server returned a read oplock and we have mandatory brlocks,
299 * set oplock level to None.
300 */
301 if (oplock == server->vals->oplock_read &&
302 cifs_has_mand_locks(cinode)) {
303 cFYI(1, "Reset oplock val from read to None due to mand locks");
304 oplock = 0;
305 }
306
279 spin_lock(&cifs_file_list_lock); 307 spin_lock(&cifs_file_list_lock);
280 if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE) 308 if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock)
281 oplock = fid->pending_open->oplock; 309 oplock = fid->pending_open->oplock;
282 list_del(&fid->pending_open->olist); 310 list_del(&fid->pending_open->olist);
283 311
284 tlink_tcon(tlink)->ses->server->ops->set_fid(cfile, fid, oplock); 312 server->ops->set_fid(cfile, fid, oplock);
285 313
286 list_add(&cfile->tlist, &tcon->openFileList); 314 list_add(&cfile->tlist, &tcon->openFileList);
287 /* if readable file instance put first in list*/ 315 /* if readable file instance put first in list*/
@@ -505,16 +533,36 @@ out:
505 return rc; 533 return rc;
506} 534}
507 535
536static int cifs_push_posix_locks(struct cifsFileInfo *cfile);
537
508/* 538/*
509 * Try to reacquire byte range locks that were released when session 539 * Try to reacquire byte range locks that were released when session
510 * to server was lost 540 * to server was lost.
511 */ 541 */
512static int cifs_relock_file(struct cifsFileInfo *cifsFile) 542static int
543cifs_relock_file(struct cifsFileInfo *cfile)
513{ 544{
545 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
546 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
547 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
514 int rc = 0; 548 int rc = 0;
515 549
516 /* BB list all locks open on this file and relock */ 550 /* we are going to update can_cache_brlcks here - need a write access */
551 down_write(&cinode->lock_sem);
552 if (cinode->can_cache_brlcks) {
553 /* can cache locks - no need to push them */
554 up_write(&cinode->lock_sem);
555 return rc;
556 }
557
558 if (cap_unix(tcon->ses) &&
559 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
560 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
561 rc = cifs_push_posix_locks(cfile);
562 else
563 rc = tcon->ses->server->ops->push_mand_locks(cfile);
517 564
565 up_write(&cinode->lock_sem);
518 return rc; 566 return rc;
519} 567}
520 568
@@ -739,10 +787,15 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock)
739 } 787 }
740} 788}
741 789
790#define CIFS_LOCK_OP 0
791#define CIFS_READ_OP 1
792#define CIFS_WRITE_OP 2
793
794/* @rw_check : 0 - no op, 1 - read, 2 - write */
742static bool 795static bool
743cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, 796cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
744 __u64 length, __u8 type, struct cifsFileInfo *cfile, 797 __u64 length, __u8 type, struct cifsFileInfo *cfile,
745 struct cifsLockInfo **conf_lock, bool rw_check) 798 struct cifsLockInfo **conf_lock, int rw_check)
746{ 799{
747 struct cifsLockInfo *li; 800 struct cifsLockInfo *li;
748 struct cifsFileInfo *cur_cfile = fdlocks->cfile; 801 struct cifsFileInfo *cur_cfile = fdlocks->cfile;
@@ -752,9 +805,13 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
752 if (offset + length <= li->offset || 805 if (offset + length <= li->offset ||
753 offset >= li->offset + li->length) 806 offset >= li->offset + li->length)
754 continue; 807 continue;
755 if (rw_check && server->ops->compare_fids(cfile, cur_cfile) && 808 if (rw_check != CIFS_LOCK_OP && current->tgid == li->pid &&
756 current->tgid == li->pid) 809 server->ops->compare_fids(cfile, cur_cfile)) {
757 continue; 810 /* shared lock prevents write op through the same fid */
811 if (!(li->type & server->vals->shared_lock_type) ||
812 rw_check != CIFS_WRITE_OP)
813 continue;
814 }
758 if ((type & server->vals->shared_lock_type) && 815 if ((type & server->vals->shared_lock_type) &&
759 ((server->ops->compare_fids(cfile, cur_cfile) && 816 ((server->ops->compare_fids(cfile, cur_cfile) &&
760 current->tgid == li->pid) || type == li->type)) 817 current->tgid == li->pid) || type == li->type))
@@ -769,7 +826,7 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
769bool 826bool
770cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length, 827cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
771 __u8 type, struct cifsLockInfo **conf_lock, 828 __u8 type, struct cifsLockInfo **conf_lock,
772 bool rw_check) 829 int rw_check)
773{ 830{
774 bool rc = false; 831 bool rc = false;
775 struct cifs_fid_locks *cur; 832 struct cifs_fid_locks *cur;
@@ -805,7 +862,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
805 down_read(&cinode->lock_sem); 862 down_read(&cinode->lock_sem);
806 863
807 exist = cifs_find_lock_conflict(cfile, offset, length, type, 864 exist = cifs_find_lock_conflict(cfile, offset, length, type,
808 &conf_lock, false); 865 &conf_lock, CIFS_LOCK_OP);
809 if (exist) { 866 if (exist) {
810 flock->fl_start = conf_lock->offset; 867 flock->fl_start = conf_lock->offset;
811 flock->fl_end = conf_lock->offset + conf_lock->length - 1; 868 flock->fl_end = conf_lock->offset + conf_lock->length - 1;
@@ -852,7 +909,7 @@ try_again:
852 down_write(&cinode->lock_sem); 909 down_write(&cinode->lock_sem);
853 910
854 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, 911 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length,
855 lock->type, &conf_lock, false); 912 lock->type, &conf_lock, CIFS_LOCK_OP);
856 if (!exist && cinode->can_cache_brlcks) { 913 if (!exist && cinode->can_cache_brlcks) {
857 list_add_tail(&lock->llist, &cfile->llist->locks); 914 list_add_tail(&lock->llist, &cfile->llist->locks);
858 up_write(&cinode->lock_sem); 915 up_write(&cinode->lock_sem);
@@ -948,7 +1005,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
948 int rc = 0, stored_rc; 1005 int rc = 0, stored_rc;
949 struct cifsLockInfo *li, *tmp; 1006 struct cifsLockInfo *li, *tmp;
950 struct cifs_tcon *tcon; 1007 struct cifs_tcon *tcon;
951 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
952 unsigned int num, max_num, max_buf; 1008 unsigned int num, max_num, max_buf;
953 LOCKING_ANDX_RANGE *buf, *cur; 1009 LOCKING_ANDX_RANGE *buf, *cur;
954 int types[] = {LOCKING_ANDX_LARGE_FILES, 1010 int types[] = {LOCKING_ANDX_LARGE_FILES,
@@ -958,21 +1014,12 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
958 xid = get_xid(); 1014 xid = get_xid();
959 tcon = tlink_tcon(cfile->tlink); 1015 tcon = tlink_tcon(cfile->tlink);
960 1016
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 /* 1017 /*
970 * Accessing maxBuf is racy with cifs_reconnect - need to store value 1018 * Accessing maxBuf is racy with cifs_reconnect - need to store value
971 * and check it for zero before using. 1019 * and check it for zero before using.
972 */ 1020 */
973 max_buf = tcon->ses->server->maxBuf; 1021 max_buf = tcon->ses->server->maxBuf;
974 if (!max_buf) { 1022 if (!max_buf) {
975 up_write(&cinode->lock_sem);
976 free_xid(xid); 1023 free_xid(xid);
977 return -EINVAL; 1024 return -EINVAL;
978 } 1025 }
@@ -981,7 +1028,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
981 sizeof(LOCKING_ANDX_RANGE); 1028 sizeof(LOCKING_ANDX_RANGE);
982 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 1029 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
983 if (!buf) { 1030 if (!buf) {
984 up_write(&cinode->lock_sem);
985 free_xid(xid); 1031 free_xid(xid);
986 return -ENOMEM; 1032 return -ENOMEM;
987 } 1033 }
@@ -1018,9 +1064,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
1018 } 1064 }
1019 } 1065 }
1020 1066
1021 cinode->can_cache_brlcks = false;
1022 up_write(&cinode->lock_sem);
1023
1024 kfree(buf); 1067 kfree(buf);
1025 free_xid(xid); 1068 free_xid(xid);
1026 return rc; 1069 return rc;
@@ -1043,7 +1086,6 @@ struct lock_to_push {
1043static int 1086static int
1044cifs_push_posix_locks(struct cifsFileInfo *cfile) 1087cifs_push_posix_locks(struct cifsFileInfo *cfile)
1045{ 1088{
1046 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
1047 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1089 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1048 struct file_lock *flock, **before; 1090 struct file_lock *flock, **before;
1049 unsigned int count = 0, i = 0; 1091 unsigned int count = 0, i = 0;
@@ -1054,14 +1096,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1054 1096
1055 xid = get_xid(); 1097 xid = get_xid();
1056 1098
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(); 1099 lock_flocks();
1066 cifs_for_each_lock(cfile->dentry->d_inode, before) { 1100 cifs_for_each_lock(cfile->dentry->d_inode, before) {
1067 if ((*before)->fl_flags & FL_POSIX) 1101 if ((*before)->fl_flags & FL_POSIX)
@@ -1127,9 +1161,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
1127 } 1161 }
1128 1162
1129out: 1163out:
1130 cinode->can_cache_brlcks = false;
1131 up_write(&cinode->lock_sem);
1132
1133 free_xid(xid); 1164 free_xid(xid);
1134 return rc; 1165 return rc;
1135err_out: 1166err_out:
@@ -1144,14 +1175,27 @@ static int
1144cifs_push_locks(struct cifsFileInfo *cfile) 1175cifs_push_locks(struct cifsFileInfo *cfile)
1145{ 1176{
1146 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); 1177 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
1178 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
1147 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1179 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1180 int rc = 0;
1181
1182 /* we are going to update can_cache_brlcks here - need a write access */
1183 down_write(&cinode->lock_sem);
1184 if (!cinode->can_cache_brlcks) {
1185 up_write(&cinode->lock_sem);
1186 return rc;
1187 }
1148 1188
1149 if (cap_unix(tcon->ses) && 1189 if (cap_unix(tcon->ses) &&
1150 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && 1190 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
1151 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) 1191 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
1152 return cifs_push_posix_locks(cfile); 1192 rc = cifs_push_posix_locks(cfile);
1193 else
1194 rc = tcon->ses->server->ops->push_mand_locks(cfile);
1153 1195
1154 return tcon->ses->server->ops->push_mand_locks(cfile); 1196 cinode->can_cache_brlcks = false;
1197 up_write(&cinode->lock_sem);
1198 return rc;
1155} 1199}
1156 1200
1157static void 1201static void
@@ -1406,6 +1450,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1406 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1450 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
1407 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1451 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1408 struct TCP_Server_Info *server = tcon->ses->server; 1452 struct TCP_Server_Info *server = tcon->ses->server;
1453 struct inode *inode = cfile->dentry->d_inode;
1409 1454
1410 if (posix_lck) { 1455 if (posix_lck) {
1411 int posix_lock_type; 1456 int posix_lock_type;
@@ -1436,16 +1481,33 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1436 return -ENOMEM; 1481 return -ENOMEM;
1437 1482
1438 rc = cifs_lock_add_if(cfile, lock, wait_flag); 1483 rc = cifs_lock_add_if(cfile, lock, wait_flag);
1439 if (rc < 0) 1484 if (rc < 0) {
1440 kfree(lock); 1485 kfree(lock);
1441 if (rc <= 0) 1486 return rc;
1487 }
1488 if (!rc)
1442 goto out; 1489 goto out;
1443 1490
1491 /*
1492 * Windows 7 server can delay breaking lease from read to None
1493 * if we set a byte-range lock on a file - break it explicitly
1494 * before sending the lock to the server to be sure the next
1495 * read won't conflict with non-overlapted locks due to
1496 * pagereading.
1497 */
1498 if (!CIFS_I(inode)->clientCanCacheAll &&
1499 CIFS_I(inode)->clientCanCacheRead) {
1500 cifs_invalidate_mapping(inode);
1501 cFYI(1, "Set no oplock for inode=%p due to mand locks",
1502 inode);
1503 CIFS_I(inode)->clientCanCacheRead = false;
1504 }
1505
1444 rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, 1506 rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length,
1445 type, 1, 0, wait_flag); 1507 type, 1, 0, wait_flag);
1446 if (rc) { 1508 if (rc) {
1447 kfree(lock); 1509 kfree(lock);
1448 goto out; 1510 return rc;
1449 } 1511 }
1450 1512
1451 cifs_lock_add(cfile, lock); 1513 cifs_lock_add(cfile, lock);
@@ -1794,7 +1856,6 @@ static int cifs_writepages(struct address_space *mapping,
1794 struct TCP_Server_Info *server; 1856 struct TCP_Server_Info *server;
1795 struct page *page; 1857 struct page *page;
1796 int rc = 0; 1858 int rc = 0;
1797 loff_t isize = i_size_read(mapping->host);
1798 1859
1799 /* 1860 /*
1800 * If wsize is smaller than the page cache size, default to writing 1861 * If wsize is smaller than the page cache size, default to writing
@@ -1899,7 +1960,7 @@ retry:
1899 */ 1960 */
1900 set_page_writeback(page); 1961 set_page_writeback(page);
1901 1962
1902 if (page_offset(page) >= isize) { 1963 if (page_offset(page) >= i_size_read(mapping->host)) {
1903 done = true; 1964 done = true;
1904 unlock_page(page); 1965 unlock_page(page);
1905 end_page_writeback(page); 1966 end_page_writeback(page);
@@ -1932,7 +1993,8 @@ retry:
1932 wdata->offset = page_offset(wdata->pages[0]); 1993 wdata->offset = page_offset(wdata->pages[0]);
1933 wdata->pagesz = PAGE_CACHE_SIZE; 1994 wdata->pagesz = PAGE_CACHE_SIZE;
1934 wdata->tailsz = 1995 wdata->tailsz =
1935 min(isize - page_offset(wdata->pages[nr_pages - 1]), 1996 min(i_size_read(mapping->host) -
1997 page_offset(wdata->pages[nr_pages - 1]),
1936 (loff_t)PAGE_CACHE_SIZE); 1998 (loff_t)PAGE_CACHE_SIZE);
1937 wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + 1999 wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) +
1938 wdata->tailsz; 2000 wdata->tailsz;
@@ -2457,7 +2519,7 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
2457 down_read(&cinode->lock_sem); 2519 down_read(&cinode->lock_sem);
2458 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), 2520 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs),
2459 server->vals->exclusive_lock_type, NULL, 2521 server->vals->exclusive_lock_type, NULL,
2460 true)) { 2522 CIFS_WRITE_OP)) {
2461 mutex_lock(&inode->i_mutex); 2523 mutex_lock(&inode->i_mutex);
2462 rc = __generic_file_aio_write(iocb, iov, nr_segs, 2524 rc = __generic_file_aio_write(iocb, iov, nr_segs,
2463 &iocb->ki_pos); 2525 &iocb->ki_pos);
@@ -2487,42 +2549,34 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
2487 struct cifsFileInfo *cfile = (struct cifsFileInfo *) 2549 struct cifsFileInfo *cfile = (struct cifsFileInfo *)
2488 iocb->ki_filp->private_data; 2550 iocb->ki_filp->private_data;
2489 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 2551 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
2552 ssize_t written;
2490 2553
2491#ifdef CONFIG_CIFS_SMB2 2554 if (cinode->clientCanCacheAll) {
2492 /* 2555 if (cap_unix(tcon->ses) &&
2493 * If we have an oplock for read and want to write a data to the file 2556 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
2494 * we need to store it in the page cache and then push it to the server 2557 && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
2495 * to be sure the next read will get a valid data. 2558 return generic_file_aio_write(iocb, iov, nr_segs, pos);
2496 */ 2559 return cifs_writev(iocb, iov, nr_segs, pos);
2497 if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead) {
2498 ssize_t written;
2499 int rc;
2500
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
2506 return written;
2507 } 2560 }
2508#endif
2509
2510 /* 2561 /*
2511 * For non-oplocked files in strict cache mode we need to write the data 2562 * For non-oplocked files in strict cache mode we need to write the data
2512 * to the server exactly from the pos to pos+len-1 rather than flush all 2563 * to the server exactly from the pos to pos+len-1 rather than flush all
2513 * affected pages because it may cause a error with mandatory locks on 2564 * affected pages because it may cause a error with mandatory locks on
2514 * these pages but not on the region from pos to ppos+len-1. 2565 * these pages but not on the region from pos to ppos+len-1.
2515 */ 2566 */
2516 2567 written = cifs_user_writev(iocb, iov, nr_segs, pos);
2517 if (!cinode->clientCanCacheAll) 2568 if (written > 0 && cinode->clientCanCacheRead) {
2518 return cifs_user_writev(iocb, iov, nr_segs, pos); 2569 /*
2519 2570 * Windows 7 server can delay breaking level2 oplock if a write
2520 if (cap_unix(tcon->ses) && 2571 * request comes - break it on the client to prevent reading
2521 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && 2572 * an old data.
2522 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) 2573 */
2523 return generic_file_aio_write(iocb, iov, nr_segs, pos); 2574 cifs_invalidate_mapping(inode);
2524 2575 cFYI(1, "Set no oplock for inode=%p after a write operation",
2525 return cifs_writev(iocb, iov, nr_segs, pos); 2576 inode);
2577 cinode->clientCanCacheRead = false;
2578 }
2579 return written;
2526} 2580}
2527 2581
2528static struct cifs_readdata * 2582static struct cifs_readdata *
@@ -2892,7 +2946,7 @@ cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
2892 down_read(&cinode->lock_sem); 2946 down_read(&cinode->lock_sem);
2893 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), 2947 if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs),
2894 tcon->ses->server->vals->shared_lock_type, 2948 tcon->ses->server->vals->shared_lock_type,
2895 NULL, true)) 2949 NULL, CIFS_READ_OP))
2896 rc = generic_file_aio_read(iocb, iov, nr_segs, pos); 2950 rc = generic_file_aio_read(iocb, iov, nr_segs, pos);
2897 up_read(&cinode->lock_sem); 2951 up_read(&cinode->lock_sem);
2898 return rc; 2952 return rc;
@@ -3527,6 +3581,13 @@ void cifs_oplock_break(struct work_struct *work)
3527 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 3581 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
3528 int rc = 0; 3582 int rc = 0;
3529 3583
3584 if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead &&
3585 cifs_has_mand_locks(cinode)) {
3586 cFYI(1, "Reset oplock to None for inode=%p due to mand locks",
3587 inode);
3588 cinode->clientCanCacheRead = false;
3589 }
3590
3530 if (inode && S_ISREG(inode->i_mode)) { 3591 if (inode && S_ISREG(inode->i_mode)) {
3531 if (cinode->clientCanCacheRead) 3592 if (cinode->clientCanCacheRead)
3532 break_lease(inode, O_RDONLY); 3593 break_lease(inode, O_RDONLY);
@@ -3536,7 +3597,7 @@ void cifs_oplock_break(struct work_struct *work)
3536 if (cinode->clientCanCacheRead == 0) { 3597 if (cinode->clientCanCacheRead == 0) {
3537 rc = filemap_fdatawait(inode->i_mapping); 3598 rc = filemap_fdatawait(inode->i_mapping);
3538 mapping_set_error(inode->i_mapping, rc); 3599 mapping_set_error(inode->i_mapping, rc);
3539 invalidate_remote_inode(inode); 3600 cifs_invalidate_mapping(inode);
3540 } 3601 }
3541 cFYI(1, "Oplock flush inode %p rc %d", inode, rc); 3602 cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
3542 } 3603 }
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..cdd6ff48246b 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -66,18 +66,21 @@ 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;
81 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
79 82
80 cFYI(1, "For %s", name->name); 83 cFYI(1, "%s: for %s", __func__, name->name);
81 84
82 if (parent->d_op && parent->d_op->d_hash) 85 if (parent->d_op && parent->d_op->d_hash)
83 parent->d_op->d_hash(parent, parent->d_inode, name); 86 parent->d_op->d_hash(parent, parent->d_inode, name);
@@ -86,35 +89,43 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
86 89
87 dentry = d_lookup(parent, name); 90 dentry = d_lookup(parent, name);
88 if (dentry) { 91 if (dentry) {
92 int err;
93
89 inode = dentry->d_inode; 94 inode = dentry->d_inode;
90 /* update inode in place if i_ino didn't change */ 95 if (inode) {
91 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { 96 /*
92 cifs_fattr_to_inode(inode, fattr); 97 * If we're generating inode numbers, then we don't
93 return dentry; 98 * want to clobber the existing one with the one that
99 * the readdir code created.
100 */
101 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
102 fattr->cf_uniqueid = CIFS_I(inode)->uniqueid;
103
104 /* update inode in place if i_ino didn't change */
105 if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
106 cifs_fattr_to_inode(inode, fattr);
107 goto out;
108 }
94 } 109 }
95 d_drop(dentry); 110 err = d_invalidate(dentry);
96 dput(dentry); 111 dput(dentry);
112 if (err)
113 return;
97 } 114 }
98 115
99 dentry = d_alloc(parent, name); 116 dentry = d_alloc(parent, name);
100 if (dentry == NULL) 117 if (!dentry)
101 return NULL; 118 return;
102 119
103 inode = cifs_iget(sb, fattr); 120 inode = cifs_iget(sb, fattr);
104 if (!inode) { 121 if (!inode)
105 dput(dentry); 122 goto out;
106 return NULL;
107 }
108 123
109 alias = d_materialise_unique(dentry, inode); 124 alias = d_materialise_unique(dentry, inode);
110 if (alias != NULL) { 125 if (alias && !IS_ERR(alias))
111 dput(dentry); 126 dput(alias);
112 if (IS_ERR(alias)) 127out:
113 return NULL; 128 dput(dentry);
114 dentry = alias;
115 }
116
117 return dentry;
118} 129}
119 130
120static void 131static void
@@ -134,6 +145,16 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
134 if (fattr->cf_cifsattrs & ATTR_READONLY) 145 if (fattr->cf_cifsattrs & ATTR_READONLY)
135 fattr->cf_mode &= ~S_IWUGO; 146 fattr->cf_mode &= ~S_IWUGO;
136 147
148 /*
149 * We of course don't get ACL info in FIND_FIRST/NEXT results, so
150 * mark it for revalidation so that "ls -l" will look right. It might
151 * be super-slow, but if we don't do this then the ownership of files
152 * may look wrong since the inodes may not have timed out by the time
153 * "ls" does a stat() call on them.
154 */
155 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
156 fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
157
137 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && 158 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
138 fattr->cf_cifsattrs & ATTR_SYSTEM) { 159 fattr->cf_cifsattrs & ATTR_SYSTEM) {
139 if (fattr->cf_eof == 0) { 160 if (fattr->cf_eof == 0) {
@@ -649,7 +670,6 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
649 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 670 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
650 struct cifs_dirent de = { NULL, }; 671 struct cifs_dirent de = { NULL, };
651 struct cifs_fattr fattr; 672 struct cifs_fattr fattr;
652 struct dentry *dentry;
653 struct qstr name; 673 struct qstr name;
654 int rc = 0; 674 int rc = 0;
655 ino_t ino; 675 ino_t ino;
@@ -720,13 +740,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
720 */ 740 */
721 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; 741 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
722 742
723 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 743 cifs_prime_dcache(file->f_dentry, &name, &fattr);
724 dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
725 744
745 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
726 rc = filldir(dirent, name.name, name.len, file->f_pos, ino, 746 rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
727 fattr.cf_dtype); 747 fattr.cf_dtype);
728
729 dput(dentry);
730 return rc; 748 return rc;
731} 749}
732 750
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 56cc4be87807..47bc5a87f94e 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -53,6 +53,13 @@ send_nt_cancel(struct TCP_Server_Info *server, void *buf,
53 mutex_unlock(&server->srv_mutex); 53 mutex_unlock(&server->srv_mutex);
54 return rc; 54 return rc;
55 } 55 }
56
57 /*
58 * The response to this call was already factored into the sequence
59 * number when the call went out, so we must adjust it back downward
60 * after signing here.
61 */
62 --server->sequence_number;
56 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); 63 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
57 mutex_unlock(&server->srv_mutex); 64 mutex_unlock(&server->srv_mutex);
58 65
@@ -575,37 +582,6 @@ cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
575 return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data); 582 return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data);
576} 583}
577 584
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 585static void
610cifs_clear_stats(struct cifs_tcon *tcon) 586cifs_clear_stats(struct cifs_tcon *tcon)
611{ 587{
@@ -766,7 +742,6 @@ smb_set_file_info(struct inode *inode, const char *full_path,
766 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 742 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
767 struct tcon_link *tlink = NULL; 743 struct tcon_link *tlink = NULL;
768 struct cifs_tcon *tcon; 744 struct cifs_tcon *tcon;
769 FILE_BASIC_INFO info_buf;
770 745
771 /* if the file is already open for write, just use that fileid */ 746 /* if the file is already open for write, just use that fileid */
772 open_file = find_writable_file(cinode, true); 747 open_file = find_writable_file(cinode, true);
@@ -817,7 +792,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
817 netpid = current->tgid; 792 netpid = current->tgid;
818 793
819set_via_filehandle: 794set_via_filehandle:
820 rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid); 795 rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid);
821 if (!rc) 796 if (!rc)
822 cinode->cifsAttrs = le32_to_cpu(buf->Attributes); 797 cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
823 798
@@ -944,7 +919,6 @@ struct smb_version_operations smb1_operations = {
944 .set_path_size = CIFSSMBSetEOF, 919 .set_path_size = CIFSSMBSetEOF,
945 .set_file_size = CIFSSMBSetFileSize, 920 .set_file_size = CIFSSMBSetFileSize,
946 .set_file_info = smb_set_file_info, 921 .set_file_info = smb_set_file_info,
947 .build_path_to_root = cifs_build_path_to_root,
948 .echo = CIFSSMBEcho, 922 .echo = CIFSSMBEcho,
949 .mkdir = CIFSSMBMkDir, 923 .mkdir = CIFSSMBMkDir,
950 .mkdir_setinfo = cifs_mkdir_setinfo, 924 .mkdir_setinfo = cifs_mkdir_setinfo,
@@ -985,4 +959,5 @@ struct smb_version_values smb1_values = {
985 .cap_unix = CAP_UNIX, 959 .cap_unix = CAP_UNIX,
986 .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND, 960 .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND,
987 .cap_large_files = CAP_LARGE_FILES, 961 .cap_large_files = CAP_LARGE_FILES,
962 .oplock_read = OPLOCK_READ,
988}; 963};
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..c9c7aa7ed966 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,92 @@ 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,
711 .oplock_read = SMB2_OPLOCK_LEVEL_II,
644}; 712};
645 713
646struct smb_version_values smb21_values = { 714struct smb_version_values smb21_values = {
@@ -658,6 +726,7 @@ struct smb_version_values smb21_values = {
658 .cap_unix = 0, 726 .cap_unix = 0,
659 .cap_nt_find = SMB2_NT_FIND, 727 .cap_nt_find = SMB2_NT_FIND,
660 .cap_large_files = SMB2_LARGE_FILES, 728 .cap_large_files = SMB2_LARGE_FILES,
729 .oplock_read = SMB2_OPLOCK_LEVEL_II,
661}; 730};
662 731
663struct smb_version_values smb30_values = { 732struct smb_version_values smb30_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)
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 76d974c952fe..1a528680ec5a 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -144,9 +144,6 @@ smb_send_kvec(struct TCP_Server_Info *server, struct kvec *iov, size_t n_vec,
144 144
145 *sent = 0; 145 *sent = 0;
146 146
147 if (ssocket == NULL)
148 return -ENOTSOCK; /* BB eventually add reconnect code here */
149
150 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr; 147 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
151 smb_msg.msg_namelen = sizeof(struct sockaddr); 148 smb_msg.msg_namelen = sizeof(struct sockaddr);
152 smb_msg.msg_control = NULL; 149 smb_msg.msg_control = NULL;
@@ -291,6 +288,9 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
291 struct socket *ssocket = server->ssocket; 288 struct socket *ssocket = server->ssocket;
292 int val = 1; 289 int val = 1;
293 290
291 if (ssocket == NULL)
292 return -ENOTSOCK;
293
294 cFYI(1, "Sending smb: smb_len=%u", smb_buf_length); 294 cFYI(1, "Sending smb: smb_len=%u", smb_buf_length);
295 dump_smb(iov[0].iov_base, iov[0].iov_len); 295 dump_smb(iov[0].iov_base, iov[0].iov_len);
296 296