Blame view

fs/cifs/misc.c 21.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   *   fs/cifs/misc.c
   *
ad7a2926b   Steve French   [CIFS] reduce che...
4
   *   Copyright (C) International Business Machines  Corp., 2002,2008
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   This library is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Lesser General Public License as published
   *   by the Free Software Foundation; either version 2.1 of the License, or
   *   (at your option) any later version.
   *
   *   This library is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   *   the GNU Lesser General Public License for more details.
   *
   *   You should have received a copy of the GNU Lesser General Public License
   *   along with this library; if not, write to the Free Software
fb8c4b14d   Steve French   [CIFS] whitespace...
19
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
23
24
25
26
27
28
29
30
   */
  
  #include <linux/slab.h>
  #include <linux/ctype.h>
  #include <linux/mempool.h>
  #include "cifspdu.h"
  #include "cifsglob.h"
  #include "cifsproto.h"
  #include "cifs_debug.h"
  #include "smberr.h"
  #include "nterr.h"
6c91d362f   Steve French   [PATCH] cifs: fin...
31
  #include "cifs_unicode.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
  
  extern mempool_t *cifs_sm_req_poolp;
  extern mempool_t *cifs_req_poolp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

fb8c4b14d   Steve French   [CIFS] whitespace...
36
37
38
39
  /* The xid serves as a useful identifier for each incoming vfs request,
     in a similar way to the mid which is useful to track each sent smb,
     and CurrentXid can also provide a running counter (although it
     will eventually wrap past zero) of the total vfs operations handled
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
44
45
46
47
48
     since the cifs fs was mounted */
  
  unsigned int
  _GetXid(void)
  {
  	unsigned int xid;
  
  	spin_lock(&GlobalMid_Lock);
  	GlobalTotalActiveXid++;
50c2f7538   Steve French   [CIFS] whitespace...
49
50
  
  	/* keep high water mark for number of simultaneous ops in filesystem */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  	if (GlobalTotalActiveXid > GlobalMaxActiveXid)
50c2f7538   Steve French   [CIFS] whitespace...
52
  		GlobalMaxActiveXid = GlobalTotalActiveXid;
790fe579f   Steve French   [CIFS] more white...
53
  	if (GlobalTotalActiveXid > 65000)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
54
  		cFYI(1, "warning: more than 65000 requests active");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
62
63
  	xid = GlobalCurrentXid++;
  	spin_unlock(&GlobalMid_Lock);
  	return xid;
  }
  
  void
  _FreeXid(unsigned int xid)
  {
  	spin_lock(&GlobalMid_Lock);
790fe579f   Steve French   [CIFS] more white...
64
  	/* if (GlobalTotalActiveXid == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
68
69
70
71
72
73
  		BUG(); */
  	GlobalTotalActiveXid--;
  	spin_unlock(&GlobalMid_Lock);
  }
  
  struct cifsSesInfo *
  sesInfoAlloc(void)
  {
  	struct cifsSesInfo *ret_buf;
630f3f0c4   Steve French   [CIFS] acl suppor...
74
  	ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  	if (ret_buf) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
  		atomic_inc(&sesInfoAllocCount);
  		ret_buf->status = CifsNew;
14fbf50d6   Jeff Layton   cifs: reinstate s...
78
79
  		++ret_buf->ses_count;
  		INIT_LIST_HEAD(&ret_buf->smb_ses_list);
f1987b44f   Jeff Layton   cifs: reinstate s...
80
  		INIT_LIST_HEAD(&ret_buf->tcon_list);
d7b619cf5   Steve French   [CIFS] pSesInfo->...
81
  		mutex_init(&ret_buf->session_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
84
85
86
87
88
89
  	}
  	return ret_buf;
  }
  
  void
  sesInfoFree(struct cifsSesInfo *buf_to_free)
  {
  	if (buf_to_free == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
90
  		cFYI(1, "Null buffer passed to sesInfoFree");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
  		return;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  	atomic_dec(&sesInfoAllocCount);
f99d49adf   Jesper Juhl   [PATCH] kfree cle...
94
95
96
  	kfree(buf_to_free->serverOS);
  	kfree(buf_to_free->serverDomain);
  	kfree(buf_to_free->serverNOS);
55162dec9   Jeff Layton   cifs: zero out se...
97
98
99
100
  	if (buf_to_free->password) {
  		memset(buf_to_free->password, 0, strlen(buf_to_free->password));
  		kfree(buf_to_free->password);
  	}
3979877e5   Steve French   [CIFS] Support fo...
101
  	kfree(buf_to_free->domainName);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
106
107
108
  	kfree(buf_to_free);
  }
  
  struct cifsTconInfo *
  tconInfoAlloc(void)
  {
  	struct cifsTconInfo *ret_buf;
630f3f0c4   Steve French   [CIFS] acl suppor...
109
  	ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  	if (ret_buf) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  		atomic_inc(&tconInfoAllocCount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  		ret_buf->tidStatus = CifsNew;
f1987b44f   Jeff Layton   cifs: reinstate s...
113
  		++ret_buf->tc_count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  		INIT_LIST_HEAD(&ret_buf->openFileList);
f1987b44f   Jeff Layton   cifs: reinstate s...
115
  		INIT_LIST_HEAD(&ret_buf->tcon_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
  #ifdef CONFIG_CIFS_STATS
  		spin_lock_init(&ret_buf->stat_lock);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
123
124
125
126
  	}
  	return ret_buf;
  }
  
  void
  tconInfoFree(struct cifsTconInfo *buf_to_free)
  {
  	if (buf_to_free == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
127
  		cFYI(1, "Null buffer passed to tconInfoFree");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
  		return;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  	atomic_dec(&tconInfoAllocCount);
f99d49adf   Jesper Juhl   [PATCH] kfree cle...
131
  	kfree(buf_to_free->nativeFileSystem);
00e485b01   Jeff Layton   cifs: store passw...
132
133
134
135
  	if (buf_to_free->password) {
  		memset(buf_to_free->password, 0, strlen(buf_to_free->password));
  		kfree(buf_to_free->password);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
138
139
140
141
142
  	kfree(buf_to_free);
  }
  
  struct smb_hdr *
  cifs_buf_get(void)
  {
  	struct smb_hdr *ret_buf = NULL;
fb8c4b14d   Steve French   [CIFS] whitespace...
143
144
145
  /* We could use negotiated size instead of max_msgsize -
     but it may be more efficient to always alloc same size
     albeit slightly larger than necessary and maxbuffersize
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
     defaults to this and can not be bigger */
232087cb7   Pekka Enberg   cifs: don't use G...
147
  	ret_buf = mempool_alloc(cifs_req_poolp, GFP_NOFS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
150
151
152
153
  
  	/* clear the first few header bytes */
  	/* for most paths, more is cleared in header_assemble */
  	if (ret_buf) {
  		memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
  		atomic_inc(&bufAllocCount);
4498eed50   Steve French   [CIFS] Add extend...
154
155
156
  #ifdef CONFIG_CIFS_STATS2
  		atomic_inc(&totBufAllocCount);
  #endif /* CONFIG_CIFS_STATS2 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
160
161
162
163
164
  	}
  
  	return ret_buf;
  }
  
  void
  cifs_buf_release(void *buf_to_free)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  	if (buf_to_free == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
166
  		/* cFYI(1, "Null buffer passed to cifs_buf_release");*/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
  		return;
  	}
fb8c4b14d   Steve French   [CIFS] whitespace...
169
  	mempool_free(buf_to_free, cifs_req_poolp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
173
174
175
176
177
178
  
  	atomic_dec(&bufAllocCount);
  	return;
  }
  
  struct smb_hdr *
  cifs_small_buf_get(void)
  {
  	struct smb_hdr *ret_buf = NULL;
fb8c4b14d   Steve French   [CIFS] whitespace...
179
180
181
  /* We could use negotiated size instead of max_msgsize -
     but it may be more efficient to always alloc same size
     albeit slightly larger than necessary and maxbuffersize
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
     defaults to this and can not be bigger */
232087cb7   Pekka Enberg   cifs: don't use G...
183
  	ret_buf = mempool_alloc(cifs_sm_req_poolp, GFP_NOFS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
187
  	if (ret_buf) {
  	/* No need to clear memory here, cleared in header assemble */
  	/*	memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
  		atomic_inc(&smBufAllocCount);
4498eed50   Steve French   [CIFS] Add extend...
188
189
190
  #ifdef CONFIG_CIFS_STATS2
  		atomic_inc(&totSmBufAllocCount);
  #endif /* CONFIG_CIFS_STATS2 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
196
197
198
199
  	}
  	return ret_buf;
  }
  
  void
  cifs_small_buf_release(void *buf_to_free)
  {
  
  	if (buf_to_free == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
200
  		cFYI(1, "Null buffer passed to cifs_small_buf_release");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
  		return;
  	}
fb8c4b14d   Steve French   [CIFS] whitespace...
203
  	mempool_free(buf_to_free, cifs_sm_req_poolp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
  
  	atomic_dec(&smBufAllocCount);
  	return;
  }
fb8c4b14d   Steve French   [CIFS] whitespace...
208
  /*
1982c344f   Steve French   [CIFS] Ensure tha...
209
210
211
212
213
214
  	Find a free multiplex id (SMB mid). Otherwise there could be
  	mid collisions which might cause problems, demultiplexing the
  	wrong response to this request. Multiplex ids could collide if
  	one of a series requests takes much longer than the others, or
  	if a very large number of long lived requests (byte range
  	locks or FindNotify requests) are pending.  No more than
fb8c4b14d   Steve French   [CIFS] whitespace...
215
  	64K-1 requests can be outstanding at one time.  If no
1982c344f   Steve French   [CIFS] Ensure tha...
216
217
  	mids are available, return zero.  A future optimization
  	could make the combination of mids and uid the key we use
fb8c4b14d   Steve French   [CIFS] whitespace...
218
  	to demultiplex on (rather than mid alone).
1982c344f   Steve French   [CIFS] Ensure tha...
219
220
221
222
223
224
  	In addition to the above check, the cifs demultiplex
  	code already used the command code as a secondary
  	check of the frame and if signing is negotiated the
  	response would be discarded if the mid were the same
  	but the signature was wrong.  Since the mid is not put in the
  	pending queue until later (when it is about to be dispatched)
fb8c4b14d   Steve French   [CIFS] whitespace...
225
  	we do have to limit the number of outstanding requests
1982c344f   Steve French   [CIFS] Ensure tha...
226
227
228
229
230
231
232
  	to somewhat less than 64K-1 although it is hard to imagine
  	so many threads being in the vfs at one time.
  */
  __u16 GetNextMid(struct TCP_Server_Info *server)
  {
  	__u16 mid = 0;
  	__u16 last_mid;
fb8c4b14d   Steve French   [CIFS] whitespace...
233
  	int   collision;
1982c344f   Steve French   [CIFS] Ensure tha...
234

790fe579f   Steve French   [CIFS] more white...
235
  	if (server == NULL)
1982c344f   Steve French   [CIFS] Ensure tha...
236
237
238
239
240
241
  		return mid;
  
  	spin_lock(&GlobalMid_Lock);
  	last_mid = server->CurrentMid; /* we do not want to loop forever */
  	server->CurrentMid++;
  	/* This nested loop looks more expensive than it is.
fb8c4b14d   Steve French   [CIFS] whitespace...
242
  	In practice the list of pending requests is short,
1982c344f   Steve French   [CIFS] Ensure tha...
243
244
245
246
247
  	fewer than 50, and the mids are likely to be unique
  	on the first pass through the loop unless some request
  	takes longer than the 64 thousand requests before it
  	(and it would also have to have been a request that
  	 did not time out) */
fb8c4b14d   Steve French   [CIFS] whitespace...
248
  	while (server->CurrentMid != last_mid) {
1982c344f   Steve French   [CIFS] Ensure tha...
249
250
251
252
  		struct list_head *tmp;
  		struct mid_q_entry *mid_entry;
  
  		collision = 0;
790fe579f   Steve French   [CIFS] more white...
253
  		if (server->CurrentMid == 0)
1982c344f   Steve French   [CIFS] Ensure tha...
254
255
256
257
258
259
260
261
262
263
264
265
  			server->CurrentMid++;
  
  		list_for_each(tmp, &server->pending_mid_q) {
  			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
  
  			if ((mid_entry->mid == server->CurrentMid) &&
  			    (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
  				/* This mid is in use, try a different one */
  				collision = 1;
  				break;
  			}
  		}
790fe579f   Steve French   [CIFS] more white...
266
  		if (collision == 0) {
1982c344f   Steve French   [CIFS] Ensure tha...
267
268
269
270
271
272
273
274
275
276
277
  			mid = server->CurrentMid;
  			break;
  		}
  		server->CurrentMid++;
  	}
  	spin_unlock(&GlobalMid_Lock);
  	return mid;
  }
  
  /* NB: MID can not be set if treeCon not passed in, in that
     case it is responsbility of caller to set the mid */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
279
280
281
282
  void
  header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
  		const struct cifsTconInfo *treeCon, int word_count
  		/* length of fixed section (word count) in two byte units  */)
  {
fb8c4b14d   Steve French   [CIFS] whitespace...
283
284
  	struct list_head *temp_item;
  	struct cifsSesInfo *ses;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
  	char *temp = (char *) buffer;
fb8c4b14d   Steve French   [CIFS] whitespace...
286
  	memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
  
  	buffer->smb_buf_length =
630f3f0c4   Steve French   [CIFS] acl suppor...
289
  	    (2 * word_count) + sizeof(struct smb_hdr) -
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
  	    4 /*  RFC 1001 length field does not count */  +
  	    2 /* for bcc field itself */ ;
1982c344f   Steve French   [CIFS] Ensure tha...
292
293
  	/* Note that this is the only network field that has to be converted
  	   to big endian and it is done just before we send it */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
297
298
299
300
301
302
303
  
  	buffer->Protocol[0] = 0xFF;
  	buffer->Protocol[1] = 'S';
  	buffer->Protocol[2] = 'M';
  	buffer->Protocol[3] = 'B';
  	buffer->Command = smb_command;
  	buffer->Flags = 0x00;	/* case sensitive */
  	buffer->Flags2 = SMBFLG2_KNOWS_LONG_NAMES;
  	buffer->Pid = cpu_to_le16((__u16)current->tgid);
  	buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
  	if (treeCon) {
  		buffer->Tid = treeCon->tid;
  		if (treeCon->ses) {
  			if (treeCon->ses->capabilities & CAP_UNICODE)
  				buffer->Flags2 |= SMBFLG2_UNICODE;
ad7a2926b   Steve French   [CIFS] reduce che...
309
  			if (treeCon->ses->capabilities & CAP_STATUS32)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  				buffer->Flags2 |= SMBFLG2_ERR_STATUS;
ad7a2926b   Steve French   [CIFS] reduce che...
311

1982c344f   Steve French   [CIFS] Ensure tha...
312
313
314
  			/* Uid is not converted */
  			buffer->Uid = treeCon->ses->Suid;
  			buffer->Mid = GetNextMid(treeCon->ses->server);
790fe579f   Steve French   [CIFS] more white...
315
  			if (multiuser_mount != 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  		/* For the multiuser case, there are few obvious technically  */
  		/* possible mechanisms to match the local linux user (uid)    */
  		/* to a valid remote smb user (smb_uid):		      */
  		/* 	1) Query Winbind (or other local pam/nss daemon       */
  		/* 	  for userid/password/logon_domain or credential      */
  		/*      2) Query Winbind for uid to sid to username mapping   */
  		/* 	   and see if we have a matching password for existing*/
  		/*         session for that user perhas getting password by   */
  		/*         adding a new pam_cifs module that stores passwords */
  		/*         so that the cifs vfs can get at that for all logged*/
  		/*	   on users					      */
  		/*	3) (Which is the mechanism we have chosen)	      */
  		/*	   Search through sessions to the same server for a   */
  		/*	   a match on the uid that was passed in on mount     */
  		/*         with the current processes uid (or euid?) and use  */
  		/* 	   that smb uid.   If no existing smb session for     */
  		/* 	   that uid found, use the default smb session ie     */
  		/*         the smb session for the volume mounted which is    */
  		/* 	   the same as would be used if the multiuser mount   */
  		/* 	   flag were disabled.  */
  
  		/*  BB Add support for establishing new tCon and SMB Session  */
fb8c4b14d   Steve French   [CIFS] whitespace...
338
  		/*      with userid/password pairs found on the smb session   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  		/*	for other target tcp/ip addresses 		BB    */
a001e5b55   David Howells   CRED: Wrap task c...
340
  				if (current_fsuid() != treeCon->ses->linux_uid) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
341
342
  					cFYI(1, "Multiuser mode and UID "
  						 "did not match tcon uid");
14fbf50d6   Jeff Layton   cifs: reinstate s...
343
344
345
  					read_lock(&cifs_tcp_ses_lock);
  					list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
  						ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
a001e5b55   David Howells   CRED: Wrap task c...
346
  						if (ses->linux_uid == current_fsuid()) {
790fe579f   Steve French   [CIFS] more white...
347
  							if (ses->server == treeCon->ses->server) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
348
  								cFYI(1, "found matching uid substitute right smb_uid");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
  								buffer->Uid = ses->Suid;
  								break;
  							} else {
fb8c4b14d   Steve French   [CIFS] whitespace...
352
  				/* BB eventually call cifs_setup_session here */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
353
  								cFYI(1, "local UID found but no smb sess with this server exists");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
  							}
  						}
  					}
14fbf50d6   Jeff Layton   cifs: reinstate s...
357
  					read_unlock(&cifs_tcp_ses_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
359
360
361
362
  				}
  			}
  		}
  		if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
  			buffer->Flags2 |= SMBFLG2_DFS;
d3485d37c   Steve French   [CIFS] Finish cif...
363
364
  		if (treeCon->nocase)
  			buffer->Flags  |= SMBFLG_CASELESS;
790fe579f   Steve French   [CIFS] more white...
365
366
  		if ((treeCon->ses) && (treeCon->ses->server))
  			if (treeCon->ses->server->secMode &
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
368
369
370
371
372
373
374
  			  (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
  				buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
  	}
  
  /*  endian conversion of flags is now done just before sending */
  	buffer->WordCount = (char) word_count;
  	return;
  }
2cd646a2d   Steve French   [CIFS] Remove sta...
375
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
377
  checkSMBhdr(struct smb_hdr *smb, __u16 mid)
  {
fb8c4b14d   Steve French   [CIFS] whitespace...
378
  	/* Make sure that this really is an SMB, that it is a response,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
  	   and that the message ids match */
fb8c4b14d   Steve French   [CIFS] whitespace...
380
381
  	if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) &&
  		(mid == smb->Mid)) {
790fe579f   Steve French   [CIFS] more white...
382
  		if (smb->Flags & SMBFLG_RESPONSE)
fb8c4b14d   Steve French   [CIFS] whitespace...
383
384
  			return 0;
  		else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  		/* only one valid case where server sends us request */
790fe579f   Steve French   [CIFS] more white...
386
  			if (smb->Command == SMB_COM_LOCKING_ANDX)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
  				return 0;
  			else
b6b38f704   Joe Perches   [CIFS] Neaten cER...
389
  				cERROR(1, "Received Request not response");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
  		}
  	} else { /* bad signature or mid */
  		if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
b6b38f704   Joe Perches   [CIFS] Neaten cER...
393
394
  			cERROR(1, "Bad protocol string signature header %x",
  				*(unsigned int *) smb->Protocol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  		if (mid != smb->Mid)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
396
  			cERROR(1, "Mids do not match");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  	}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
398
  	cERROR(1, "bad smb detected. The Mid=%d", smb->Mid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
401
402
  	return 1;
  }
  
  int
d103e164b   Steve French   [CIFS] Workaround...
403
  checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
  {
70ca734a1   Steve French   [CIFS] Various mi...
405
  	__u32 len = smb->smb_buf_length;
190fdeb84   Steve French   [CIFS] Fix byte r...
406
  	__u32 clc_len;  /* calculated length */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
407
  	cFYI(0, "checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len);
d103e164b   Steve French   [CIFS] Workaround...
408

630f3f0c4   Steve French   [CIFS] acl suppor...
409
410
  	if (length < 2 + sizeof(struct smb_hdr)) {
  		if ((length >= sizeof(struct smb_hdr) - 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
  			    && (smb->Status.CifsError != 0)) {
d103e164b   Steve French   [CIFS] Workaround...
412
413
414
  			smb->WordCount = 0;
  			/* some error cases do not return wct and bcc */
  			return 0;
fb8c4b14d   Steve French   [CIFS] whitespace...
415
  		} else if ((length == sizeof(struct smb_hdr) + 1) &&
d103e164b   Steve French   [CIFS] Workaround...
416
  				(smb->WordCount == 0)) {
fb8c4b14d   Steve French   [CIFS] whitespace...
417
  			char *tmp = (char *)smb;
d103e164b   Steve French   [CIFS] Workaround...
418
419
420
421
422
423
424
425
426
427
428
  			/* Need to work around a bug in two servers here */
  			/* First, check if the part of bcc they sent was zero */
  			if (tmp[sizeof(struct smb_hdr)] == 0) {
  				/* some servers return only half of bcc
  				 * on simple responses (wct, bcc both zero)
  				 * in particular have seen this on
  				 * ulogoffX and FindClose. This leaves
  				 * one byte of bcc potentially unitialized
  				 */
  				/* zero rest of bcc */
  				tmp[sizeof(struct smb_hdr)+1] = 0;
46c79a645   Steve French   [CIFS] Move noisy...
429
  				return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  			}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
431
  			cERROR(1, "rcvd invalid byte count (bcc)");
d103e164b   Steve French   [CIFS] Workaround...
432
  		} else {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
433
  			cERROR(1, "Length less than smb header size");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  		}
d103e164b   Steve French   [CIFS] Workaround...
435
436
437
  		return 1;
  	}
  	if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
438
439
  		cERROR(1, "smb length greater than MaxBufSize, mid=%d",
  				   smb->Mid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
442
443
444
  		return 1;
  	}
  
  	if (checkSMBhdr(smb, mid))
  		return 1;
190fdeb84   Steve French   [CIFS] Fix byte r...
445
  	clc_len = smbCalcSize_LE(smb);
184ed2110   Steve French   [CIFS] Fix large ...
446

790fe579f   Steve French   [CIFS] more white...
447
  	if (4 + len != length) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
448
449
  		cERROR(1, "Length read does not match RFC1001 length %d",
  			   len);
184ed2110   Steve French   [CIFS] Fix large ...
450
451
452
453
454
  		return 1;
  	}
  
  	if (4 + len != clc_len) {
  		/* check if bcc wrapped around for large read responses */
790fe579f   Steve French   [CIFS] more white...
455
  		if ((len > 64 * 1024) && (len > clc_len)) {
184ed2110   Steve French   [CIFS] Fix large ...
456
  			/* check if lengths match mod 64K */
790fe579f   Steve French   [CIFS] more white...
457
  			if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
fb8c4b14d   Steve French   [CIFS] whitespace...
458
  				return 0; /* bcc wrapped */
184ed2110   Steve French   [CIFS] Fix large ...
459
  		}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
460
461
  		cFYI(1, "Calculated size %d vs length %d mismatch for mid %d",
  				clc_len, 4 + len, smb->Mid);
190fdeb84   Steve French   [CIFS] Fix byte r...
462
  		/* Windows XP can return a few bytes too much, presumably
fb8c4b14d   Steve French   [CIFS] whitespace...
463
  		an illegal pad, at the end of byte range lock responses
6ab16d249   Steve French   [CIFS] Fix umount...
464
  		so we allow for that three byte pad, as long as actual
190fdeb84   Steve French   [CIFS] Fix byte r...
465
  		received length is as long or longer than calculated length */
fb8c4b14d   Steve French   [CIFS] whitespace...
466
  		/* We have now had to extend this more, since there is a
6ab16d249   Steve French   [CIFS] Fix umount...
467
468
469
470
471
472
  		case in which it needs to be bigger still to handle a
  		malformed response to transact2 findfirst from WinXP when
  		access denied is returned and thus bcc and wct are zero
  		but server says length is 0x21 bytes too long as if the server
  		forget to reset the smb rfc1001 length when it reset the
  		wct and bcc to minimum size and drop the t2 parms and data */
790fe579f   Steve French   [CIFS] more white...
473
  		if ((4+len > clc_len) && (len <= clc_len + 512))
190fdeb84   Steve French   [CIFS] Fix byte r...
474
  			return 0;
46c79a645   Steve French   [CIFS] Move noisy...
475
  		else {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
476
477
  			cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d",
  					len, smb->Mid);
190fdeb84   Steve French   [CIFS] Fix byte r...
478
  			return 1;
46c79a645   Steve French   [CIFS] Move noisy...
479
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
  	}
209624388   Steve French   [CIFS] Add suppor...
481
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
  }
4b18f2a9c   Steve French   [CIFS] convert us...
483
484
  
  bool
d7c8c94d3   Steve French   [CIFS] Fix slow o...
485
  is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
fb8c4b14d   Steve French   [CIFS] whitespace...
486
487
  {
  	struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
f1987b44f   Jeff Layton   cifs: reinstate s...
488
489
  	struct list_head *tmp, *tmp1, *tmp2;
  	struct cifsSesInfo *ses;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
  	struct cifsTconInfo *tcon;
f1987b44f   Jeff Layton   cifs: reinstate s...
491
  	struct cifsInodeInfo *pCifsInode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  	struct cifsFileInfo *netfile;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
493
  	cFYI(1, "Checking for oplock break or dnotify response");
790fe579f   Steve French   [CIFS] more white...
494
  	if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
  	   (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
fb8c4b14d   Steve French   [CIFS] whitespace...
496
  		struct smb_com_transaction_change_notify_rsp *pSMBr =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
  			(struct smb_com_transaction_change_notify_rsp *)buf;
fb8c4b14d   Steve French   [CIFS] whitespace...
498
  		struct file_notify_information *pnotify;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
  		__u32 data_offset = 0;
790fe579f   Steve French   [CIFS] more white...
500
  		if (pSMBr->ByteCount > sizeof(struct file_notify_information)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  			data_offset = le32_to_cpu(pSMBr->DataOffset);
3979877e5   Steve French   [CIFS] Support fo...
502
503
  			pnotify = (struct file_notify_information *)
  				((char *)&pSMBr->hdr.Protocol + data_offset);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
504
505
  			cFYI(1, "dnotify on %s Action: 0x%x",
  				 pnotify->FileName, pnotify->Action);
fb8c4b14d   Steve French   [CIFS] whitespace...
506
  			/*   cifs_dump_mem("Rcvd notify Data: ",buf,
3979877e5   Steve French   [CIFS] Support fo...
507
  				sizeof(struct smb_hdr)+60); */
4b18f2a9c   Steve French   [CIFS] convert us...
508
  			return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
  		}
790fe579f   Steve French   [CIFS] more white...
510
  		if (pSMBr->hdr.Status.CifsError) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
511
512
  			cFYI(1, "notify err 0x%d",
  				pSMBr->hdr.Status.CifsError);
4b18f2a9c   Steve French   [CIFS] convert us...
513
  			return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
  		}
4b18f2a9c   Steve French   [CIFS] convert us...
515
  		return false;
fb8c4b14d   Steve French   [CIFS] whitespace...
516
  	}
790fe579f   Steve French   [CIFS] more white...
517
  	if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
4b18f2a9c   Steve French   [CIFS] convert us...
518
  		return false;
790fe579f   Steve French   [CIFS] more white...
519
  	if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
523
  		/* no sense logging error on invalid handle on oplock
  		   break - harmless race between close request and oplock
  		   break response is expected from time to time writing out
  		   large dirty files cached on the client */
fb8c4b14d   Steve French   [CIFS] whitespace...
524
525
  		if ((NT_STATUS_INVALID_HANDLE) ==
  		   le32_to_cpu(pSMB->hdr.Status.CifsError)) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
526
  			cFYI(1, "invalid handle on oplock break");
4b18f2a9c   Steve French   [CIFS] convert us...
527
  			return true;
fb8c4b14d   Steve French   [CIFS] whitespace...
528
  		} else if (ERRbadfid ==
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
  		   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
4b18f2a9c   Steve French   [CIFS] convert us...
530
  			return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
  		} else {
4b18f2a9c   Steve French   [CIFS] convert us...
532
  			return false; /* on valid oplock brk we get "request" */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
534
  		}
  	}
790fe579f   Steve French   [CIFS] more white...
535
  	if (pSMB->hdr.WordCount != 8)
4b18f2a9c   Steve French   [CIFS] convert us...
536
  		return false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537

b6b38f704   Joe Perches   [CIFS] Neaten cER...
538
539
  	cFYI(1, "oplock type 0x%d level 0x%d",
  		 pSMB->LockType, pSMB->OplockLevel);
790fe579f   Steve French   [CIFS] more white...
540
  	if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
4b18f2a9c   Steve French   [CIFS] convert us...
541
  		return false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
  
  	/* look up tcon based on tid & uid */
f1987b44f   Jeff Layton   cifs: reinstate s...
544
545
546
547
548
549
550
  	read_lock(&cifs_tcp_ses_lock);
  	list_for_each(tmp, &srv->smb_ses_list) {
  		ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
  		list_for_each(tmp1, &ses->tcon_list) {
  			tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
  			if (tcon->tid != buf->Tid)
  				continue;
a45443475   Steve French   CIFS: Reduce CONF...
551
  			cifs_stats_inc(&tcon->num_oplock_brks);
058daf4f6   Jeff Layton   cifs: take read l...
552
  			read_lock(&GlobalSMBSeslock);
f1987b44f   Jeff Layton   cifs: reinstate s...
553
554
  			list_for_each(tmp2, &tcon->openFileList) {
  				netfile = list_entry(tmp2, struct cifsFileInfo,
57337e42f   Steve French   [PATCH] cifs: han...
555
  						     tlist);
f1987b44f   Jeff Layton   cifs: reinstate s...
556
557
  				if (pSMB->Fid != netfile->netfid)
  					continue;
3bc303c25   Jeff Layton   cifs: convert opl...
558
559
560
561
562
563
564
565
566
  				/*
  				 * don't do anything if file is about to be
  				 * closed anyway.
  				 */
  				if (netfile->closePend) {
  					read_unlock(&GlobalSMBSeslock);
  					read_unlock(&cifs_tcp_ses_lock);
  					return true;
  				}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
567
  				cFYI(1, "file id match, oplock break");
f1987b44f   Jeff Layton   cifs: reinstate s...
568
569
570
571
  				pCifsInode = CIFS_I(netfile->pInode);
  				pCifsInode->clientCanCacheAll = false;
  				if (pSMB->OplockLevel == 0)
  					pCifsInode->clientCanCacheRead = false;
9b6469724   Tejun Heo   cifs: use workque...
572
573
574
575
576
577
578
579
580
581
582
  
  				/*
  				 * cifs_oplock_break_put() can't be called
  				 * from here.  Get reference after queueing
  				 * succeeded.  cifs_oplock_break() will
  				 * synchronize using GlobalSMSSeslock.
  				 */
  				if (queue_work(system_nrt_wq,
  					       &netfile->oplock_break))
  					cifs_oplock_break_get(netfile);
  				netfile->oplock_break_cancelled = false;
3bc303c25   Jeff Layton   cifs: convert opl...
583
584
  				read_unlock(&GlobalSMBSeslock);
  				read_unlock(&cifs_tcp_ses_lock);
f1987b44f   Jeff Layton   cifs: reinstate s...
585
  				return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
  			}
058daf4f6   Jeff Layton   cifs: take read l...
587
  			read_unlock(&GlobalSMBSeslock);
f1987b44f   Jeff Layton   cifs: reinstate s...
588
  			read_unlock(&cifs_tcp_ses_lock);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
589
  			cFYI(1, "No matching file for oplock break");
4b18f2a9c   Steve French   [CIFS] convert us...
590
  			return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
  		}
  	}
f1987b44f   Jeff Layton   cifs: reinstate s...
593
  	read_unlock(&cifs_tcp_ses_lock);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
594
  	cFYI(1, "Can not process oplock break for non-existent connection");
4b18f2a9c   Steve French   [CIFS] convert us...
595
  	return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
598
599
600
601
602
603
604
605
606
607
608
609
  }
  
  void
  dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
  {
  	int i, j;
  	char debug_line[17];
  	unsigned char *buffer;
  
  	if (traceSMB == 0)
  		return;
  
  	buffer = (unsigned char *) smb_buf;
  	for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
ad7a2926b   Steve French   [CIFS] reduce che...
610
611
  		if (i % 8 == 0) {
  			/* have reached the beginning of line */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
613
614
615
616
617
618
619
620
  			printk(KERN_DEBUG "| ");
  			j = 0;
  		}
  		printk("%0#4x ", buffer[i]);
  		debug_line[2 * j] = ' ';
  		if (isprint(buffer[i]))
  			debug_line[1 + (2 * j)] = buffer[i];
  		else
  			debug_line[1 + (2 * j)] = '_';
ad7a2926b   Steve French   [CIFS] reduce che...
621
622
  		if (i % 8 == 7) {
  			/* reached end of line, time to print ascii */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
624
625
626
627
628
629
630
631
632
  			debug_line[16] = 0;
  			printk(" | %s
  ", debug_line);
  		}
  	}
  	for (; j < 8; j++) {
  		printk("     ");
  		debug_line[2 * j] = ' ';
  		debug_line[1 + (2 * j)] = ' ';
  	}
ad7a2926b   Steve French   [CIFS] reduce che...
633
634
  	printk(" | %s
  ", debug_line);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
636
  	return;
  }
6a0b48245   Steve French   [PATCH] cifs: Add...
637

6c91d362f   Steve French   [PATCH] cifs: fin...
638
639
640
641
642
  /* Convert 16 bit Unicode pathname to wire format from string in current code
     page.  Conversion may involve remapping up the seven characters that are
     only legal in POSIX-like OS (if they are present in the string). Path
     names are little endian 16 bit Unicode on the wire */
  int
fb8c4b14d   Steve French   [CIFS] whitespace...
643
644
  cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
  		 const struct nls_table *cp, int mapChars)
6c91d362f   Steve French   [PATCH] cifs: fin...
645
  {
fb8c4b14d   Steve French   [CIFS] whitespace...
646
  	int i, j, charlen;
6c91d362f   Steve French   [PATCH] cifs: fin...
647
648
  	int len_remaining = maxlen;
  	char src_char;
70ca734a1   Steve French   [CIFS] Various mi...
649
  	__u16 temp;
6c91d362f   Steve French   [PATCH] cifs: fin...
650

790fe579f   Steve French   [CIFS] more white...
651
  	if (!mapChars)
e89dc9209   Steve French   [CIFS] Cleanup sp...
652
  		return cifs_strtoUCS(target, source, PATH_MAX, cp);
6c91d362f   Steve French   [PATCH] cifs: fin...
653

fb8c4b14d   Steve French   [CIFS] whitespace...
654
  	for (i = 0, j = 0; i < maxlen; j++) {
6c91d362f   Steve French   [PATCH] cifs: fin...
655
656
657
  		src_char = source[i];
  		switch (src_char) {
  			case 0:
f4cfd69cf   Steve French   [CIFS] Fix path n...
658
  				target[j] = 0;
6c91d362f   Steve French   [PATCH] cifs: fin...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  				goto ctoUCS_out;
  			case ':':
  				target[j] = cpu_to_le16(UNI_COLON);
  				break;
  			case '*':
  				target[j] = cpu_to_le16(UNI_ASTERIK);
  				break;
  			case '?':
  				target[j] = cpu_to_le16(UNI_QUESTION);
  				break;
  			case '<':
  				target[j] = cpu_to_le16(UNI_LESSTHAN);
  				break;
  			case '>':
  				target[j] = cpu_to_le16(UNI_GRTRTHAN);
  				break;
  			case '|':
  				target[j] = cpu_to_le16(UNI_PIPE);
fb8c4b14d   Steve French   [CIFS] whitespace...
677
  				break;
6c91d362f   Steve French   [PATCH] cifs: fin...
678
679
680
681
682
683
684
685
  			/* BB We can not handle remapping slash until
  			   all the calls to build_path_from_dentry
  			   are modified, as they use slash as separator BB */
  			/* case '\\':
  				target[j] = cpu_to_le16(UNI_SLASH);
  				break;*/
  			default:
  				charlen = cp->char2uni(source+i,
70ca734a1   Steve French   [CIFS] Various mi...
686
  					len_remaining, &temp);
6c91d362f   Steve French   [PATCH] cifs: fin...
687
688
  				/* if no match, use question mark, which
  				at least in some cases servers as wild card */
790fe579f   Steve French   [CIFS] more white...
689
  				if (charlen < 1) {
6c91d362f   Steve French   [PATCH] cifs: fin...
690
691
  					target[j] = cpu_to_le16(0x003f);
  					charlen = 1;
70ca734a1   Steve French   [CIFS] Various mi...
692
693
  				} else
  					target[j] = cpu_to_le16(temp);
6c91d362f   Steve French   [PATCH] cifs: fin...
694
695
696
697
  				len_remaining -= charlen;
  				/* character may take more than one byte in the
  				   the source string, but will take exactly two
  				   bytes in the target string */
fb8c4b14d   Steve French   [CIFS] whitespace...
698
  				i += charlen;
6c91d362f   Steve French   [PATCH] cifs: fin...
699
700
701
702
703
704
705
706
707
  				continue;
  		}
  		i++; /* move to next char in source string */
  		len_remaining--;
  	}
  
  ctoUCS_out:
  	return i;
  }
ec06aedd4   Jeff Layton   cifs: clean up ha...
708
709
710
711
712
  
  void
  cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
  {
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
f534dc994   Suresh Jayaraman   cifs: clear serve...
713
  		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
714
  		cERROR(1, "Autodisabling the use of server inode numbers on "
ec06aedd4   Jeff Layton   cifs: clean up ha...
715
716
717
718
  			   "%s. This server doesn't seem to support them "
  			   "properly. Hardlinks will not be recognized on this "
  			   "mount. Consider mounting with the \"noserverino\" "
  			   "option to silence this message.",
b6b38f704   Joe Perches   [CIFS] Neaten cER...
719
  			   cifs_sb->tcon->treeName);
ec06aedd4   Jeff Layton   cifs: clean up ha...
720
721
  	}
  }