aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <smfrench@austin.rr.com>2005-04-29 01:41:05 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-29 01:41:05 -0400
commit6a0b48245a135cd132e747815854e3999967f8a7 (patch)
tree55fffb67b924fbca2a5a16e83100a5d1000daaf4 /fs
parentcbe0476fa6a76b01b79e7c117963d45ed0a28758 (diff)
[PATCH] cifs: Add new mount parm mapchars
For handling seven special characters that shells use for filenames. This first parts implements conversions from Unicode. Signed-off-by: Steve French Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES4
-rw-r--r--fs/cifs/README11
-rw-r--r--fs/cifs/TODO19
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/connect.c7
-rw-r--r--fs/cifs/misc.c69
-rw-r--r--fs/cifs/readdir.c15
8 files changed, 116 insertions, 12 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index ce16b0ae772e..412b6d243d53 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -7,7 +7,9 @@ as new protocol extensions. Do not send Get/Set calls for POSIX ACLs
7unless server explicitly claims to support them in CIFS Unix extensions 7unless server explicitly claims to support them in CIFS Unix extensions
8POSIX ACL capability bit. Fix packet signing when multiuser mounting with 8POSIX ACL capability bit. Fix packet signing when multiuser mounting with
9different users from the same client to the same server. Fix oops in 9different users from the same client to the same server. Fix oops in
10cifs_close. 10cifs_close. Add mount option for remapping reserved characters in
11filenames (also allow recognizing files with created by SFU which have any
12of these seven reserved characters to be recognized).
11 13
12Version 1.31 14Version 1.31
13------------ 15------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 0f20edc935b5..83e054576258 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -376,6 +376,17 @@ A partial list of the supported mount options follows:
376 attributes) to the server (default) e.g. via setfattr 376 attributes) to the server (default) e.g. via setfattr
377 and getfattr utilities. 377 and getfattr utilities.
378 nouser_xattr Do not allow getfattr/setfattr to get/set xattrs 378 nouser_xattr Do not allow getfattr/setfattr to get/set xattrs
379 mapchars Translate the seven reserved characters
380 *?<>|:\
381 to the remap range (above 0xF000), which also
382 allows the CIFS client to recognize files created with
383 such characters by Windows's POSIX emulation. This can
384 also be useful when mounting to most versions of Samba
385 (which also forbids creating and opening files
386 whose names contain any of these seven characters).
387 This has no effect if the server does not support
388 Unicode on the wire.
389 nomapchars Do not translate any of these seven characters (default).
379 390
380The mount.cifs mount helper also accepts a few mount options before -o 391The mount.cifs mount helper also accepts a few mount options before -o
381including: 392including:
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index f4e3e1f67ee4..a69227415a73 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
1version 1.22 July 30, 2004 1version 1.32 April 3, 2005
2 2
3A Partial List of Missing Features 3A Partial List of Missing Features
4================================== 4==================================
@@ -14,7 +14,7 @@ b) Better pam/winbind integration (e.g. to handle uid mapping
14better) 14better)
15 15
16c) multi-user mounts - multiplexed sessionsetups over single vc 16c) multi-user mounts - multiplexed sessionsetups over single vc
17(ie tcp session) - prettying up needed, and more testing needed 17(ie tcp session) - more testing needed
18 18
19d) Kerberos/SPNEGO session setup support - (started) 19d) Kerberos/SPNEGO session setup support - (started)
20 20
@@ -67,12 +67,15 @@ q) implement support for security and trusted categories of xattrs
67 67
68r) Implement O_DIRECT flag on open (already supported on mount) 68r) Implement O_DIRECT flag on open (already supported on mount)
69 69
70KNOWN BUGS (updated December 10, 2004) 70KNOWN BUGS (updated April 3, 2005)
71==================================== 71====================================
72See http://bugzilla.samba.org - search on product "CifsVFS" for
73current bug list.
74
721) existing symbolic links (Windows reparse points) are recognized but 751) existing symbolic links (Windows reparse points) are recognized but
73can not be created remotely. They are implemented for Samba and those that 76can not be created remotely. They are implemented for Samba and those that
74support the CIFS Unix extensions but Samba has a bug currently handling 77support the CIFS Unix extensions, although earlier versions of Samba
75symlink text beginning with slash 78overly restrict the pathnames.
762) follow_link and readdir code does not follow dfs junctions 792) follow_link and readdir code does not follow dfs junctions
77but recognizes them 80but recognizes them
783) create of new files to FAT partitions on Windows servers can 813) create of new files to FAT partitions on Windows servers can
@@ -98,7 +101,5 @@ there are some easy changes that can be done to parallelize sequential writes,
98and when signing is disabled to request larger read sizes (larger than 101and when signing is disabled to request larger read sizes (larger than
99negotiated size) and send larger write sizes to modern servers. 102negotiated size) and send larger write sizes to modern servers.
100 103
1014) More exhaustively test the recently added NT4 support against various 1044) More exhaustively test against less common servers. More testing
102NT4 service pack levels, and fix cifs_setattr for setting file times and 105against Windows 9x, Windows ME servers.
103size to fall back to level 1 when error invalid level returned.
104
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 77da902d8f32..ec00d61d5308 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -23,6 +23,7 @@
23#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ 23#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ 24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ 25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
26 27
27struct cifs_sb_info { 28struct cifs_sb_info {
28 struct cifsTconInfo *tcon; /* primary mount */ 29 struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index dd95c2bcbc25..b486ba738d95 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -212,6 +212,8 @@ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
212extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 212extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
213 const unsigned char *searchName, __u64 * inode_number, 213 const unsigned char *searchName, __u64 * inode_number,
214 const struct nls_table *nls_codepage); 214 const struct nls_table *nls_codepage);
215extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen,
216 const struct nls_table * codepage);
215#endif /* CONFIG_CIFS_EXPERIMENTAL */ 217#endif /* CONFIG_CIFS_EXPERIMENTAL */
216 218
217extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 219extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 814e709ca0ca..3d036bf689d8 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -72,6 +72,7 @@ struct smb_vol {
72 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ 72 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
73 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ 73 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
74 unsigned direct_io:1; 74 unsigned direct_io:1;
75 unsigned remap:1; /* set to remap seven reserved chars in filenames */
75 unsigned int rsize; 76 unsigned int rsize;
76 unsigned int wsize; 77 unsigned int wsize;
77 unsigned int sockopt; 78 unsigned int sockopt;
@@ -771,6 +772,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
771 vol->noperm = 0; 772 vol->noperm = 0;
772 } else if (strnicmp(data, "noperm", 6) == 0) { 773 } else if (strnicmp(data, "noperm", 6) == 0) {
773 vol->noperm = 1; 774 vol->noperm = 1;
775 } else if (strnicmp(data, "mapchars", 8) == 0) {
776 vol->remap = 1;
777 } else if (strnicmp(data, "nomapchars", 10) == 0) {
778 vol->remap = 0;
774 } else if (strnicmp(data, "setuids", 7) == 0) { 779 } else if (strnicmp(data, "setuids", 7) == 0) {
775 vol->setuids = 1; 780 vol->setuids = 1;
776 } else if (strnicmp(data, "nosetuids", 9) == 0) { 781 } else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1421,6 +1426,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1421 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; 1426 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1422 if(volume_info.server_ino) 1427 if(volume_info.server_ino)
1423 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; 1428 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1429 if(volume_info.remap)
1430 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1424 if(volume_info.no_xattr) 1431 if(volume_info.no_xattr)
1425 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; 1432 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1426 if(volume_info.direct_io) { 1433 if(volume_info.direct_io) {
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 7b38d3059a83..f2a026073b62 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -514,3 +514,72 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
514 printk( " | %s\n", debug_line); 514 printk( " | %s\n", debug_line);
515 return; 515 return;
516} 516}
517
518#ifdef CONFIG_CIFS_EXPERIMENTAL
519/* Windows maps these to the user defined 16 bit Unicode range since they are
520 reserved symbols (along with \ and /), otherwise illegal to store
521 in filenames in NTFS */
522#define UNI_ASTERIK cpu_to_le16('*' + 0xF000)
523#define UNI_QUESTION cpu_to_le16('?' + 0xF000)
524#define UNI_COLON cpu_to_le16(':' + 0xF000)
525#define UNI_GRTRTHAN cpu_to_le16('>' + 0xF000)
526#define UNI_LESSTHAN cpu_to_le16('<' + 0xF000)
527#define UNI_PIPE cpu_to_le16('|' + 0xF000)
528#define UNI_SLASH cpu_to_le16('\\' + 0xF000)
529
530/* Convert 16 bit Unicode pathname from wire format to string in current code
531 page. Conversion may involve remapping up the seven characters that are
532 only legal in POSIX-like OS (if they are present in the string). Path
533 names are little endian 16 bit Unicode on the wire */
534int
535cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
536 const struct nls_table * cp)
537{
538 int i,j,len;
539 wchar_t src_char;
540
541 for(i = 0, j = 0; i < maxlen; i++) {
542 src_char = le16_to_cpu(source[i]);
543 switch (src_char) {
544 case 0:
545 goto cUCS_out; /* BB check this BB */
546 case UNI_COLON:
547 target[j] = ':';
548 break;
549 case UNI_ASTERIK:
550 target[j] = '*';
551 break;
552 case UNI_QUESTION:
553 target[j] = '?';
554 break;
555 case UNI_SLASH:
556 target[j] = '\\'; /* BB check this - is there risk here of converting path sep BB */
557 break;
558 case UNI_PIPE:
559 target[j] = '|';
560 break;
561 case UNI_GRTRTHAN:
562 target[j] = '>';
563 break;
564 case UNI_LESSTHAN:
565 target[j] = '<';
566 default:
567 len = cp->uni2char(src_char, &target[j],
568 NLS_MAX_CHARSET_SIZE);
569 if(len > 0) {
570 j += len;
571 continue;
572 } else {
573 target[j] = '?';
574 }
575 }
576 j++;
577 /* check to make sure we do not overrun callers allocated temp buffer */
578 if(j >= (2 * NAME_MAX))
579 break;
580 }
581cUCS_out:
582 target[j] = 0;
583 return j;
584}
585#endif /* CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 07838a5ba3a1..4a33add24d53 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -600,7 +600,14 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
600 if(unicode) { 600 if(unicode) {
601 /* BB fixme - test with long names */ 601 /* BB fixme - test with long names */
602 /* Note converted filename can be longer than in unicode */ 602 /* Note converted filename can be longer than in unicode */
603 pqst->len = cifs_strfromUCS_le((char *)pqst->name,(wchar_t *)filename,len/2,nlt); 603#ifdef CONFIG_CIFS_EXPERIMENTAL
604 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
605 pqst->len = cifs_convertUCSpath((char *)pqst->name,
606 (__le16 *)filename, len/2, nlt);
607 else
608#endif /* CIFS_EXPERIMENTAL */
609 pqst->len = cifs_strfromUCS_le((char *)pqst->name,
610 (wchar_t *)filename,len/2,nlt);
604 } else { 611 } else {
605 pqst->name = filename; 612 pqst->name = filename;
606 pqst->len = len; 613 pqst->len = len;
@@ -829,7 +836,11 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
829 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 836 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
830 smbCalcSize((struct smb_hdr *) 837 smbCalcSize((struct smb_hdr *)
831 cifsFile->srch_inf.ntwrk_buf_start); 838 cifsFile->srch_inf.ntwrk_buf_start);
832 tmp_buf = kmalloc(NAME_MAX+1,GFP_KERNEL); 839 /* To be safe - for UCS to UTF-8 with strings loaded
840 with the rare long characters alloc more to account for
841 such multibyte target UTF-8 characters. cifs_unicode.c,
842 which actually does the conversion, has the same limit */
843 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
833 for(i=0;(i<num_to_fill) && (rc == 0);i++) { 844 for(i=0;(i<num_to_fill) && (rc == 0);i++) {
834 if(current_entry == NULL) { 845 if(current_entry == NULL) {
835 /* evaluate whether this case is an error */ 846 /* evaluate whether this case is an error */