diff options
-rw-r--r-- | fs/cifs/CHANGES | 2 | ||||
-rw-r--r-- | fs/cifs/cifs_unicode.c | 13 | ||||
-rw-r--r-- | fs/cifs/cifs_unicode.h | 6 | ||||
-rw-r--r-- | fs/cifs/cifsencrypt.c | 2 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 40 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 43 | ||||
-rw-r--r-- | fs/cifs/connect.c | 91 | ||||
-rw-r--r-- | fs/cifs/inode.c | 114 | ||||
-rw-r--r-- | fs/cifs/misc.c | 2 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 12 |
11 files changed, 218 insertions, 109 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index eab3750cf30..289e4079c96 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -3,6 +3,8 @@ Version 1.39 Defer close of a file handle slightly if pending writes depend on that file handle (this reduces the EBADF bad file handle errors that can be logged under heavy stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 +Fix SFU style symlinks and mknod needed for servers which do not support the CIFS +Unix Extensions. Version 1.38 ------------ diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 4e12053f080..d2b12825594 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -1,7 +1,7 @@ /* * fs/cifs/cifs_unicode.c * - * Copyright (c) International Business Machines Corp., 2000,2002 + * Copyright (c) International Business Machines Corp., 2000,2005 * Modified by Steve French (sfrench@us.ibm.com) * * This program is free software; you can redistribute it and/or modify @@ -31,7 +31,7 @@ * */ int -cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ +cifs_strfromUCS_le(char *to, const __le16 * from, int len, const struct nls_table *codepage) { int i; @@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ * */ int -cifs_strtoUCS(wchar_t * to, const char *from, int len, +cifs_strtoUCS(__le16 * to, const char *from, int len, const struct nls_table *codepage) { int charlen; int i; + wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */ for (i = 0; len && *from; i++, from += charlen, len -= charlen) { /* works for 2.4.0 kernel or later */ - charlen = codepage->char2uni(from, len, &to[i]); + charlen = codepage->char2uni(from, len, &wchar_to[i]); if (charlen < 1) { cERROR(1, ("cifs_strtoUCS: char2uni returned %d", charlen)); /* A question mark */ - to[i] = (wchar_t)cpu_to_le16(0x003f); + to[i] = cpu_to_le16(0x003f); charlen = 1; } else - to[i] = (wchar_t)cpu_to_le16(to[i]); + to[i] = cpu_to_le16(wchar_to[i]); } diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index da8dde96527..39e5b970325 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h @@ -5,7 +5,7 @@ * Convert a unicode character to upper or lower case using * compressed tables. * - * Copyright (c) International Business Machines Corp., 2000,2002 + * Copyright (c) International Business Machines Corp., 2000,2005555555555555555555555555555555555555555555555555555555 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[]; #endif /* UNIUPR_NOLOWER */ #ifdef __KERNEL__ -int cifs_strfromUCS_le(char *, const wchar_t *, int, const struct nls_table *); -int cifs_strtoUCS(wchar_t *, const char *, int, const struct nls_table *); +int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *); +int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); #endif /* diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 1959c7c4b18..fe2bb7c4c91 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_ char temp_hash[16]; struct HMACMD5Context ctx; char * ucase_buf; - wchar_t * unicode_buf; + __le16 * unicode_buf; unsigned int i,user_name_len,dom_name_len; if(ses == NULL) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 682b0235ad9..1433455c61e 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -635,6 +635,46 @@ struct file_operations cifs_file_direct_ops = { .dir_notify = cifs_dir_notify, #endif /* CONFIG_CIFS_EXPERIMENTAL */ }; +struct file_operations cifs_file_nobrl_ops = { + .read = cifs_read_wrapper, + .write = cifs_write_wrapper, + .open = cifs_open, + .release = cifs_close, + .fsync = cifs_fsync, + .flush = cifs_flush, + .mmap = cifs_file_mmap, + .sendfile = generic_file_sendfile, +#ifdef CONFIG_CIFS_POSIX + .ioctl = cifs_ioctl, +#endif /* CONFIG_CIFS_POSIX */ + +#ifdef CONFIG_CIFS_EXPERIMENTAL + .readv = generic_file_readv, + .writev = generic_file_writev, + .aio_read = generic_file_aio_read, + .aio_write = generic_file_aio_write, + .dir_notify = cifs_dir_notify, +#endif /* CONFIG_CIFS_EXPERIMENTAL */ +}; + +struct file_operations cifs_file_direct_nobrl_ops = { + /* no mmap, no aio, no readv - + BB reevaluate whether they can be done with directio, no cache */ + .read = cifs_user_read, + .write = cifs_user_write, + .open = cifs_open, + .release = cifs_close, + .fsync = cifs_fsync, + .flush = cifs_flush, + .sendfile = generic_file_sendfile, /* BB removeme BB */ +#ifdef CONFIG_CIFS_POSIX + .ioctl = cifs_ioctl, +#endif /* CONFIG_CIFS_POSIX */ + +#ifdef CONFIG_CIFS_EXPERIMENTAL + .dir_notify = cifs_dir_notify, +#endif /* CONFIG_CIFS_EXPERIMENTAL */ +}; struct file_operations cifs_dir_ops = { .readdir = cifs_readdir, diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 1223fa81dbd..9ec40e0e54f 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops; /* Functions related to files and directories */ extern struct file_operations cifs_file_ops; extern struct file_operations cifs_file_direct_ops; /* if directio mount */ +extern struct file_operations cifs_file_nobrl_ops; +extern struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */ extern int cifs_open(struct inode *inode, struct file *file); extern int cifs_close(struct inode *inode, struct file *file); extern int cifs_closedir(struct inode *inode, struct file *file); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index a53c596e108..d179b0c3eee 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, int bytes_returned, wct; int smb_hdr_len; - cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ + /* BB removeme BB */ + cFYI(1,("write2 at %lld %d bytes", (long long)offset, count)); + if(tcon->ses->capabilities & CAP_LARGE_FILES) wct = 14; else @@ -1553,7 +1555,7 @@ createSymLinkRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX + cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX /* find define for this maxpathcomponent */ , nls_codepage); name_len++; /* trailing null */ @@ -1577,7 +1579,7 @@ createSymLinkRetry: data_offset = (char *) (&pSMB->hdr.Protocol) + offset; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len_target = - cifs_strtoUCS((wchar_t *) data_offset, toName, PATH_MAX + cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX /* find define for this maxpathcomponent */ , nls_codepage); name_len_target++; /* trailing null */ @@ -1803,7 +1805,7 @@ querySymLinkRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = - cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX + cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX /* find define for this maxpathcomponent */ , nls_codepage); name_len++; /* trailing null */ @@ -1860,7 +1862,7 @@ querySymLinkRetry: min_t(const int, buflen,count) / 2); /* BB FIXME investigate remapping reserved chars here */ cifs_strfromUCS_le(symlinkinfo, - (wchar_t *) ((char *)&pSMBr->hdr.Protocol + + (__le16 *) ((char *)&pSMBr->hdr.Protocol + data_offset), name_len, nls_codepage); } else { @@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, reparse_buf->TargetNameOffset), min(buflen/2, reparse_buf->TargetNameLen / 2)); cifs_strfromUCS_le(symlinkinfo, - (wchar_t *) (reparse_buf->LinkNamesBuf + + (__le16 *) (reparse_buf->LinkNamesBuf + reparse_buf->TargetNameOffset), name_len, nls_codepage); } else { /* ASCII names */ @@ -1983,9 +1985,9 @@ qreparse_out: static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace) { /* u8 cifs fields do not need le conversion */ - ace->e_perm = (__u16)cifs_ace->cifs_e_perm; - ace->e_tag = (__u16)cifs_ace->cifs_e_tag; - ace->e_id = (__u32)le64_to_cpu(cifs_ace->cifs_uid); + ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm); + ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag); + ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid)); /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */ return; @@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen, } else if(size > buflen) { return -ERANGE; } else /* buffer big enough */ { - local_acl->a_version = POSIX_ACL_XATTR_VERSION; + local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); for(i = 0;i < count ;i++) { cifs_convert_ace(&local_acl->a_entries[i],pACE); pACE ++; @@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace, { __u16 rc = 0; /* 0 = ACL converted ok */ - cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm); - cifs_ace->cifs_e_tag = (__u8)cpu_to_le16(local_ace->e_tag); + cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm); + cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag); /* BB is there a better way to handle the large uid? */ - if(local_ace->e_id == -1) { + if(local_ace->e_id == cpu_to_le32(-1)) { /* Probably no need to le convert -1 on any arch but can not hurt */ cifs_ace->cifs_uid = cpu_to_le64(-1); } else - cifs_ace->cifs_uid = (__u64)cpu_to_le32(local_ace->e_id); + cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id)); /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/ return rc; } @@ -2078,16 +2080,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl count = posix_acl_xattr_count((size_t)buflen); cFYI(1,("setting acl with %d entries from buf of length %d and version of %d", - count,buflen,local_acl->a_version)); - if(local_acl->a_version != 2) { - cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version)); + count, buflen, le32_to_cpu(local_acl->a_version))); + if(le32_to_cpu(local_acl->a_version) != 2) { + cFYI(1,("unknown POSIX ACL version %d", + le32_to_cpu(local_acl->a_version))); return 0; } cifs_acl->version = cpu_to_le16(1); if(acl_type == ACL_TYPE_ACCESS) - cifs_acl->access_entry_count = count; + cifs_acl->access_entry_count = cpu_to_le16(count); else if(acl_type == ACL_TYPE_DEFAULT) - cifs_acl->default_entry_count = count; + cifs_acl->default_entry_count = cpu_to_le16(count); else { cFYI(1,("unknown ACL type %d",acl_type)); return 0; @@ -3203,7 +3206,7 @@ getDFSRetry: temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset); if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { cifs_strfromUCS_le(*targetUNCs, - (wchar_t *) temp, name_len, nls_codepage); + (__le16 *) temp, name_len, nls_codepage); } else { strncpy(*targetUNCs,temp,name_len); } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2cb620716bc..c467de85761 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1986,32 +1986,32 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, bytes_returned = 0; /* skill null user */ else bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, + cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage); /* convert number of 16 bit words to bytes */ bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; /* trailing null */ if (domain == NULL) bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, + cifs_strtoUCS((__le16 *) bcc_ptr, "CIFS_LINUX_DOM", 32, nls_codepage); else bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, + cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", + cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ", 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, + cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, + cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 64, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; @@ -2081,7 +2081,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, if(ses->serverOS == NULL) goto sesssetup_nomem; cifs_strfromUCS_le(ses->serverOS, - (wchar_t *)bcc_ptr, len,nls_codepage); + (__le16 *)bcc_ptr, len,nls_codepage); bcc_ptr += 2 * (len + 1); remaining_words -= len + 1; ses->serverOS[2 * len] = 0; @@ -2093,7 +2093,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, if(ses->serverNOS == NULL) goto sesssetup_nomem; cifs_strfromUCS_le(ses->serverNOS, - (wchar_t *)bcc_ptr,len,nls_codepage); + (__le16 *)bcc_ptr,len,nls_codepage); bcc_ptr += 2 * (len + 1); ses->serverNOS[2 * len] = 0; ses->serverNOS[1 + (2 * len)] = 0; @@ -2111,7 +2111,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, if(ses->serverDomain == NULL) goto sesssetup_nomem; cifs_strfromUCS_le(ses->serverDomain, - (wchar_t *)bcc_ptr,len,nls_codepage); + (__le16 *)bcc_ptr,len,nls_codepage); bcc_ptr += 2 * (len + 1); ses->serverDomain[2*len] = 0; ses->serverDomain[1+(2*len)] = 0; @@ -2255,30 +2255,30 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, bcc_ptr++; } bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage); + cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage); bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */ bcc_ptr += 2; /* trailing null */ if (domain == NULL) bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, + cifs_strtoUCS((__le16 *) bcc_ptr, "CIFS_LINUX_DOM", 32, nls_codepage); else bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, + cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", + cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ", 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, + cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, + cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 64, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; @@ -2357,7 +2357,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); cifs_strfromUCS_le(ses->serverOS, - (wchar_t *) + (__le16 *) bcc_ptr, len, nls_codepage); bcc_ptr += 2 * (len + 1); @@ -2372,7 +2372,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, kzalloc(2 * (len + 1), GFP_KERNEL); cifs_strfromUCS_le(ses->serverNOS, - (wchar_t *)bcc_ptr, + (__le16 *)bcc_ptr, len, nls_codepage); bcc_ptr += 2 * (len + 1); @@ -2384,9 +2384,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); cifs_strfromUCS_le(ses->serverDomain, - (wchar_t *)bcc_ptr, - len, - nls_codepage); + (__le16 *)bcc_ptr, + len, nls_codepage); bcc_ptr += 2*(len+1); ses->serverDomain[2*len] = 0; ses->serverDomain[1+(2*len)] = 0; @@ -2560,16 +2559,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, } bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", + cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ", 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, + cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; /* null terminate Linux version */ bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, + cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 64, nls_codepage); bcc_ptr += 2 * bytes_returned; *(bcc_ptr + 1) = 0; @@ -2673,7 +2672,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); cifs_strfromUCS_le(ses->serverOS, - (wchar_t *) + (__le16 *) bcc_ptr, len, nls_codepage); bcc_ptr += 2 * (len + 1); @@ -2690,7 +2689,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, GFP_KERNEL); cifs_strfromUCS_le(ses-> serverNOS, - (wchar_t *) + (__le16 *) bcc_ptr, len, nls_codepage); @@ -2708,23 +2707,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, 1), GFP_KERNEL); cifs_strfromUCS_le - (ses-> - serverDomain, - (wchar_t *) - bcc_ptr, len, - nls_codepage); + (ses->serverDomain, + (__le16 *)bcc_ptr, + len, nls_codepage); bcc_ptr += 2 * (len + 1); - ses-> - serverDomain[2 - * len] + ses->serverDomain[2*len] = 0; - ses-> - serverDomain[1 - + - (2 - * - len)] + ses->serverDomain + [1 + (2 * len)] = 0; } /* else no more room so create dummy domain string */ else @@ -2903,7 +2894,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, SecurityBlob->DomainName.MaximumLength = 0; } else { __u16 len = - cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, + cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, nls_codepage); len *= 2; SecurityBlob->DomainName.MaximumLength = @@ -2921,7 +2912,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, SecurityBlob->UserName.MaximumLength = 0; } else { __u16 len = - cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64, + cifs_strtoUCS((__le16 *) bcc_ptr, user, 64, nls_codepage); len *= 2; SecurityBlob->UserName.MaximumLength = @@ -2934,7 +2925,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, cpu_to_le16(len); } - /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage); + /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage); SecurityBlob->WorkstationName.Length *= 2; SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length); SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength); @@ -2947,16 +2938,16 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, bcc_ptr++; } bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", + cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ", 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, + cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32, nls_codepage); bcc_ptr += 2 * bytes_returned; bcc_ptr += 2; /* null term version string */ bytes_returned = - cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, + cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 64, nls_codepage); bcc_ptr += 2 * bytes_returned; *(bcc_ptr + 1) = 0; @@ -3069,7 +3060,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL); cifs_strfromUCS_le(ses->serverOS, - (wchar_t *) + (__le16 *) bcc_ptr, len, nls_codepage); bcc_ptr += 2 * (len + 1); @@ -3086,7 +3077,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, GFP_KERNEL); cifs_strfromUCS_le(ses-> serverNOS, - (wchar_t *) + (__le16 *) bcc_ptr, len, nls_codepage); @@ -3105,7 +3096,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, cifs_strfromUCS_le (ses-> serverDomain, - (wchar_t *) + (__le16 *) bcc_ptr, len, nls_codepage); bcc_ptr += @@ -3227,7 +3218,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, if (ses->capabilities & CAP_UNICODE) { smb_buffer->Flags2 |= SMBFLG2_UNICODE; length = - cifs_strtoUCS((wchar_t *) bcc_ptr, tree, 100, nls_codepage); + cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage); bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ bcc_ptr += 2; /* skip trailing null */ } else { /* ASCII */ @@ -3263,7 +3254,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, tcon->nativeFileSystem = kzalloc(length + 2, GFP_KERNEL); cifs_strfromUCS_le(tcon->nativeFileSystem, - (wchar_t *) bcc_ptr, + (__le16 *) bcc_ptr, length, nls_codepage); bcc_ptr += 2 * length; bcc_ptr[0] = 0; /* null terminate the string */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 923d071163b..ba9eae56d01 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, inode = *pinode; cifsInfo = CIFS_I(inode); - cFYI(1, (" Old time %ld ", cifsInfo->time)); + cFYI(1, ("Old time %ld ", cifsInfo->time)); cifsInfo->time = jiffies; - cFYI(1, (" New time %ld ", cifsInfo->time)); + cFYI(1, ("New time %ld ", cifsInfo->time)); /* this is ok to set on every inode revalidate */ atomic_set(&cifsInfo->inUse,1); @@ -155,34 +155,39 @@ int cifs_get_inode_info_unix(struct inode **pinode, } if (num_of_bytes < end_of_file) - cFYI(1, ("allocation size less than end of file ")); + cFYI(1, ("allocation size less than end of file")); cFYI(1, ("Size %ld and blocks %ld", (unsigned long) inode->i_size, inode->i_blocks)); if (S_ISREG(inode->i_mode)) { - cFYI(1, (" File inode ")); + cFYI(1, ("File inode")); inode->i_op = &cifs_file_inode_ops; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) - inode->i_fop = &cifs_file_direct_ops; - else + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop = + &cifs_file_direct_nobrl_ops; + else + inode->i_fop = &cifs_file_direct_ops; + } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop = &cifs_file_nobrl_ops; + else /* not direct, send byte range locks */ inode->i_fop = &cifs_file_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - inode->i_fop->lock = NULL; + inode->i_data.a_ops = &cifs_addr_ops; /* check if server can support readpages */ if(pTcon->ses->server->maxBuf < 4096 + MAX_CIFS_HDR_SIZE) inode->i_data.a_ops->readpages = NULL; } else if (S_ISDIR(inode->i_mode)) { - cFYI(1, (" Directory inode")); + cFYI(1, ("Directory inode")); inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } else if (S_ISLNK(inode->i_mode)) { - cFYI(1, (" Symbolic Link inode ")); + cFYI(1, ("Symbolic Link inode")); inode->i_op = &cifs_symlink_inode_ops; /* tmp_inode->i_fop = */ /* do not need to set to anything */ } else { - cFYI(1, (" Init special inode ")); + cFYI(1, ("Init special inode")); init_special_inode(inode, inode->i_mode, inode->i_rdev); } @@ -190,6 +195,55 @@ int cifs_get_inode_info_unix(struct inode **pinode, return rc; } +static int decode_sfu_inode(struct inode * inode, __u64 size, + const unsigned char *path, + struct cifs_sb_info *cifs_sb, int xid) +{ + int rc; + int oplock = FALSE; + __u16 netfid; + struct cifsTconInfo *pTcon = cifs_sb->tcon; + char buf[8]; + unsigned int bytes_read; + char * pbuf; + + pbuf = buf; + + if(size == 0) { + inode->i_mode |= S_IFIFO; + return 0; + } else if (size < 8) { + return -EINVAL; /* EOPNOTSUPP? */ + } + + rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, + CREATE_NOT_DIR, &netfid, &oplock, NULL, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc==0) { + /* Read header */ + rc = CIFSSMBRead(xid, pTcon, + netfid, + 8 /* length */, 0 /* offset */, + &bytes_read, &pbuf); + if((rc == 0) && (bytes_read == 8)) { + /* if memcmp(IntxCHR\000, pbuf, 8) + else if memcmp(IntxBLK\000, pbuf, 8) + else if memcmp(IntxLNK\001, pbuf, 8) */ + } + + CIFSSMBClose(xid, pTcon, netfid); + + + /* inode->i_rdev = MKDEV(le64_to_cpu(DevMajor), + le64_to_cpu(DevMinor) & MINORMASK);*/ +/* inode->i_mode |= S_IFBLK; */ + } + return rc; + +} + int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO *pfindData, struct super_block *sb, int xid) @@ -202,7 +256,7 @@ int cifs_get_inode_info(struct inode **pinode, char *buf = NULL; pTcon = cifs_sb->tcon; - cFYI(1,("Getting info on %s ", search_path)); + cFYI(1,("Getting info on %s", search_path)); if ((pfindData == NULL) && (*pinode != NULL)) { if (CIFS_I(*pinode)->clientCanCacheRead) { @@ -340,10 +394,15 @@ int cifs_get_inode_info(struct inode **pinode, (pfindData->EndOfFile == 0)) { inode->i_mode = cifs_sb->mnt_file_mode; inode->i_mode |= S_IFIFO; -/* BB Finish for SFU style symlinks and devies */ -/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && - (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */ - +/* BB Finish for SFU style symlinks and devices */ + } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { + if (decode_sfu_inode(inode, + le64_to_cpu(pfindData->EndOfFile), + search_path, + cifs_sb, xid)) { + cFYI(1,("Unrecognized sfu inode type")); + } } else { inode->i_mode |= S_IFREG; /* treat the dos attribute of read-only as read-only @@ -377,24 +436,29 @@ int cifs_get_inode_info(struct inode **pinode, } if (S_ISREG(inode->i_mode)) { - cFYI(1, (" File inode ")); + cFYI(1, ("File inode")); inode->i_op = &cifs_file_inode_ops; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) - inode->i_fop = &cifs_file_direct_ops; - else + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop = + &cifs_file_direct_nobrl_ops; + else + inode->i_fop = &cifs_file_direct_ops; + } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop = &cifs_file_nobrl_ops; + else /* not direct, send byte range locks */ inode->i_fop = &cifs_file_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - inode->i_fop->lock = NULL; + inode->i_data.a_ops = &cifs_addr_ops; if(pTcon->ses->server->maxBuf < 4096 + MAX_CIFS_HDR_SIZE) inode->i_data.a_ops->readpages = NULL; } else if (S_ISDIR(inode->i_mode)) { - cFYI(1, (" Directory inode ")); + cFYI(1, ("Directory inode")); inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } else if (S_ISLNK(inode->i_mode)) { - cFYI(1, (" Symbolic Link inode ")); + cFYI(1, ("Symbolic Link inode")); inode->i_op = &cifs_symlink_inode_ops; } else { init_special_inode(inode, inode->i_mode, diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 34a06692e4f..ca27a82c54c 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -678,7 +678,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen, __u16 temp; if(!mapChars) - return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); + return cifs_strtoUCS(target, source, PATH_MAX, cp); for(i = 0, j = 0; i < maxlen; j++) { src_char = source[i]; diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index a86bd1c0760..9b7e0ff9584 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -193,8 +193,14 @@ static void fill_in_inode(struct inode *tmp_inode, if (S_ISREG(tmp_inode->i_mode)) { cFYI(1, ("File inode")); tmp_inode->i_op = &cifs_file_inode_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) - tmp_inode->i_fop = &cifs_file_direct_ops; + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; + else + tmp_inode->i_fop = &cifs_file_direct_ops; + + } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + tmp_inode->i_fop = &cifs_file_nobrl_ops; else tmp_inode->i_fop = &cifs_file_ops; if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) @@ -699,7 +705,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, (__le16 *)filename, len/2, nlt); else pqst->len = cifs_strfromUCS_le((char *)pqst->name, - (wchar_t *)filename,len/2,nlt); + (__le16 *)filename,len/2,nlt); } else { pqst->name = filename; pqst->len = len; |