mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
[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>
This commit is contained in:
parent
cbe0476fa6
commit
6a0b48245a
8 changed files with 116 additions and 12 deletions
|
@ -7,7 +7,9 @@ as new protocol extensions. Do not send Get/Set calls for POSIX ACLs
|
|||
unless server explicitly claims to support them in CIFS Unix extensions
|
||||
POSIX ACL capability bit. Fix packet signing when multiuser mounting with
|
||||
different users from the same client to the same server. Fix oops in
|
||||
cifs_close.
|
||||
cifs_close. Add mount option for remapping reserved characters in
|
||||
filenames (also allow recognizing files with created by SFU which have any
|
||||
of these seven reserved characters to be recognized).
|
||||
|
||||
Version 1.31
|
||||
------------
|
||||
|
|
|
@ -376,6 +376,17 @@ A partial list of the supported mount options follows:
|
|||
attributes) to the server (default) e.g. via setfattr
|
||||
and getfattr utilities.
|
||||
nouser_xattr Do not allow getfattr/setfattr to get/set xattrs
|
||||
mapchars Translate the seven reserved characters
|
||||
*?<>|:\
|
||||
to the remap range (above 0xF000), which also
|
||||
allows the CIFS client to recognize files created with
|
||||
such characters by Windows's POSIX emulation. This can
|
||||
also be useful when mounting to most versions of Samba
|
||||
(which also forbids creating and opening files
|
||||
whose names contain any of these seven characters).
|
||||
This has no effect if the server does not support
|
||||
Unicode on the wire.
|
||||
nomapchars Do not translate any of these seven characters (default).
|
||||
|
||||
The mount.cifs mount helper also accepts a few mount options before -o
|
||||
including:
|
||||
|
|
19
fs/cifs/TODO
19
fs/cifs/TODO
|
@ -1,4 +1,4 @@
|
|||
version 1.22 July 30, 2004
|
||||
version 1.32 April 3, 2005
|
||||
|
||||
A Partial List of Missing Features
|
||||
==================================
|
||||
|
@ -14,7 +14,7 @@ b) Better pam/winbind integration (e.g. to handle uid mapping
|
|||
better)
|
||||
|
||||
c) multi-user mounts - multiplexed sessionsetups over single vc
|
||||
(ie tcp session) - prettying up needed, and more testing needed
|
||||
(ie tcp session) - more testing needed
|
||||
|
||||
d) Kerberos/SPNEGO session setup support - (started)
|
||||
|
||||
|
@ -67,12 +67,15 @@ q) implement support for security and trusted categories of xattrs
|
|||
|
||||
r) Implement O_DIRECT flag on open (already supported on mount)
|
||||
|
||||
KNOWN BUGS (updated December 10, 2004)
|
||||
KNOWN BUGS (updated April 3, 2005)
|
||||
====================================
|
||||
See http://bugzilla.samba.org - search on product "CifsVFS" for
|
||||
current bug list.
|
||||
|
||||
1) existing symbolic links (Windows reparse points) are recognized but
|
||||
can not be created remotely. They are implemented for Samba and those that
|
||||
support the CIFS Unix extensions but Samba has a bug currently handling
|
||||
symlink text beginning with slash
|
||||
support the CIFS Unix extensions, although earlier versions of Samba
|
||||
overly restrict the pathnames.
|
||||
2) follow_link and readdir code does not follow dfs junctions
|
||||
but recognizes them
|
||||
3) 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,
|
|||
and when signing is disabled to request larger read sizes (larger than
|
||||
negotiated size) and send larger write sizes to modern servers.
|
||||
|
||||
4) More exhaustively test the recently added NT4 support against various
|
||||
NT4 service pack levels, and fix cifs_setattr for setting file times and
|
||||
size to fall back to level 1 when error invalid level returned.
|
||||
|
||||
4) More exhaustively test against less common servers. More testing
|
||||
against Windows 9x, Windows ME servers.
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
|
||||
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
|
||||
#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
|
||||
#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
|
||||
|
||||
struct cifs_sb_info {
|
||||
struct cifsTconInfo *tcon; /* primary mount */
|
||||
|
|
|
@ -212,6 +212,8 @@ extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
|||
extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName, __u64 * inode_number,
|
||||
const struct nls_table *nls_codepage);
|
||||
extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen,
|
||||
const struct nls_table * codepage);
|
||||
#endif /* CONFIG_CIFS_EXPERIMENTAL */
|
||||
|
||||
extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
||||
|
|
|
@ -72,6 +72,7 @@ struct smb_vol {
|
|||
unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
|
||||
unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
|
||||
unsigned direct_io:1;
|
||||
unsigned remap:1; /* set to remap seven reserved chars in filenames */
|
||||
unsigned int rsize;
|
||||
unsigned int wsize;
|
||||
unsigned int sockopt;
|
||||
|
@ -771,6 +772,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
|
|||
vol->noperm = 0;
|
||||
} else if (strnicmp(data, "noperm", 6) == 0) {
|
||||
vol->noperm = 1;
|
||||
} else if (strnicmp(data, "mapchars", 8) == 0) {
|
||||
vol->remap = 1;
|
||||
} else if (strnicmp(data, "nomapchars", 10) == 0) {
|
||||
vol->remap = 0;
|
||||
} else if (strnicmp(data, "setuids", 7) == 0) {
|
||||
vol->setuids = 1;
|
||||
} else if (strnicmp(data, "nosetuids", 9) == 0) {
|
||||
|
@ -1421,6 +1426,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
|||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
|
||||
if(volume_info.server_ino)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
|
||||
if(volume_info.remap)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
|
||||
if(volume_info.no_xattr)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
|
||||
if(volume_info.direct_io) {
|
||||
|
|
|
@ -514,3 +514,72 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
|
|||
printk( " | %s\n", debug_line);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
/* Windows maps these to the user defined 16 bit Unicode range since they are
|
||||
reserved symbols (along with \ and /), otherwise illegal to store
|
||||
in filenames in NTFS */
|
||||
#define UNI_ASTERIK cpu_to_le16('*' + 0xF000)
|
||||
#define UNI_QUESTION cpu_to_le16('?' + 0xF000)
|
||||
#define UNI_COLON cpu_to_le16(':' + 0xF000)
|
||||
#define UNI_GRTRTHAN cpu_to_le16('>' + 0xF000)
|
||||
#define UNI_LESSTHAN cpu_to_le16('<' + 0xF000)
|
||||
#define UNI_PIPE cpu_to_le16('|' + 0xF000)
|
||||
#define UNI_SLASH cpu_to_le16('\\' + 0xF000)
|
||||
|
||||
/* Convert 16 bit Unicode pathname from wire format to 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
|
||||
cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
|
||||
const struct nls_table * cp)
|
||||
{
|
||||
int i,j,len;
|
||||
wchar_t src_char;
|
||||
|
||||
for(i = 0, j = 0; i < maxlen; i++) {
|
||||
src_char = le16_to_cpu(source[i]);
|
||||
switch (src_char) {
|
||||
case 0:
|
||||
goto cUCS_out; /* BB check this BB */
|
||||
case UNI_COLON:
|
||||
target[j] = ':';
|
||||
break;
|
||||
case UNI_ASTERIK:
|
||||
target[j] = '*';
|
||||
break;
|
||||
case UNI_QUESTION:
|
||||
target[j] = '?';
|
||||
break;
|
||||
case UNI_SLASH:
|
||||
target[j] = '\\'; /* BB check this - is there risk here of converting path sep BB */
|
||||
break;
|
||||
case UNI_PIPE:
|
||||
target[j] = '|';
|
||||
break;
|
||||
case UNI_GRTRTHAN:
|
||||
target[j] = '>';
|
||||
break;
|
||||
case UNI_LESSTHAN:
|
||||
target[j] = '<';
|
||||
default:
|
||||
len = cp->uni2char(src_char, &target[j],
|
||||
NLS_MAX_CHARSET_SIZE);
|
||||
if(len > 0) {
|
||||
j += len;
|
||||
continue;
|
||||
} else {
|
||||
target[j] = '?';
|
||||
}
|
||||
}
|
||||
j++;
|
||||
/* check to make sure we do not overrun callers allocated temp buffer */
|
||||
if(j >= (2 * NAME_MAX))
|
||||
break;
|
||||
}
|
||||
cUCS_out:
|
||||
target[j] = 0;
|
||||
return j;
|
||||
}
|
||||
#endif /* CIFS_EXPERIMENTAL */
|
||||
|
|
|
@ -600,7 +600,14 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
|
|||
if(unicode) {
|
||||
/* BB fixme - test with long names */
|
||||
/* Note converted filename can be longer than in unicode */
|
||||
pqst->len = cifs_strfromUCS_le((char *)pqst->name,(wchar_t *)filename,len/2,nlt);
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
pqst->len = cifs_convertUCSpath((char *)pqst->name,
|
||||
(__le16 *)filename, len/2, nlt);
|
||||
else
|
||||
#endif /* CIFS_EXPERIMENTAL */
|
||||
pqst->len = cifs_strfromUCS_le((char *)pqst->name,
|
||||
(wchar_t *)filename,len/2,nlt);
|
||||
} else {
|
||||
pqst->name = filename;
|
||||
pqst->len = len;
|
||||
|
@ -829,7 +836,11 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||
end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
|
||||
smbCalcSize((struct smb_hdr *)
|
||||
cifsFile->srch_inf.ntwrk_buf_start);
|
||||
tmp_buf = kmalloc(NAME_MAX+1,GFP_KERNEL);
|
||||
/* To be safe - for UCS to UTF-8 with strings loaded
|
||||
with the rare long characters alloc more to account for
|
||||
such multibyte target UTF-8 characters. cifs_unicode.c,
|
||||
which actually does the conversion, has the same limit */
|
||||
tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
|
||||
for(i=0;(i<num_to_fill) && (rc == 0);i++) {
|
||||
if(current_entry == NULL) {
|
||||
/* evaluate whether this case is an error */
|
||||
|
|
Loading…
Reference in a new issue