aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c90
1 files changed, 86 insertions, 4 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index b4f7b9859e3b..7d14f2414812 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2411,7 +2411,9 @@ findUniqueRetry:
2411 if (rc) { 2411 if (rc) {
2412 cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); 2412 cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
2413 } else { /* decode response */ 2413 } else { /* decode response */
2414 2414#ifdef CONFIG_CIFS_STATS
2415 atomic_inc(&tcon->num_ffirst);
2416#endif
2415 /* BB fill in */ 2417 /* BB fill in */
2416 } 2418 }
2417 2419
@@ -2429,7 +2431,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
2429 const char *searchName, 2431 const char *searchName,
2430 const struct nls_table *nls_codepage, 2432 const struct nls_table *nls_codepage,
2431 __u16 * pnetfid, 2433 __u16 * pnetfid,
2432 struct cifs_search_info * psrch_inf, int remap) 2434 struct cifs_search_info * psrch_inf, int remap, const char dirsep)
2433{ 2435{
2434/* level 257 SMB_ */ 2436/* level 257 SMB_ */
2435 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 2437 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2456,7 +2458,7 @@ findFirstRetry:
2456 it got remapped to 0xF03A as if it were part of the 2458 it got remapped to 0xF03A as if it were part of the
2457 directory name instead of a wildcard */ 2459 directory name instead of a wildcard */
2458 name_len *= 2; 2460 name_len *= 2;
2459 pSMB->FileName[name_len] = '\\'; 2461 pSMB->FileName[name_len] = dirsep;
2460 pSMB->FileName[name_len+1] = 0; 2462 pSMB->FileName[name_len+1] = 0;
2461 pSMB->FileName[name_len+2] = '*'; 2463 pSMB->FileName[name_len+2] = '*';
2462 pSMB->FileName[name_len+3] = 0; 2464 pSMB->FileName[name_len+3] = 0;
@@ -2470,7 +2472,7 @@ findFirstRetry:
2470 if(name_len > buffersize-header) 2472 if(name_len > buffersize-header)
2471 free buffer exit; BB */ 2473 free buffer exit; BB */
2472 strncpy(pSMB->FileName, searchName, name_len); 2474 strncpy(pSMB->FileName, searchName, name_len);
2473 pSMB->FileName[name_len] = '\\'; 2475 pSMB->FileName[name_len] = dirsep;
2474 pSMB->FileName[name_len+1] = '*'; 2476 pSMB->FileName[name_len+1] = '*';
2475 pSMB->FileName[name_len+2] = 0; 2477 pSMB->FileName[name_len+2] = 0;
2476 name_len += 3; 2478 name_len += 3;
@@ -2524,6 +2526,9 @@ findFirstRetry:
2524 if (rc == -EAGAIN) 2526 if (rc == -EAGAIN)
2525 goto findFirstRetry; 2527 goto findFirstRetry;
2526 } else { /* decode response */ 2528 } else { /* decode response */
2529#ifdef CONFIG_CIFS_STATS
2530 atomic_inc(&tcon->num_ffirst);
2531#endif
2527 /* BB remember to free buffer if error BB */ 2532 /* BB remember to free buffer if error BB */
2528 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2533 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2529 if(rc == 0) { 2534 if(rc == 0) {
@@ -2637,6 +2642,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
2637 } else 2642 } else
2638 cFYI(1, ("FindNext returned = %d", rc)); 2643 cFYI(1, ("FindNext returned = %d", rc));
2639 } else { /* decode response */ 2644 } else { /* decode response */
2645#ifdef CONFIG_CIFS_STATS
2646 atomic_inc(&tcon->num_fnext);
2647#endif
2640 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2648 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2641 2649
2642 if(rc == 0) { 2650 if(rc == 0) {
@@ -2706,6 +2714,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
2706 if (rc) { 2714 if (rc) {
2707 cERROR(1, ("Send error in FindClose = %d", rc)); 2715 cERROR(1, ("Send error in FindClose = %d", rc));
2708 } 2716 }
2717#ifdef CONFIG_CIFS_STATS
2718 atomic_inc(&tcon->num_fclose);
2719#endif
2709 cifs_small_buf_release(pSMB); 2720 cifs_small_buf_release(pSMB);
2710 2721
2711 /* Since session is dead, search handle closed on server already */ 2722 /* Since session is dead, search handle closed on server already */
@@ -3269,6 +3280,77 @@ QFSUnixRetry:
3269 return rc; 3280 return rc;
3270} 3281}
3271 3282
3283int
3284CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
3285{
3286/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
3287 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
3288 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
3289 int rc = 0;
3290 int bytes_returned = 0;
3291 __u16 params, param_offset, offset, byte_count;
3292
3293 cFYI(1, ("In SETFSUnixInfo"));
3294SETFSUnixRetry:
3295 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3296 (void **) &pSMBr);
3297 if (rc)
3298 return rc;
3299
3300 params = 4; /* 2 bytes zero followed by info level. */
3301 pSMB->MaxSetupCount = 0;
3302 pSMB->Reserved = 0;
3303 pSMB->Flags = 0;
3304 pSMB->Timeout = 0;
3305 pSMB->Reserved2 = 0;
3306 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
3307 offset = param_offset + params;
3308
3309 pSMB->MaxParameterCount = cpu_to_le16(4);
3310 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
3311 pSMB->SetupCount = 1;
3312 pSMB->Reserved3 = 0;
3313 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
3314 byte_count = 1 /* pad */ + params + 12;
3315
3316 pSMB->DataCount = cpu_to_le16(12);
3317 pSMB->ParameterCount = cpu_to_le16(params);
3318 pSMB->TotalDataCount = pSMB->DataCount;
3319 pSMB->TotalParameterCount = pSMB->ParameterCount;
3320 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3321 pSMB->DataOffset = cpu_to_le16(offset);
3322
3323 /* Params. */
3324 pSMB->FileNum = 0;
3325 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
3326
3327 /* Data. */
3328 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
3329 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
3330 pSMB->ClientUnixCap = cpu_to_le64(cap);
3331
3332 pSMB->hdr.smb_buf_length += byte_count;
3333 pSMB->ByteCount = cpu_to_le16(byte_count);
3334
3335 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3336 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3337 if (rc) {
3338 cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
3339 } else { /* decode response */
3340 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3341 if (rc) {
3342 rc = -EIO; /* bad smb */
3343 }
3344 }
3345 cifs_buf_release(pSMB);
3346
3347 if (rc == -EAGAIN)
3348 goto SETFSUnixRetry;
3349
3350 return rc;
3351}
3352
3353
3272 3354
3273int 3355int
3274CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 3356CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,