···4444 int charlen, outlen = 0;4545 int maxwords = maxbytes / 2;4646 char tmp[NLS_MAX_CHARSET_SIZE];4747+ __u16 ftmp;47484848- for (i = 0; i < maxwords && from[i]; i++) {4949- charlen = codepage->uni2char(le16_to_cpu(from[i]), tmp,5050- NLS_MAX_CHARSET_SIZE);4949+ for (i = 0; i < maxwords; i++) {5050+ ftmp = get_unaligned_le16(&from[i]);5151+ if (ftmp == 0)5252+ break;5353+5454+ charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE);5155 if (charlen > 0)5256 outlen += charlen;5357 else···6258}63596460/*6565- * cifs_mapchar - convert a little-endian char to proper char in codepage6161+ * cifs_mapchar - convert a host-endian char to proper char in codepage6662 * @target - where converted character should be copied6767- * @src_char - 2 byte little-endian source character6363+ * @src_char - 2 byte host-endian source character6864 * @cp - codepage to which character should be converted6965 * @mapchar - should character be mapped according to mapchars mount option?7066 *···7369 * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).7470 */7571static int7676-cifs_mapchar(char *target, const __le16 src_char, const struct nls_table *cp,7272+cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,7773 bool mapchar)7874{7975 int len = 1;···8682 * build_path_from_dentry are modified, as they use slash as8783 * separator.8884 */8989- switch (le16_to_cpu(src_char)) {8585+ switch (src_char) {9086 case UNI_COLON:9187 *target = ':';9288 break;···113109 return len;114110115111cp_convert:116116- len = cp->uni2char(le16_to_cpu(src_char), target,117117- NLS_MAX_CHARSET_SIZE);112112+ len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE);118113 if (len <= 0) {119114 *target = '?';120115 len = 1;···152149 int nullsize = nls_nullsize(codepage);153150 int fromwords = fromlen / 2;154151 char tmp[NLS_MAX_CHARSET_SIZE];152152+ __u16 ftmp;155153156154 /*157155 * because the chars can be of varying widths, we need to take care···162158 */163159 safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);164160165165- for (i = 0; i < fromwords && from[i]; i++) {161161+ for (i = 0; i < fromwords; i++) {162162+ ftmp = get_unaligned_le16(&from[i]);163163+ if (ftmp == 0)164164+ break;165165+166166 /*167167 * check to see if converting this character might make the168168 * conversion bleed into the null terminator169169 */170170 if (outlen >= safelen) {171171- charlen = cifs_mapchar(tmp, from[i], codepage, mapchar);171171+ charlen = cifs_mapchar(tmp, ftmp, codepage, mapchar);172172 if ((outlen + charlen) > (tolen - nullsize))173173 break;174174 }175175176176 /* put converted char into 'to' buffer */177177- charlen = cifs_mapchar(&to[outlen], from[i], codepage, mapchar);177177+ charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar);178178 outlen += charlen;179179 }180180···201193{202194 int charlen;203195 int i;204204- wchar_t *wchar_to = (wchar_t *)to; /* needed to quiet sparse */196196+ wchar_t wchar_to; /* needed to quiet sparse */205197206198 for (i = 0; len && *from; i++, from += charlen, len -= charlen) {207207-208208- /* works for 2.4.0 kernel or later */209209- charlen = codepage->char2uni(from, len, &wchar_to[i]);199199+ charlen = codepage->char2uni(from, len, &wchar_to);210200 if (charlen < 1) {211211- cERROR(1, "strtoUCS: char2uni of %d returned %d",212212- (int)*from, charlen);201201+ cERROR(1, "strtoUCS: char2uni of 0x%x returned %d",202202+ *from, charlen);213203 /* A question mark */214214- to[i] = cpu_to_le16(0x003f);204204+ wchar_to = 0x003f;215205 charlen = 1;216216- } else217217- to[i] = cpu_to_le16(wchar_to[i]);218218-206206+ }207207+ put_unaligned_le16(wchar_to, &to[i]);219208 }220209221221- to[i] = 0;210210+ put_unaligned_le16(0, &to[i]);222211 return i;223212}224213···255250 }256251257252 return dst;253253+}254254+255255+/*256256+ * Convert 16 bit Unicode pathname to wire format from string in current code257257+ * page. Conversion may involve remapping up the six characters that are258258+ * only legal in POSIX-like OS (if they are present in the string). Path259259+ * names are little endian 16 bit Unicode on the wire260260+ */261261+int262262+cifsConvertToUCS(__le16 *target, const char *source, int maxlen,263263+ const struct nls_table *cp, int mapChars)264264+{265265+ int i, j, charlen;266266+ int len_remaining = maxlen;267267+ char src_char;268268+ __u16 temp;269269+270270+ if (!mapChars)271271+ return cifs_strtoUCS(target, source, PATH_MAX, cp);272272+273273+ for (i = 0, j = 0; i < maxlen; j++) {274274+ src_char = source[i];275275+ switch (src_char) {276276+ case 0:277277+ put_unaligned_le16(0, &target[j]);278278+ goto ctoUCS_out;279279+ case ':':280280+ temp = UNI_COLON;281281+ break;282282+ case '*':283283+ temp = UNI_ASTERIK;284284+ break;285285+ case '?':286286+ temp = UNI_QUESTION;287287+ break;288288+ case '<':289289+ temp = UNI_LESSTHAN;290290+ break;291291+ case '>':292292+ temp = UNI_GRTRTHAN;293293+ break;294294+ case '|':295295+ temp = UNI_PIPE;296296+ break;297297+ /*298298+ * FIXME: We can not handle remapping backslash (UNI_SLASH)299299+ * until all the calls to build_path_from_dentry are modified,300300+ * as they use backslash as separator.301301+ */302302+ default:303303+ charlen = cp->char2uni(source+i, len_remaining,304304+ &temp);305305+ /*306306+ * if no match, use question mark, which at least in307307+ * some cases serves as wild card308308+ */309309+ if (charlen < 1) {310310+ temp = 0x003f;311311+ charlen = 1;312312+ }313313+ len_remaining -= charlen;314314+ /*315315+ * character may take more than one byte in the source316316+ * string, but will take exactly two bytes in the317317+ * target string318318+ */319319+ i += charlen;320320+ continue;321321+ }322322+ put_unaligned_le16(temp, &target[j]);323323+ i++; /* move to next char in source string */324324+ len_remaining--;325325+ }326326+327327+ctoUCS_out:328328+ return i;258329}259330
···6161 struct dentry *);6262extern int cifs_revalidate_file(struct file *filp);6363extern int cifs_revalidate_dentry(struct dentry *);6464+extern void cifs_invalidate_mapping(struct inode *inode);6465extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);6566extern int cifs_setattr(struct dentry *, struct iattr *);6667···7372/* Functions related to files and directories */7473extern const struct file_operations cifs_file_ops;7574extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */7676-extern const struct file_operations cifs_file_nobrl_ops;7777-extern const struct file_operations cifs_file_direct_nobrl_ops; /* no brlocks */7575+extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */7676+extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */7777+extern const struct file_operations cifs_file_direct_nobrl_ops;7878+extern const struct file_operations cifs_file_strict_nobrl_ops;7879extern int cifs_open(struct inode *inode, struct file *file);7980extern int cifs_close(struct inode *inode, struct file *file);8081extern int cifs_closedir(struct inode *inode, struct file *file);8182extern ssize_t cifs_user_read(struct file *file, char __user *read_data,8282- size_t read_size, loff_t *poffset);8383+ size_t read_size, loff_t *poffset);8484+extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,8585+ unsigned long nr_segs, loff_t pos);8386extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,8487 size_t write_size, loff_t *poffset);8588extern int cifs_lock(struct file *, int, struct file_lock *);8689extern int cifs_fsync(struct file *, int);9090+extern int cifs_strict_fsync(struct file *, int);8791extern int cifs_flush(struct file *, fl_owner_t id);8892extern int cifs_file_mmap(struct file * , struct vm_area_struct *);9393+extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *);8994extern const struct file_operations cifs_dir_ops;9095extern int cifs_dir_open(struct inode *inode, struct file *file);9196extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
+14-22
fs/cifs/cifsglob.h
···161161 int srv_count; /* reference counter */162162 /* 15 character server name + 0x20 16th byte indicating type = srv */163163 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];164164+ enum statusEnum tcpStatus; /* what we think the status is */164165 char *hostname; /* hostname portion of UNC string */165166 struct socket *ssocket;166167 struct sockaddr_storage dstaddr;···169168 wait_queue_head_t response_q;170169 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/171170 struct list_head pending_mid_q;172172- void *Server_NlsInfo; /* BB - placeholder for future NLS info */173173- unsigned short server_codepage; /* codepage for the server */174174- enum protocolEnum protocolType;175175- char versionMajor;176176- char versionMinor;177177- bool svlocal:1; /* local server or remote */178171 bool noblocksnd; /* use blocking sendmsg */179172 bool noautotune; /* do not autotune send buf sizes */180173 bool tcp_nodelay;181174 atomic_t inFlight; /* number of requests on the wire to server */182182-#ifdef CONFIG_CIFS_STATS2183183- atomic_t inSend; /* requests trying to send */184184- atomic_t num_waiters; /* blocked waiting to get in sendrecv */185185-#endif186186- enum statusEnum tcpStatus; /* what we think the status is */187175 struct mutex srv_mutex;188176 struct task_struct *tsk;189177 char server_GUID[16];190178 char secMode;179179+ bool session_estab; /* mark when very first sess is established */180180+ u16 dialect; /* dialect index that server chose */191181 enum securityEnum secType;192182 unsigned int maxReq; /* Clients should submit no more */193183 /* than maxReq distinct unanswered SMBs to the server when using */···191199 unsigned int max_vcs; /* maximum number of smb sessions, at least192200 those that can be specified uniquely with193201 vcnumbers */194194- char sessid[4]; /* unique token id for this session */195195- /* (returned on Negotiate */196202 int capabilities; /* allow selective disabling of caps by smb sess */197203 int timeAdj; /* Adjust for difference in server time zone in sec */198204 __u16 CurrentMid; /* multiplex id - rotating counter */···200210 __u32 sequence_number; /* for signing, protected by srv_mutex */201211 struct session_key session_key;202212 unsigned long lstrp; /* when we got last response from this server */203203- u16 dialect; /* dialect index that server chose */204213 struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */205214 /* extended security flavors that server supports */215215+ bool sec_ntlmssp; /* supports NTLMSSP */216216+ bool sec_kerberosu2u; /* supports U2U Kerberos */206217 bool sec_kerberos; /* supports plain Kerberos */207218 bool sec_mskerberos; /* supports legacy MS Kerberos */208208- bool sec_kerberosu2u; /* supports U2U Kerberos */209209- bool sec_ntlmssp; /* supports NTLMSSP */210210- bool session_estab; /* mark when very first sess is established */211219 struct delayed_work echo; /* echo ping workqueue job */212220#ifdef CONFIG_CIFS_FSCACHE213221 struct fscache_cookie *fscache; /* client index cache cookie */222222+#endif223223+#ifdef CONFIG_CIFS_STATS2224224+ atomic_t inSend; /* requests trying to send */225225+ atomic_t num_waiters; /* blocked waiting to get in sendrecv */214226#endif215227};216228···439447 /* BB add in lists for dirty pages i.e. write caching info for oplock */440448 struct list_head openFileList;441449 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */442442- unsigned long time; /* jiffies of last update/check of inode */443443- bool clientCanCacheRead:1; /* read oplock */444444- bool clientCanCacheAll:1; /* read and writebehind oplock */445445- bool delete_pending:1; /* DELETE_ON_CLOSE is set */446446- bool invalid_mapping:1; /* pagecache is invalid */450450+ bool clientCanCacheRead; /* read oplock */451451+ bool clientCanCacheAll; /* read and writebehind oplock */452452+ bool delete_pending; /* DELETE_ON_CLOSE is set */453453+ bool invalid_mapping; /* pagecache is invalid */454454+ unsigned long time; /* jiffies of last update of inode */447455 u64 server_eof; /* current file size on server */448456 u64 uniqueid; /* server inode number */449457 u64 createtime; /* creation time on server */
+43-4
fs/cifs/cifspdu.h
···2323#define _CIFSPDU_H24242525#include <net/sock.h>2626+#include <asm/unaligned.h>2627#include "smbfsctl.h"27282829#ifdef CONFIG_CIFS_WEAK_PW_HASH···427426 __u16 Mid;428427 __u8 WordCount;429428} __attribute__((packed));430430-/* given a pointer to an smb_hdr retrieve the value of byte count */431431-#define BCC(smb_var) (*(__u16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))432432-#define BCC_LE(smb_var) (*(__le16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))429429+430430+/* given a pointer to an smb_hdr retrieve a char pointer to the byte count */431431+#define BCC(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + \432432+ (2 * (smb_var)->WordCount))433433+433434/* given a pointer to an smb_hdr retrieve the pointer to the byte area */434434-#define pByteArea(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount) + 2)435435+#define pByteArea(smb_var) (BCC(smb_var) + 2)436436+437437+/* get the converted ByteCount for a SMB packet and return it */438438+static inline __u16439439+get_bcc(struct smb_hdr *hdr)440440+{441441+ __u16 *bc_ptr = (__u16 *)BCC(hdr);442442+443443+ return get_unaligned(bc_ptr);444444+}445445+446446+/* get the unconverted ByteCount for a SMB packet and return it */447447+static inline __u16448448+get_bcc_le(struct smb_hdr *hdr)449449+{450450+ __le16 *bc_ptr = (__le16 *)BCC(hdr);451451+452452+ return get_unaligned_le16(bc_ptr);453453+}454454+455455+/* set the ByteCount for a SMB packet in host-byte order */456456+static inline void457457+put_bcc(__u16 count, struct smb_hdr *hdr)458458+{459459+ __u16 *bc_ptr = (__u16 *)BCC(hdr);460460+461461+ put_unaligned(count, bc_ptr);462462+}463463+464464+/* set the ByteCount for a SMB packet in little-endian */465465+static inline void466466+put_bcc_le(__u16 count, struct smb_hdr *hdr)467467+{468468+ __le16 *bc_ptr = (__le16 *)BCC(hdr);469469+470470+ put_unaligned_le16(count, bc_ptr);471471+}435472436473/*437474 * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
+25-29
fs/cifs/cifssmb.c
···331331332332static int validate_t2(struct smb_t2_rsp *pSMB)333333{334334- int rc = -EINVAL;335335- int total_size;336336- char *pBCC;334334+ unsigned int total_size;337335338338- /* check for plausible wct, bcc and t2 data and parm sizes */336336+ /* check for plausible wct */337337+ if (pSMB->hdr.WordCount < 10)338338+ goto vt2_err;339339+339340 /* check for parm and data offset going beyond end of smb */340340- if (pSMB->hdr.WordCount >= 10) {341341- if ((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) &&342342- (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) {343343- /* check that bcc is at least as big as parms + data */344344- /* check that bcc is less than negotiated smb buffer */345345- total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount);346346- if (total_size < 512) {347347- total_size +=348348- le16_to_cpu(pSMB->t2_rsp.DataCount);349349- /* BCC le converted in SendReceive */350350- pBCC = (pSMB->hdr.WordCount * 2) +351351- sizeof(struct smb_hdr) +352352- (char *)pSMB;353353- if ((total_size <= (*(u16 *)pBCC)) &&354354- (total_size <355355- CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) {356356- return 0;357357- }358358- }359359- }360360- }341341+ if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||342342+ get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)343343+ goto vt2_err;344344+345345+ /* check that bcc is at least as big as parms + data */346346+ /* check that bcc is less than negotiated smb buffer */347347+ total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);348348+ if (total_size >= 512)349349+ goto vt2_err;350350+351351+ total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);352352+ if (total_size > get_bcc(&pSMB->hdr) ||353353+ total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)354354+ goto vt2_err;355355+356356+ return 0;357357+vt2_err:361358 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,362359 sizeof(struct smb_t2_rsp) + 16);363363- return rc;360360+ return -EINVAL;364361}362362+365363int366364CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)367365{···450452 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),451453 (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);452454 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);453453- GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey);454455 /* even though we do not use raw we might as well set this455456 accurately, in case we ever find a need for it */456457 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {···563566 (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);564567 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);565568 cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);566566- GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);567569 server->capabilities = le32_to_cpu(pSMBr->Capabilities);568570 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);569571 server->timeAdj *= 60;···56075611 }5608561256095613 /* make sure list_len doesn't go past end of SMB */56105610- end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr);56145614+ end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);56115615 if ((char *)ea_response_data + list_len > end_of_smb) {56125616 cFYI(1, "EA list appears to go beyond SMB");56135617 rc = -EIO;
+19-24
fs/cifs/connect.c
···232232static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)233233{234234 struct smb_t2_rsp *pSMBt;235235- int total_data_size;236236- int data_in_this_rsp;237235 int remaining;236236+ __u16 total_data_size, data_in_this_rsp;238237239238 if (pSMB->Command != SMB_COM_TRANSACTION2)240239 return 0;···247248248249 pSMBt = (struct smb_t2_rsp *)pSMB;249250250250- total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);251251- data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);251251+ total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);252252+ data_in_this_rsp = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);252253253254 remaining = total_data_size - data_in_this_rsp;254255···274275{275276 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;276277 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;277277- int total_data_size;278278- int total_in_buf;279279- int remaining;280280- int total_in_buf2;281278 char *data_area_of_target;282279 char *data_area_of_buf2;283283- __u16 byte_count;280280+ int remaining;281281+ __u16 byte_count, total_data_size, total_in_buf, total_in_buf2;284282285285- total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);283283+ total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);286284287287- if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {285285+ if (total_data_size !=286286+ get_unaligned_le16(&pSMB2->t2_rsp.TotalDataCount))288287 cFYI(1, "total data size of primary and secondary t2 differ");289289- }290288291291- total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);289289+ total_in_buf = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);292290293291 remaining = total_data_size - total_in_buf;294292···295299 if (remaining == 0) /* nothing to do, ignore */296300 return 0;297301298298- total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);302302+ total_in_buf2 = get_unaligned_le16(&pSMB2->t2_rsp.DataCount);299303 if (remaining < total_in_buf2) {300304 cFYI(1, "transact2 2nd response contains too much data");301305 }302306303307 /* find end of first SMB data area */304308 data_area_of_target = (char *)&pSMBt->hdr.Protocol +305305- le16_to_cpu(pSMBt->t2_rsp.DataOffset);309309+ get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);306310 /* validate target area */307311308308- data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +309309- le16_to_cpu(pSMB2->t2_rsp.DataOffset);312312+ data_area_of_buf2 = (char *)&pSMB2->hdr.Protocol +313313+ get_unaligned_le16(&pSMB2->t2_rsp.DataOffset);310314311315 data_area_of_target += total_in_buf;312316313317 /* copy second buffer into end of first buffer */314318 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);315319 total_in_buf += total_in_buf2;316316- pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);317317- byte_count = le16_to_cpu(BCC_LE(pTargetSMB));320320+ put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount);321321+ byte_count = get_bcc_le(pTargetSMB);318322 byte_count += total_in_buf2;319319- BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);323323+ put_bcc_le(byte_count, pTargetSMB);320324321325 byte_count = pTargetSMB->smb_buf_length;322326 byte_count += total_in_buf2;···330334 return 0; /* we are done */331335 } else /* more responses to go */332336 return 1;333333-334337}335338336339static void···29322937 TCONX_RSP *pSMBr;29332938 unsigned char *bcc_ptr;29342939 int rc = 0;29352935- int length, bytes_left;29362936- __u16 count;29402940+ int length;29412941+ __u16 bytes_left, count;2937294229382943 if (ses == NULL)29392944 return -EIO;···30273032 tcon->need_reconnect = false;30283033 tcon->tid = smb_buffer_response->Tid;30293034 bcc_ptr = pByteArea(smb_buffer_response);30303030- bytes_left = BCC(smb_buffer_response);30353035+ bytes_left = get_bcc(smb_buffer_response);30313036 length = strnlen(bcc_ptr, bytes_left - 2);30323037 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)30333038 is_unicode = true;
+130-45
fs/cifs/file.c
···287287 struct inode *inode = cifs_file->dentry->d_inode;288288 struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);289289 struct cifsInodeInfo *cifsi = CIFS_I(inode);290290+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);290291 struct cifsLockInfo *li, *tmp;291292292293 spin_lock(&cifs_file_list_lock);···303302 if (list_empty(&cifsi->openFileList)) {304303 cFYI(1, "closing last open instance for inode %p",305304 cifs_file->dentry->d_inode);305305+306306+ /* in strict cache mode we need invalidate mapping on the last307307+ close because it may cause a error when we open this file308308+ again and get at least level II oplock */309309+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)310310+ CIFS_I(inode)->invalid_mapping = true;311311+306312 cifs_set_oplock_level(cifsi, 0);307313 }308314 spin_unlock(&cifs_file_list_lock);···15281520 return rc;15291521}1530152215311531-int cifs_fsync(struct file *file, int datasync)15231523+int cifs_strict_fsync(struct file *file, int datasync)15321524{15331525 int xid;15341526 int rc = 0;15351527 struct cifsTconInfo *tcon;15361528 struct cifsFileInfo *smbfile = file->private_data;15371529 struct inode *inode = file->f_path.dentry->d_inode;15301530+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);1538153115391532 xid = GetXid();1540153315411534 cFYI(1, "Sync file - name: %s datasync: 0x%x",15421535 file->f_path.dentry->d_name.name, datasync);1543153615441544- rc = filemap_write_and_wait(inode->i_mapping);15451545- if (rc == 0) {15461546- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);15371537+ if (!CIFS_I(inode)->clientCanCacheRead)15381538+ cifs_invalidate_mapping(inode);1547153915481548- tcon = tlink_tcon(smbfile->tlink);15491549- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))15501550- rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);15511551- }15401540+ tcon = tlink_tcon(smbfile->tlink);15411541+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))15421542+ rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);15431543+15441544+ FreeXid(xid);15451545+ return rc;15461546+}15471547+15481548+int cifs_fsync(struct file *file, int datasync)15491549+{15501550+ int xid;15511551+ int rc = 0;15521552+ struct cifsTconInfo *tcon;15531553+ struct cifsFileInfo *smbfile = file->private_data;15541554+ struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);15551555+15561556+ xid = GetXid();15571557+15581558+ cFYI(1, "Sync file - name: %s datasync: 0x%x",15591559+ file->f_path.dentry->d_name.name, datasync);15601560+15611561+ tcon = tlink_tcon(smbfile->tlink);15621562+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))15631563+ rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);1552156415531565 FreeXid(xid);15541566 return rc;···16191591 return rc;16201592}1621159316221622-ssize_t cifs_user_read(struct file *file, char __user *read_data,16231623- size_t read_size, loff_t *poffset)15941594+static ssize_t15951595+cifs_iovec_read(struct file *file, const struct iovec *iov,15961596+ unsigned long nr_segs, loff_t *poffset)16241597{16251625- int rc = -EACCES;16261626- unsigned int bytes_read = 0;16271627- unsigned int total_read = 0;16281628- unsigned int current_read_size;15981598+ int rc;15991599+ int xid;16001600+ unsigned int total_read, bytes_read = 0;16011601+ size_t len, cur_len;16021602+ int iov_offset = 0;16291603 struct cifs_sb_info *cifs_sb;16301604 struct cifsTconInfo *pTcon;16311631- int xid;16321605 struct cifsFileInfo *open_file;16331633- char *smb_read_data;16341634- char __user *current_offset;16351606 struct smb_com_read_rsp *pSMBr;16071607+ char *read_data;16081608+16091609+ if (!nr_segs)16101610+ return 0;16111611+16121612+ len = iov_length(iov, nr_segs);16131613+ if (!len)16141614+ return 0;1636161516371616 xid = GetXid();16381617 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);1639161816401640- if (file->private_data == NULL) {16411641- rc = -EBADF;16421642- FreeXid(xid);16431643- return rc;16441644- }16451619 open_file = file->private_data;16461620 pTcon = tlink_tcon(open_file->tlink);1647162116481622 if ((file->f_flags & O_ACCMODE) == O_WRONLY)16491623 cFYI(1, "attempting read on write only file instance");1650162416511651- for (total_read = 0, current_offset = read_data;16521652- read_size > total_read;16531653- total_read += bytes_read, current_offset += bytes_read) {16541654- current_read_size = min_t(const int, read_size - total_read,16551655- cifs_sb->rsize);16251625+ for (total_read = 0; total_read < len; total_read += bytes_read) {16261626+ cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize);16561627 rc = -EAGAIN;16571657- smb_read_data = NULL;16281628+ read_data = NULL;16291629+16581630 while (rc == -EAGAIN) {16591631 int buf_type = CIFS_NO_BUFFER;16601632 if (open_file->invalidHandle) {···16621634 if (rc != 0)16631635 break;16641636 }16651665- rc = CIFSSMBRead(xid, pTcon,16661666- open_file->netfid,16671667- current_read_size, *poffset,16681668- &bytes_read, &smb_read_data,16691669- &buf_type);16701670- pSMBr = (struct smb_com_read_rsp *)smb_read_data;16711671- if (smb_read_data) {16721672- if (copy_to_user(current_offset,16731673- smb_read_data +16741674- 4 /* RFC1001 length field */ +16751675- le16_to_cpu(pSMBr->DataOffset),16761676- bytes_read))16371637+ rc = CIFSSMBRead(xid, pTcon, open_file->netfid,16381638+ cur_len, *poffset, &bytes_read,16391639+ &read_data, &buf_type);16401640+ pSMBr = (struct smb_com_read_rsp *)read_data;16411641+ if (read_data) {16421642+ char *data_offset = read_data + 4 +16431643+ le16_to_cpu(pSMBr->DataOffset);16441644+ if (memcpy_toiovecend(iov, data_offset,16451645+ iov_offset, bytes_read))16771646 rc = -EFAULT;16781678-16791647 if (buf_type == CIFS_SMALL_BUFFER)16801680- cifs_small_buf_release(smb_read_data);16481648+ cifs_small_buf_release(read_data);16811649 else if (buf_type == CIFS_LARGE_BUFFER)16821682- cifs_buf_release(smb_read_data);16831683- smb_read_data = NULL;16501650+ cifs_buf_release(read_data);16511651+ read_data = NULL;16521652+ iov_offset += bytes_read;16841653 }16851654 }16551655+16861656 if (rc || (bytes_read == 0)) {16871657 if (total_read) {16881658 break;···16931667 *poffset += bytes_read;16941668 }16951669 }16701670+16961671 FreeXid(xid);16971672 return total_read;16981673}1699167416751675+ssize_t cifs_user_read(struct file *file, char __user *read_data,16761676+ size_t read_size, loff_t *poffset)16771677+{16781678+ struct iovec iov;16791679+ iov.iov_base = read_data;16801680+ iov.iov_len = read_size;16811681+16821682+ return cifs_iovec_read(file, &iov, 1, poffset);16831683+}16841684+16851685+static ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,16861686+ unsigned long nr_segs, loff_t pos)16871687+{16881688+ ssize_t read;16891689+16901690+ read = cifs_iovec_read(iocb->ki_filp, iov, nr_segs, &pos);16911691+ if (read > 0)16921692+ iocb->ki_pos = pos;16931693+16941694+ return read;16951695+}16961696+16971697+ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,16981698+ unsigned long nr_segs, loff_t pos)16991699+{17001700+ struct inode *inode;17011701+17021702+ inode = iocb->ki_filp->f_path.dentry->d_inode;17031703+17041704+ if (CIFS_I(inode)->clientCanCacheRead)17051705+ return generic_file_aio_read(iocb, iov, nr_segs, pos);17061706+17071707+ /*17081708+ * In strict cache mode we need to read from the server all the time17091709+ * if we don't have level II oplock because the server can delay mtime17101710+ * change - so we can't make a decision about inode invalidating.17111711+ * And we can also fail with pagereading if there are mandatory locks17121712+ * on pages affected by this read but not on the region from pos to17131713+ * pos+len-1.17141714+ */17151715+17161716+ return cifs_user_readv(iocb, iov, nr_segs, pos);17171717+}1700171817011719static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,17021702- loff_t *poffset)17201720+ loff_t *poffset)17031721{17041722 int rc = -EACCES;17051723 unsigned int bytes_read = 0;···18091739 }18101740 FreeXid(xid);18111741 return total_read;17421742+}17431743+17441744+int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)17451745+{17461746+ int rc, xid;17471747+ struct inode *inode = file->f_path.dentry->d_inode;17481748+17491749+ xid = GetXid();17501750+17511751+ if (!CIFS_I(inode)->clientCanCacheRead)17521752+ cifs_invalidate_mapping(inode);17531753+17541754+ rc = generic_file_mmap(file, vma);17551755+ FreeXid(xid);17561756+ return rc;18121757}1813175818141759int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
+6-2
fs/cifs/inode.c
···4444 inode->i_fop = &cifs_file_direct_nobrl_ops;4545 else4646 inode->i_fop = &cifs_file_direct_ops;4747+ } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {4848+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)4949+ inode->i_fop = &cifs_file_strict_nobrl_ops;5050+ else5151+ inode->i_fop = &cifs_file_strict_ops;4752 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)4853 inode->i_fop = &cifs_file_nobrl_ops;4954 else { /* not direct, send byte range locks */5055 inode->i_fop = &cifs_file_ops;5156 }5252-53575458 /* check if server can support readpages */5559 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <···16831679/*16841680 * Zap the cache. Called when invalid_mapping flag is set.16851681 */16861686-static void16821682+void16871683cifs_invalidate_mapping(struct inode *inode)16881684{16891685 int rc;
-71
fs/cifs/misc.c
···637637 return;638638}639639640640-/* Convert 16 bit Unicode pathname to wire format from string in current code641641- page. Conversion may involve remapping up the seven characters that are642642- only legal in POSIX-like OS (if they are present in the string). Path643643- names are little endian 16 bit Unicode on the wire */644644-int645645-cifsConvertToUCS(__le16 *target, const char *source, int maxlen,646646- const struct nls_table *cp, int mapChars)647647-{648648- int i, j, charlen;649649- int len_remaining = maxlen;650650- char src_char;651651- __u16 temp;652652-653653- if (!mapChars)654654- return cifs_strtoUCS(target, source, PATH_MAX, cp);655655-656656- for (i = 0, j = 0; i < maxlen; j++) {657657- src_char = source[i];658658- switch (src_char) {659659- case 0:660660- target[j] = 0;661661- goto ctoUCS_out;662662- case ':':663663- target[j] = cpu_to_le16(UNI_COLON);664664- break;665665- case '*':666666- target[j] = cpu_to_le16(UNI_ASTERIK);667667- break;668668- case '?':669669- target[j] = cpu_to_le16(UNI_QUESTION);670670- break;671671- case '<':672672- target[j] = cpu_to_le16(UNI_LESSTHAN);673673- break;674674- case '>':675675- target[j] = cpu_to_le16(UNI_GRTRTHAN);676676- break;677677- case '|':678678- target[j] = cpu_to_le16(UNI_PIPE);679679- break;680680- /* BB We can not handle remapping slash until681681- all the calls to build_path_from_dentry682682- are modified, as they use slash as separator BB */683683- /* case '\\':684684- target[j] = cpu_to_le16(UNI_SLASH);685685- break;*/686686- default:687687- charlen = cp->char2uni(source+i,688688- len_remaining, &temp);689689- /* if no match, use question mark, which690690- at least in some cases servers as wild card */691691- if (charlen < 1) {692692- target[j] = cpu_to_le16(0x003f);693693- charlen = 1;694694- } else695695- target[j] = cpu_to_le16(temp);696696- len_remaining -= charlen;697697- /* character may take more than one byte in the698698- the source string, but will take exactly two699699- bytes in the target string */700700- i += charlen;701701- continue;702702- }703703- i++; /* move to next char in source string */704704- len_remaining--;705705- }706706-707707-ctoUCS_out:708708- return i;709709-}710710-711640void712641cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)713642{
+2-2
fs/cifs/netmisc.c
···916916smbCalcSize(struct smb_hdr *ptr)917917{918918 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +919919- 2 /* size of the bcc field */ + BCC(ptr));919919+ 2 /* size of the bcc field */ + get_bcc(ptr));920920}921921922922unsigned int923923smbCalcSize_LE(struct smb_hdr *ptr)924924{925925 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +926926- 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));926926+ 2 /* size of the bcc field */ + get_bcc_le(ptr));927927}928928929929/* The following are taken from fs/ntfs/util.c */
+6-7
fs/cifs/sess.c
···277277}278278279279static void280280-decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,280280+decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses,281281 const struct nls_table *nls_cp)282282{283283 int len;···323323 return;324324}325325326326-static int decode_ascii_ssetup(char **pbcc_area, int bleft,326326+static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,327327 struct cifsSesInfo *ses,328328 const struct nls_table *nls_cp)329329{···575575 char *str_area;576576 SESSION_SETUP_ANDX *pSMB;577577 __u32 capabilities;578578- int count;578578+ __u16 count;579579 int resp_buf_type;580580 struct kvec iov[3];581581 enum securityEnum type;582582- __u16 action;583583- int bytes_remaining;582582+ __u16 action, bytes_remaining;584583 struct key *spnego_key = NULL;585584 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */586585 u16 blob_len;···875876 count = iov[1].iov_len + iov[2].iov_len;876877 smb_buf->smb_buf_length += count;877878878878- BCC_LE(smb_buf) = cpu_to_le16(count);879879+ put_bcc_le(count, smb_buf);879880880881 rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,881882 CIFS_LOG_ERROR);···909910 cFYI(1, "UID = %d ", ses->Suid);910911 /* response can have either 3 or 4 word count - Samba sends 3 */911912 /* and lanman response is 3 */912912- bytes_remaining = BCC(smb_buf);913913+ bytes_remaining = get_bcc(smb_buf);913914 bcc_ptr = pByteArea(smb_buf);914915915916 if (smb_buf->WordCount == 4) {
+4-5
fs/cifs/transport.c
···484484 in_buf->smb_buf_length = sizeof(struct smb_hdr) - 4 + 2;485485 in_buf->Command = SMB_COM_NT_CANCEL;486486 in_buf->WordCount = 0;487487- BCC_LE(in_buf) = 0;487487+ put_bcc_le(0, in_buf);488488489489 mutex_lock(&server->srv_mutex);490490 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);···632632 if (receive_len >= sizeof(struct smb_hdr) - 4633633 /* do not count RFC1001 header */ +634634 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )635635- BCC(midQ->resp_buf) =636636- le16_to_cpu(BCC_LE(midQ->resp_buf));635635+ put_bcc(get_bcc_le(midQ->resp_buf), midQ->resp_buf);637636 if ((flags & CIFS_NO_RESP) == 0)638637 midQ->resp_buf = NULL; /* mark it so buf will639638 not be freed by···775776 if (receive_len >= sizeof(struct smb_hdr) - 4776777 /* do not count RFC1001 header */ +777778 (2 * out_buf->WordCount) + 2 /* bcc */ )778778- BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));779779+ put_bcc(get_bcc_le(midQ->resp_buf), midQ->resp_buf);779780 } else {780781 rc = -EIO;781782 cERROR(1, "Bad MID state?");···976977 if (receive_len >= sizeof(struct smb_hdr) - 4977978 /* do not count RFC1001 header */ +978979 (2 * out_buf->WordCount) + 2 /* bcc */ )979979- BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));980980+ put_bcc(get_bcc_le(out_buf), out_buf);980981981982out:982983 delete_mid(midQ);