X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=fs%2Fcifs%2Ftransport.c;h=3612d6c0a0bbc1a4c9f64c2ce0f674517ce86d72;hb=b881502666783b2d9ca2fc7a056d0f773073a808;hp=7ed32b3cb781a0011a0560b7fe3898825f5c9e4f;hpb=0a4908e19fd016d60403fc76cf38b2d08d21e2d2;p=linux-2.6-omap-h63xx.git diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 7ed32b3cb78..3612d6c0a0b 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -1,7 +1,7 @@ /* * fs/cifs/transport.c * - * Copyright (C) International Business Machines Corp., 2002,2007 + * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * Jeremy Allison (jra@samba.org) 2006. * @@ -308,7 +308,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) { - if (long_op == -1) { + if (long_op == CIFS_ASYNC_OP) { /* oplock breaks must not be held up */ atomic_inc(&ses->server->inFlight); } else { @@ -337,7 +337,7 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) as they are allowed to block on server */ /* update # of requests on the wire to server */ - if (long_op < 3) + if (long_op != CIFS_BLOCKING_OP) atomic_inc(&ses->server->inFlight); spin_unlock(&GlobalMid_Lock); break; @@ -358,9 +358,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, } else if (ses->status != CifsGood) { /* check if SMB session is bad because we are setting it up */ if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && - (in_buf->Command != SMB_COM_NEGOTIATE)) { + (in_buf->Command != SMB_COM_NEGOTIATE)) return -EAGAIN; - } /* else ok - we are setting up session */ + /* else ok - we are setting up session */ } *ppmidQ = AllocMidQEntry(in_buf, ses); if (*ppmidQ == NULL) @@ -415,17 +415,47 @@ static int wait_for_response(struct cifsSesInfo *ses, } } + +/* + * + * Send an SMB Request. No response info (other than return code) + * needs to be parsed. + * + * flags indicate the type of request buffer and how long to wait + * and whether to log NT STATUS code (error) before mapping it to POSIX error + * + */ +int +SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, + struct smb_hdr *in_buf, int flags) +{ + int rc; + struct kvec iov[1]; + int resp_buf_type; + + iov[0].iov_base = (char *)in_buf; + iov[0].iov_len = in_buf->smb_buf_length + 4; + flags |= CIFS_NO_RESP; + rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); + cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc)); + + return rc; +} + int SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, struct kvec *iov, int n_vec, int *pRespBufType /* ret */, - const int long_op, const int logError) + const int flags) { int rc = 0; + int long_op; unsigned int receive_len; unsigned long timeout; struct mid_q_entry *midQ; struct smb_hdr *in_buf = iov[0].iov_base; + long_op = flags & CIFS_TIMEOUT_MASK; + *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ if ((ses == NULL) || (ses->server == NULL)) { @@ -483,15 +513,22 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, if (rc < 0) goto out; - if (long_op == -1) - goto out; - else if (long_op == 2) /* writes past end of file can take loong time */ + if (long_op == CIFS_STD_OP) + timeout = 15 * HZ; + else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */ timeout = 180 * HZ; - else if (long_op == 1) + else if (long_op == CIFS_LONG_OP) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ - else - timeout = 15 * HZ; + else if (long_op == CIFS_ASYNC_OP) + goto out; + else if (long_op == CIFS_BLOCKING_OP) + timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */ + else { + cERROR(1, ("unknown timeout flag %d", long_op)); + rc = -EIO; + goto out; + } /* wait for 15 seconds or until woken up due to response arriving or due to last connection to this server being unmounted */ @@ -566,7 +603,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, } /* BB special case reconnect tid and uid here? */ - rc = map_smb_to_linux_error(midQ->resp_buf, logError); + rc = map_smb_to_linux_error(midQ->resp_buf, + flags & CIFS_LOG_ERROR); /* convert ByteCount if necessary */ if (receive_len >= sizeof(struct smb_hdr) - 4 @@ -574,8 +612,10 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) BCC(midQ->resp_buf) = le16_to_cpu(BCC_LE(midQ->resp_buf)); - midQ->resp_buf = NULL; /* mark it so will not be freed - by DeleteMidQEntry */ + if ((flags & CIFS_NO_RESP) == 0) + midQ->resp_buf = NULL; /* mark it so buf will + not be freed by + DeleteMidQEntry */ } else { rc = -EIO; cFYI(1, ("Bad MID state?")); @@ -663,17 +703,25 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, if (rc < 0) goto out; - if (long_op == -1) + if (long_op == CIFS_STD_OP) + timeout = 15 * HZ; + /* wait for 15 seconds or until woken up due to response arriving or + due to last connection to this server being unmounted */ + else if (long_op == CIFS_ASYNC_OP) goto out; - else if (long_op == 2) /* writes past end of file can take loong time */ + else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */ timeout = 180 * HZ; - else if (long_op == 1) + else if (long_op == CIFS_LONG_OP) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ - else - timeout = 15 * HZ; - /* wait for 15 seconds or until woken up due to response arriving or - due to last connection to this server being unmounted */ + else if (long_op == CIFS_BLOCKING_OP) + timeout = 0x7FFFFFFF; /* large but no so large as to wrap */ + else { + cERROR(1, ("unknown timeout flag %d", long_op)); + rc = -EIO; + goto out; + } + if (signal_pending(current)) { /* if signal pending do not hold up user for full smb timeout but we still give response a chance to complete */ @@ -812,7 +860,7 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon, pSMB->hdr.Mid = GetNextMid(ses->server); return SendReceive(xid, ses, in_buf, out_buf, - &bytes_returned, 0); + &bytes_returned, CIFS_STD_OP); } int @@ -844,7 +892,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, to the same server. We may make this configurable later or use ses->maxReq */ - rc = wait_for_free_request(ses, 3); + rc = wait_for_free_request(ses, CIFS_BLOCKING_OP); if (rc) return rc;