]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
CIFS: Separate protocol-specific code from cifs_readv_receive code
authorPavel Shilovsky <piastry@etersoft.ru>
Fri, 23 Mar 2012 18:28:03 +0000 (14:28 -0400)
committerJeff Layton <jlayton@redhat.com>
Fri, 23 Mar 2012 18:28:03 +0000 (14:28 -0400)
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/netmisc.c

index 34a897e3d225cb163b4e6163408ca0e740d0407a..a403398261788269ea374faa5172ae66afe66a83 100644 (file)
@@ -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.
index 70124ae77aa8d3f81aaf1438d9d07b3bd4617eb2..05f0a2e7e14a5a5d3b7ef50113a4ce6bf404b9a0 100644 (file)
@@ -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 */);
index a7ed01cd024286242a02163a1e1ca3d3c119cae3..c45d445e20940ddde7cb64026787c1390c76747b 100644 (file)
@@ -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;
 
@@ -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;
@@ -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;
@@ -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);
@@ -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);
@@ -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
@@ -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)
@@ -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);
@@ -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);
index cb6e757feb521d936453e9627f31788c586cf70e..007d4dfcaf538053f119da56d01f7361d7daf668 100644 (file)
@@ -338,18 +338,6 @@ requeue_echo:
        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)
 {
index 73e47e84b61a4827fa13ed69a41e205be510234e..dd23a321bdda60b8eacf105bea12b8e2cce51b2f 100644 (file)
@@ -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;