Loading fs/cifs/cifsglob.h +12 −0 Original line number Diff line number Diff line Loading @@ -341,6 +341,18 @@ has_credits(struct TCP_Server_Info *server, int *credits) return num > 0; } static inline size_t header_size(void) { return sizeof(struct smb_hdr); } static inline size_t max_header_size(void) { return MAX_CIFS_HDR_SIZE; } /* * Macros to allow the TCP_Server_Info->net field and related code to drop out * when CONFIG_NET_NS isn't set. Loading fs/cifs/cifsproto.h +1 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, const unsigned short int port); extern int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr); extern int map_smb_to_linux_error(char *buf, bool logErr); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifs_tcon *, int /* length of fixed section (word count) in two byte units */); Loading fs/cifs/cifssmb.c +38 −20 Original line number Diff line number Diff line Loading @@ -1414,8 +1414,7 @@ cifs_readdata_free(struct cifs_readdata *rdata) static int cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) { READ_RSP *rsp = (READ_RSP *)server->smallbuf; unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length); unsigned int rfclen = get_rfc1002_length(server->smallbuf); int remaining = rfclen + 4 - server->total_read; struct cifs_readdata *rdata = mid->callback_data; Loading @@ -1424,7 +1423,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) length = cifs_read_from_socket(server, server->bigbuf, min_t(unsigned int, remaining, CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)); CIFSMaxBufSize + max_header_size())); if (length < 0) return length; server->total_read += length; Loading @@ -1435,14 +1434,35 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) return 0; } static inline size_t read_rsp_size(void) { return sizeof(READ_RSP); } static inline unsigned int read_data_offset(char *buf) { READ_RSP *rsp = (READ_RSP *)buf; return le16_to_cpu(rsp->DataOffset); } static inline unsigned int read_data_length(char *buf) { READ_RSP *rsp = (READ_RSP *)buf; return (le16_to_cpu(rsp->DataLengthHigh) << 16) + le16_to_cpu(rsp->DataLength); } static int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) { int length, len; unsigned int data_offset, remaining, data_len; struct cifs_readdata *rdata = mid->callback_data; READ_RSP *rsp = (READ_RSP *)server->smallbuf; unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4; char *buf = server->smallbuf; unsigned int buflen = get_rfc1002_length(buf) + 4; u64 eof; pgoff_t eof_index; struct page *page, *tpage; Loading @@ -1455,10 +1475,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) * can if there's not enough data. At this point, we've read down to * the Mid. */ len = min_t(unsigned int, rfclen, sizeof(*rsp)) - sizeof(struct smb_hdr) + 1; len = min_t(unsigned int, buflen, read_rsp_size()) - header_size() + 1; rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1; rdata->iov[0].iov_base = buf + header_size() - 1; rdata->iov[0].iov_len = len; length = cifs_readv_from_socket(server, rdata->iov, 1, len); Loading @@ -1467,7 +1486,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) server->total_read += length; /* Was the SMB read successful? */ rdata->result = map_smb_to_linux_error(&rsp->hdr, false); rdata->result = map_smb_to_linux_error(buf, false); if (rdata->result != 0) { cFYI(1, "%s: server returned error %d", __func__, rdata->result); Loading @@ -1475,14 +1494,14 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* Is there enough to get to the rest of the READ_RSP header? */ if (server->total_read < sizeof(READ_RSP)) { if (server->total_read < read_rsp_size()) { cFYI(1, "%s: server returned short header. got=%u expected=%zu", __func__, server->total_read, sizeof(READ_RSP)); __func__, server->total_read, read_rsp_size()); rdata->result = -EIO; return cifs_readv_discard(server, mid); } data_offset = le16_to_cpu(rsp->DataOffset) + 4; data_offset = read_data_offset(buf) + 4; if (data_offset < server->total_read) { /* * win2k8 sometimes sends an offset of 0 when the read Loading @@ -1506,7 +1525,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) len = data_offset - server->total_read; if (len > 0) { /* read any junk before data into the rest of smallbuf */ rdata->iov[0].iov_base = server->smallbuf + server->total_read; rdata->iov[0].iov_base = buf + server->total_read; rdata->iov[0].iov_len = len; length = cifs_readv_from_socket(server, rdata->iov, 1, len); if (length < 0) Loading @@ -1515,15 +1534,14 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* set up first iov for signature check */ rdata->iov[0].iov_base = server->smallbuf; rdata->iov[0].iov_base = buf; rdata->iov[0].iov_len = server->total_read; cFYI(1, "0: iov_base=%p iov_len=%zu", rdata->iov[0].iov_base, rdata->iov[0].iov_len); /* how much data is in the response? */ data_len = le16_to_cpu(rsp->DataLengthHigh) << 16; data_len += le16_to_cpu(rsp->DataLength); if (data_offset + data_len > rfclen) { data_len = read_data_length(buf); if (data_offset + data_len > buflen) { /* data_len is corrupt -- discard frame */ rdata->result = -EIO; return cifs_readv_discard(server, mid); Loading Loading @@ -1602,11 +1620,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) rdata->bytes = length; cFYI(1, "total_read=%u rfclen=%u remaining=%u", server->total_read, rfclen, remaining); cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read, buflen, remaining); /* discard anything left over */ if (server->total_read < rfclen) if (server->total_read < buflen) return cifs_readv_discard(server, mid); dequeue_mid(mid, false); Loading fs/cifs/connect.c +0 −12 Original line number Diff line number Diff line Loading @@ -338,18 +338,6 @@ cifs_echo_request(struct work_struct *work) queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); } static inline size_t header_size(void) { return sizeof(struct smb_hdr); } static inline size_t max_header_size(void) { return MAX_CIFS_HDR_SIZE; } static bool allocate_buffers(struct TCP_Server_Info *server) { Loading fs/cifs/netmisc.c +2 −1 Original line number Diff line number Diff line Loading @@ -836,8 +836,9 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode) } int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr) map_smb_to_linux_error(char *buf, bool logErr) { struct smb_hdr *smb = (struct smb_hdr *)buf; unsigned int i; int rc = -EIO; /* if transport error smb error may not be set */ __u8 smberrclass; Loading Loading
fs/cifs/cifsglob.h +12 −0 Original line number Diff line number Diff line Loading @@ -341,6 +341,18 @@ has_credits(struct TCP_Server_Info *server, int *credits) return num > 0; } static inline size_t header_size(void) { return sizeof(struct smb_hdr); } static inline size_t max_header_size(void) { return MAX_CIFS_HDR_SIZE; } /* * Macros to allow the TCP_Server_Info->net field and related code to drop out * when CONFIG_NET_NS isn't set. Loading
fs/cifs/cifsproto.h +1 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, const unsigned short int port); extern int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr); extern int map_smb_to_linux_error(char *buf, bool logErr); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifs_tcon *, int /* length of fixed section (word count) in two byte units */); Loading
fs/cifs/cifssmb.c +38 −20 Original line number Diff line number Diff line Loading @@ -1414,8 +1414,7 @@ cifs_readdata_free(struct cifs_readdata *rdata) static int cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) { READ_RSP *rsp = (READ_RSP *)server->smallbuf; unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length); unsigned int rfclen = get_rfc1002_length(server->smallbuf); int remaining = rfclen + 4 - server->total_read; struct cifs_readdata *rdata = mid->callback_data; Loading @@ -1424,7 +1423,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) length = cifs_read_from_socket(server, server->bigbuf, min_t(unsigned int, remaining, CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)); CIFSMaxBufSize + max_header_size())); if (length < 0) return length; server->total_read += length; Loading @@ -1435,14 +1434,35 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) return 0; } static inline size_t read_rsp_size(void) { return sizeof(READ_RSP); } static inline unsigned int read_data_offset(char *buf) { READ_RSP *rsp = (READ_RSP *)buf; return le16_to_cpu(rsp->DataOffset); } static inline unsigned int read_data_length(char *buf) { READ_RSP *rsp = (READ_RSP *)buf; return (le16_to_cpu(rsp->DataLengthHigh) << 16) + le16_to_cpu(rsp->DataLength); } static int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) { int length, len; unsigned int data_offset, remaining, data_len; struct cifs_readdata *rdata = mid->callback_data; READ_RSP *rsp = (READ_RSP *)server->smallbuf; unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4; char *buf = server->smallbuf; unsigned int buflen = get_rfc1002_length(buf) + 4; u64 eof; pgoff_t eof_index; struct page *page, *tpage; Loading @@ -1455,10 +1475,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) * can if there's not enough data. At this point, we've read down to * the Mid. */ len = min_t(unsigned int, rfclen, sizeof(*rsp)) - sizeof(struct smb_hdr) + 1; len = min_t(unsigned int, buflen, read_rsp_size()) - header_size() + 1; rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1; rdata->iov[0].iov_base = buf + header_size() - 1; rdata->iov[0].iov_len = len; length = cifs_readv_from_socket(server, rdata->iov, 1, len); Loading @@ -1467,7 +1486,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) server->total_read += length; /* Was the SMB read successful? */ rdata->result = map_smb_to_linux_error(&rsp->hdr, false); rdata->result = map_smb_to_linux_error(buf, false); if (rdata->result != 0) { cFYI(1, "%s: server returned error %d", __func__, rdata->result); Loading @@ -1475,14 +1494,14 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* Is there enough to get to the rest of the READ_RSP header? */ if (server->total_read < sizeof(READ_RSP)) { if (server->total_read < read_rsp_size()) { cFYI(1, "%s: server returned short header. got=%u expected=%zu", __func__, server->total_read, sizeof(READ_RSP)); __func__, server->total_read, read_rsp_size()); rdata->result = -EIO; return cifs_readv_discard(server, mid); } data_offset = le16_to_cpu(rsp->DataOffset) + 4; data_offset = read_data_offset(buf) + 4; if (data_offset < server->total_read) { /* * win2k8 sometimes sends an offset of 0 when the read Loading @@ -1506,7 +1525,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) len = data_offset - server->total_read; if (len > 0) { /* read any junk before data into the rest of smallbuf */ rdata->iov[0].iov_base = server->smallbuf + server->total_read; rdata->iov[0].iov_base = buf + server->total_read; rdata->iov[0].iov_len = len; length = cifs_readv_from_socket(server, rdata->iov, 1, len); if (length < 0) Loading @@ -1515,15 +1534,14 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* set up first iov for signature check */ rdata->iov[0].iov_base = server->smallbuf; rdata->iov[0].iov_base = buf; rdata->iov[0].iov_len = server->total_read; cFYI(1, "0: iov_base=%p iov_len=%zu", rdata->iov[0].iov_base, rdata->iov[0].iov_len); /* how much data is in the response? */ data_len = le16_to_cpu(rsp->DataLengthHigh) << 16; data_len += le16_to_cpu(rsp->DataLength); if (data_offset + data_len > rfclen) { data_len = read_data_length(buf); if (data_offset + data_len > buflen) { /* data_len is corrupt -- discard frame */ rdata->result = -EIO; return cifs_readv_discard(server, mid); Loading Loading @@ -1602,11 +1620,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) rdata->bytes = length; cFYI(1, "total_read=%u rfclen=%u remaining=%u", server->total_read, rfclen, remaining); cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read, buflen, remaining); /* discard anything left over */ if (server->total_read < rfclen) if (server->total_read < buflen) return cifs_readv_discard(server, mid); dequeue_mid(mid, false); Loading
fs/cifs/connect.c +0 −12 Original line number Diff line number Diff line Loading @@ -338,18 +338,6 @@ cifs_echo_request(struct work_struct *work) queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); } static inline size_t header_size(void) { return sizeof(struct smb_hdr); } static inline size_t max_header_size(void) { return MAX_CIFS_HDR_SIZE; } static bool allocate_buffers(struct TCP_Server_Info *server) { Loading
fs/cifs/netmisc.c +2 −1 Original line number Diff line number Diff line Loading @@ -836,8 +836,9 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode) } int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr) map_smb_to_linux_error(char *buf, bool logErr) { struct smb_hdr *smb = (struct smb_hdr *)buf; unsigned int i; int rc = -EIO; /* if transport error smb error may not be set */ __u8 smberrclass; Loading