aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c160
1 files changed, 152 insertions, 8 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 7b38d3059a83..db14b503d89e 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -28,6 +28,7 @@
28#include "cifs_debug.h" 28#include "cifs_debug.h"
29#include "smberr.h" 29#include "smberr.h"
30#include "nterr.h" 30#include "nterr.h"
31#include "cifs_unicode.h"
31 32
32extern mempool_t *cifs_sm_req_poolp; 33extern mempool_t *cifs_sm_req_poolp;
33extern mempool_t *cifs_req_poolp; 34extern mempool_t *cifs_req_poolp;
@@ -451,25 +452,30 @@ is_valid_oplock_break(struct smb_hdr *buf)
451 atomic_inc(&tcon->num_oplock_brks); 452 atomic_inc(&tcon->num_oplock_brks);
452#endif 453#endif
453 list_for_each(tmp1,&tcon->openFileList){ 454 list_for_each(tmp1,&tcon->openFileList){
454 netfile = list_entry(tmp1,struct cifsFileInfo,tlist); 455 netfile = list_entry(tmp1,struct cifsFileInfo,
456 tlist);
455 if(pSMB->Fid == netfile->netfid) { 457 if(pSMB->Fid == netfile->netfid) {
456 struct cifsInodeInfo *pCifsInode; 458 struct cifsInodeInfo *pCifsInode;
457 read_unlock(&GlobalSMBSeslock); 459 read_unlock(&GlobalSMBSeslock);
458 cFYI(1,("Matching file id, processing oplock break")); 460 cFYI(1,("file id match, oplock break"));
459 pCifsInode = 461 pCifsInode =
460 CIFS_I(netfile->pInode); 462 CIFS_I(netfile->pInode);
461 pCifsInode->clientCanCacheAll = FALSE; 463 pCifsInode->clientCanCacheAll = FALSE;
462 if(pSMB->OplockLevel == 0) 464 if(pSMB->OplockLevel == 0)
463 pCifsInode->clientCanCacheRead = FALSE; 465 pCifsInode->clientCanCacheRead
466 = FALSE;
464 pCifsInode->oplockPending = TRUE; 467 pCifsInode->oplockPending = TRUE;
465 AllocOplockQEntry(netfile->pInode, netfile->netfid, tcon); 468 AllocOplockQEntry(netfile->pInode,
469 netfile->netfid,
470 tcon);
466 cFYI(1,("about to wake up oplock thd")); 471 cFYI(1,("about to wake up oplock thd"));
467 wake_up_process(oplockThread); 472 if(oplockThread)
473 wake_up_process(oplockThread);
468 return TRUE; 474 return TRUE;
469 } 475 }
470 } 476 }
471 read_unlock(&GlobalSMBSeslock); 477 read_unlock(&GlobalSMBSeslock);
472 cFYI(1,("No matching file for oplock break on connection")); 478 cFYI(1,("No matching file for oplock break"));
473 return TRUE; 479 return TRUE;
474 } 480 }
475 } 481 }
@@ -490,7 +496,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
490 496
491 buffer = (unsigned char *) smb_buf; 497 buffer = (unsigned char *) smb_buf;
492 for (i = 0, j = 0; i < smb_buf_length; i++, j++) { 498 for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
493 if (i % 8 == 0) { /* we have reached the beginning of line */ 499 if (i % 8 == 0) { /* have reached the beginning of line */
494 printk(KERN_DEBUG "| "); 500 printk(KERN_DEBUG "| ");
495 j = 0; 501 j = 0;
496 } 502 }
@@ -501,7 +507,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
501 else 507 else
502 debug_line[1 + (2 * j)] = '_'; 508 debug_line[1 + (2 * j)] = '_';
503 509
504 if (i % 8 == 7) { /* we have reached end of line, time to print ascii */ 510 if (i % 8 == 7) { /* reached end of line, time to print ascii */
505 debug_line[16] = 0; 511 debug_line[16] = 0;
506 printk(" | %s\n", debug_line); 512 printk(" | %s\n", debug_line);
507 } 513 }
@@ -514,3 +520,141 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
514 printk( " | %s\n", debug_line); 520 printk( " | %s\n", debug_line);
515 return; 521 return;
516} 522}
523
524/* Windows maps these to the user defined 16 bit Unicode range since they are
525 reserved symbols (along with \ and /), otherwise illegal to store
526 in filenames in NTFS */
527#define UNI_ASTERIK (__u16) ('*' + 0xF000)
528#define UNI_QUESTION (__u16) ('?' + 0xF000)
529#define UNI_COLON (__u16) (':' + 0xF000)
530#define UNI_GRTRTHAN (__u16) ('>' + 0xF000)
531#define UNI_LESSTHAN (__u16) ('<' + 0xF000)
532#define UNI_PIPE (__u16) ('|' + 0xF000)
533#define UNI_SLASH (__u16) ('\\' + 0xF000)
534
535/* Convert 16 bit Unicode pathname from wire format to string in current code
536 page. Conversion may involve remapping up the seven characters that are
537 only legal in POSIX-like OS (if they are present in the string). Path
538 names are little endian 16 bit Unicode on the wire */
539int
540cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
541 const struct nls_table * cp)
542{
543 int i,j,len;
544 __u16 src_char;
545
546 for(i = 0, j = 0; i < maxlen; i++) {
547 src_char = le16_to_cpu(source[i]);
548 switch (src_char) {
549 case 0:
550 goto cUCS_out; /* BB check this BB */
551 case UNI_COLON:
552 target[j] = ':';
553 break;
554 case UNI_ASTERIK:
555 target[j] = '*';
556 break;
557 case UNI_QUESTION:
558 target[j] = '?';
559 break;
560 /* BB We can not handle remapping slash until
561 all the calls to build_path_from_dentry
562 are modified, as they use slash as separator BB */
563 /* case UNI_SLASH:
564 target[j] = '\\';
565 break;*/
566 case UNI_PIPE:
567 target[j] = '|';
568 break;
569 case UNI_GRTRTHAN:
570 target[j] = '>';
571 break;
572 case UNI_LESSTHAN:
573 target[j] = '<';
574 default:
575 len = cp->uni2char(src_char, &target[j],
576 NLS_MAX_CHARSET_SIZE);
577 if(len > 0) {
578 j += len;
579 continue;
580 } else {
581 target[j] = '?';
582 }
583 }
584 j++;
585 /* make sure we do not overrun callers allocated temp buffer */
586 if(j >= (2 * NAME_MAX))
587 break;
588 }
589cUCS_out:
590 target[j] = 0;
591 return j;
592}
593
594/* Convert 16 bit Unicode pathname to wire format from string in current code
595 page. Conversion may involve remapping up the seven characters that are
596 only legal in POSIX-like OS (if they are present in the string). Path
597 names are little endian 16 bit Unicode on the wire */
598int
599cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
600 const struct nls_table * cp, int mapChars)
601{
602 int i,j,charlen;
603 int len_remaining = maxlen;
604 char src_char;
605
606 if(!mapChars)
607 return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
608
609 for(i = 0, j = 0; i < maxlen; j++) {
610 src_char = source[i];
611 switch (src_char) {
612 case 0:
613 goto ctoUCS_out;
614 case ':':
615 target[j] = cpu_to_le16(UNI_COLON);
616 break;
617 case '*':
618 target[j] = cpu_to_le16(UNI_ASTERIK);
619 break;
620 case '?':
621 target[j] = cpu_to_le16(UNI_QUESTION);
622 break;
623 case '<':
624 target[j] = cpu_to_le16(UNI_LESSTHAN);
625 break;
626 case '>':
627 target[j] = cpu_to_le16(UNI_GRTRTHAN);
628 break;
629 case '|':
630 target[j] = cpu_to_le16(UNI_PIPE);
631 break;
632 /* BB We can not handle remapping slash until
633 all the calls to build_path_from_dentry
634 are modified, as they use slash as separator BB */
635 /* case '\\':
636 target[j] = cpu_to_le16(UNI_SLASH);
637 break;*/
638 default:
639 charlen = cp->char2uni(source+i,
640 len_remaining, target+j);
641 /* if no match, use question mark, which
642 at least in some cases servers as wild card */
643 if(charlen < 1) {
644 target[j] = cpu_to_le16(0x003f);
645 charlen = 1;
646 }
647 len_remaining -= charlen;
648 /* character may take more than one byte in the
649 the source string, but will take exactly two
650 bytes in the target string */
651 i+= charlen;
652 continue;
653 }
654 i++; /* move to next char in source string */
655 len_remaining--;
656 }
657
658ctoUCS_out:
659 return i;
660}