summaryrefslogtreecommitdiff
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c285
1 files changed, 91 insertions, 194 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 8b7794c31591..b5ad716b2642 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -87,7 +87,6 @@ static struct {
#endif /* CIFS_POSIX */
/* Forward declarations */
-static void cifs_readv_complete(struct work_struct *work);
/* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */
@@ -458,7 +457,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
goto neg_err_exit;
}
server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
- server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
+ server->maxReq = min_t(unsigned int,
+ le16_to_cpu(rsp->MaxMpxCount),
+ cifs_max_pending);
+ set_credits(server, server->maxReq);
server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
/* even though we do not use raw we might as well set this
@@ -564,7 +566,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
/* one byte, so no need to convert this or EncryptionKeyLen from
little endian */
- server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
+ server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
+ cifs_max_pending);
+ set_credits(server, server->maxReq);
/* probably no need to store and check maxvcs */
server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
@@ -691,7 +695,7 @@ CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
if (rc)
return rc;
- rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
if (rc)
cFYI(1, "Tree disconnect failed %d", rc);
@@ -716,8 +720,7 @@ cifs_echo_callback(struct mid_q_entry *mid)
struct TCP_Server_Info *server = mid->callback_data;
DeleteMidQEntry(mid);
- atomic_dec(&server->inFlight);
- wake_up(&server->request_q);
+ add_credits(server, 1);
}
int
@@ -788,7 +791,7 @@ CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
pSMB->hdr.Uid = ses->Suid;
pSMB->AndXCommand = 0xFF;
- rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
session_already_dead:
mutex_unlock(&ses->session_mutex);
@@ -1381,28 +1384,6 @@ openRetry:
return rc;
}
-struct cifs_readdata *
-cifs_readdata_alloc(unsigned int nr_pages)
-{
- struct cifs_readdata *rdata;
-
- /* readdata + 1 kvec for each page */
- rdata = kzalloc(sizeof(*rdata) +
- sizeof(struct kvec) * nr_pages, GFP_KERNEL);
- if (rdata != NULL) {
- INIT_WORK(&rdata->work, cifs_readv_complete);
- INIT_LIST_HEAD(&rdata->pages);
- }
- return rdata;
-}
-
-void
-cifs_readdata_free(struct cifs_readdata *rdata)
-{
- cifsFileInfo_put(rdata->cfile);
- kfree(rdata);
-}
-
/*
* Discard any remaining data in the current SMB. To do this, we borrow the
* current bigbuf.
@@ -1410,8 +1391,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;
@@ -1420,7 +1400,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(server)));
if (length < 0)
return length;
server->total_read += length;
@@ -1435,15 +1415,12 @@ 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;
+ unsigned int data_offset, 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;
- u64 eof;
- pgoff_t eof_index;
- struct page *page, *tpage;
+ char *buf = server->smallbuf;
+ unsigned int buflen = get_rfc1002_length(buf) + 4;
- cFYI(1, "%s: mid=%u offset=%llu bytes=%u", __func__,
+ cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
mid->mid, rdata->offset, rdata->bytes);
/*
@@ -1451,10 +1428,10 @@ 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, server->vals->read_rsp_size) -
+ HEADER_SIZE(server) + 1;
- rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1;
+ rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1;
rdata->iov[0].iov_len = len;
length = cifs_readv_from_socket(server, rdata->iov, 1, len);
@@ -1463,7 +1440,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 = server->ops->map_error(buf, false);
if (rdata->result != 0) {
cFYI(1, "%s: server returned error %d", __func__,
rdata->result);
@@ -1471,14 +1448,15 @@ 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 < server->vals->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,
+ server->vals->read_rsp_size);
rdata->result = -EIO;
return cifs_readv_discard(server, mid);
}
- data_offset = le16_to_cpu(rsp->DataOffset) + 4;
+ data_offset = server->ops->read_data_offset(buf) + 4;
if (data_offset < server->total_read) {
/*
* win2k8 sometimes sends an offset of 0 when the read
@@ -1502,7 +1480,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)
@@ -1511,79 +1489,22 @@ 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 = server->ops->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);
}
/* marshal up the page array */
- len = 0;
- remaining = data_len;
- rdata->nr_iov = 1;
-
- /* determine the eof that the server (probably) has */
- eof = CIFS_I(rdata->mapping->host)->server_eof;
- eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
- cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
-
- list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
- if (remaining >= PAGE_CACHE_SIZE) {
- /* enough data to fill the page */
- rdata->iov[rdata->nr_iov].iov_base = kmap(page);
- rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
- cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
- rdata->nr_iov, page->index,
- rdata->iov[rdata->nr_iov].iov_base,
- rdata->iov[rdata->nr_iov].iov_len);
- ++rdata->nr_iov;
- len += PAGE_CACHE_SIZE;
- remaining -= PAGE_CACHE_SIZE;
- } else if (remaining > 0) {
- /* enough for partial page, fill and zero the rest */
- rdata->iov[rdata->nr_iov].iov_base = kmap(page);
- rdata->iov[rdata->nr_iov].iov_len = remaining;
- cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
- rdata->nr_iov, page->index,
- rdata->iov[rdata->nr_iov].iov_base,
- rdata->iov[rdata->nr_iov].iov_len);
- memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
- '\0', PAGE_CACHE_SIZE - remaining);
- ++rdata->nr_iov;
- len += remaining;
- remaining = 0;
- } else if (page->index > eof_index) {
- /*
- * The VFS will not try to do readahead past the
- * i_size, but it's possible that we have outstanding
- * writes with gaps in the middle and the i_size hasn't
- * caught up yet. Populate those with zeroed out pages
- * to prevent the VFS from repeatedly attempting to
- * fill them until the writes are flushed.
- */
- zero_user(page, 0, PAGE_CACHE_SIZE);
- list_del(&page->lru);
- lru_cache_add_file(page);
- flush_dcache_page(page);
- SetPageUptodate(page);
- unlock_page(page);
- page_cache_release(page);
- } else {
- /* no need to hold page hostage */
- list_del(&page->lru);
- lru_cache_add_file(page);
- unlock_page(page);
- page_cache_release(page);
- }
- }
+ len = rdata->marshal_iov(rdata, data_len);
+ data_len -= len;
/* issue the read if we have any iovecs left to fill */
if (rdata->nr_iov > 1) {
@@ -1598,11 +1519,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, data_len);
/* discard anything left over */
- if (server->total_read < rfclen)
+ if (server->total_read < buflen)
return cifs_readv_discard(server, mid);
dequeue_mid(mid, false);
@@ -1610,43 +1531,16 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
}
static void
-cifs_readv_complete(struct work_struct *work)
-{
- struct cifs_readdata *rdata = container_of(work,
- struct cifs_readdata, work);
- struct page *page, *tpage;
-
- list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
- list_del(&page->lru);
- lru_cache_add_file(page);
-
- if (rdata->result == 0) {
- kunmap(page);
- flush_dcache_page(page);
- SetPageUptodate(page);
- }
-
- unlock_page(page);
-
- if (rdata->result == 0)
- cifs_readpage_to_fscache(rdata->mapping->host, page);
-
- page_cache_release(page);
- }
- cifs_readdata_free(rdata);
-}
-
-static void
cifs_readv_callback(struct mid_q_entry *mid)
{
struct cifs_readdata *rdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
struct TCP_Server_Info *server = tcon->ses->server;
- cFYI(1, "%s: mid=%u state=%d result=%d bytes=%u", __func__,
- mid->mid, mid->midState, rdata->result, rdata->bytes);
+ cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
+ mid->mid, mid->mid_state, rdata->result, rdata->bytes);
- switch (mid->midState) {
+ switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED:
/* result already set, check signature */
if (server->sec_mode &
@@ -1667,10 +1561,9 @@ cifs_readv_callback(struct mid_q_entry *mid)
rdata->result = -EIO;
}
- queue_work(system_nrt_wq, &rdata->work);
+ queue_work(cifsiod_wq, &rdata->work);
DeleteMidQEntry(mid);
- atomic_dec(&server->inFlight);
- wake_up(&server->request_q);
+ add_credits(server, 1);
}
/* cifs_async_readv - send an async write, and set up mid to handle result */
@@ -1723,12 +1616,15 @@ cifs_async_readv(struct cifs_readdata *rdata)
rdata->iov[0].iov_base = smb;
rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
+ kref_get(&rdata->refcount);
rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
cifs_readv_receive, cifs_readv_callback,
rdata, false);
if (rc == 0)
cifs_stats_inc(&tcon->num_reads);
+ else
+ kref_put(&rdata->refcount, cifs_readdata_release);
cifs_small_buf_release(smb);
return rc;
@@ -2014,7 +1910,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
kref_put(&wdata->refcount, cifs_writedata_release);
}
-static void
+void
cifs_writev_complete(struct work_struct *work)
{
struct cifs_writedata *wdata = container_of(work,
@@ -2023,7 +1919,9 @@ cifs_writev_complete(struct work_struct *work)
int i = 0;
if (wdata->result == 0) {
+ spin_lock(&inode->i_lock);
cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
+ spin_unlock(&inode->i_lock);
cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
wdata->bytes);
} else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
@@ -2044,7 +1942,7 @@ cifs_writev_complete(struct work_struct *work)
}
struct cifs_writedata *
-cifs_writedata_alloc(unsigned int nr_pages)
+cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
{
struct cifs_writedata *wdata;
@@ -2058,14 +1956,16 @@ cifs_writedata_alloc(unsigned int nr_pages)
wdata = kzalloc(sizeof(*wdata) +
sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
if (wdata != NULL) {
- INIT_WORK(&wdata->work, cifs_writev_complete);
kref_init(&wdata->refcount);
+ INIT_LIST_HEAD(&wdata->list);
+ init_completion(&wdata->done);
+ INIT_WORK(&wdata->work, complete);
}
return wdata;
}
/*
- * Check the midState and signature on received buffer (if any), and queue the
+ * Check the mid_state and signature on received buffer (if any), and queue the
* workqueue completion task.
*/
static void
@@ -2076,7 +1976,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
unsigned int written;
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
- switch (mid->midState) {
+ switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED:
wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
if (wdata->result != 0)
@@ -2108,10 +2008,9 @@ cifs_writev_callback(struct mid_q_entry *mid)
break;
}
- queue_work(system_nrt_wq, &wdata->work);
+ queue_work(cifsiod_wq, &wdata->work);
DeleteMidQEntry(mid);
- atomic_dec(&tcon->ses->server->inFlight);
- wake_up(&tcon->ses->server->request_q);
+ add_credits(tcon->ses->server, 1);
}
/* cifs_async_writev - send an async write, and set up mid to handle result */
@@ -2122,7 +2021,6 @@ cifs_async_writev(struct cifs_writedata *wdata)
WRITE_REQ *smb = NULL;
int wct;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
- struct inode *inode = wdata->cfile->dentry->d_inode;
struct kvec *iov = NULL;
if (tcon->ses->capabilities & CAP_LARGE_FILES) {
@@ -2146,8 +2044,8 @@ cifs_async_writev(struct cifs_writedata *wdata)
goto async_writev_out;
}
- smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
- smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
+ smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
+ smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */
smb->Fid = wdata->cfile->netfid;
@@ -2165,15 +2063,13 @@ cifs_async_writev(struct cifs_writedata *wdata)
iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
iov[0].iov_base = smb;
- /* marshal up the pages into iov array */
- wdata->bytes = 0;
- for (i = 0; i < wdata->nr_pages; i++) {
- iov[i + 1].iov_len = min(inode->i_size -
- page_offset(wdata->pages[i]),
- (loff_t)PAGE_CACHE_SIZE);
- iov[i + 1].iov_base = kmap(wdata->pages[i]);
- wdata->bytes += iov[i + 1].iov_len;
- }
+ /*
+ * This function should marshal up the page array into the kvec
+ * array, reserving [0] for the header. It should kmap the pages
+ * and set the iov_len properly for each one. It may also set
+ * wdata->bytes too.
+ */
+ wdata->marshal_iov(iov, wdata);
cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
@@ -2418,8 +2314,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
(struct smb_hdr *) pSMB, &bytes_returned);
cifs_small_buf_release(pSMB);
} else {
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
- timeout);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout);
/* SMB buffer freed by function above */
}
cifs_stats_inc(&tcon->num_locks);
@@ -2586,7 +2481,7 @@ CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
pSMB->FileID = (__u16) smb_file_id;
pSMB->LastWriteTime = 0xFFFFFFFF;
pSMB->ByteCount = 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
cifs_stats_inc(&tcon->num_closes);
if (rc) {
if (rc != -EINTR) {
@@ -2615,7 +2510,7 @@ CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
pSMB->FileID = (__u16) smb_file_id;
pSMB->ByteCount = 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
cifs_stats_inc(&tcon->num_flushes);
if (rc)
cERROR(1, "Send error in Flush = %d", rc);
@@ -3872,13 +3767,12 @@ CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
int rc = 0;
int bytes_returned = 0;
SET_SEC_DESC_REQ *pSMB = NULL;
- NTRANSACT_RSP *pSMBr = NULL;
+ void *pSMBr;
setCifsAclRetry:
- rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
- (void **) &pSMBr);
+ rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
if (rc)
- return (rc);
+ return rc;
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
@@ -3906,9 +3800,8 @@ setCifsAclRetry:
pSMB->AclFlags = cpu_to_le32(aclflag);
if (pntsd && acllen) {
- memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
- (char *) pntsd,
- acllen);
+ memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
+ data_offset, pntsd, acllen);
inc_rfc1001_len(pSMB, byte_count + data_count);
} else
inc_rfc1001_len(pSMB, byte_count);
@@ -4326,7 +4219,7 @@ int
CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
const char *searchName,
const struct nls_table *nls_codepage,
- __u16 *pnetfid,
+ __u16 *pnetfid, __u16 search_flags,
struct cifs_search_info *psrch_inf, int remap, const char dirsep)
{
/* level 257 SMB_ */
@@ -4398,8 +4291,7 @@ findFirstRetry:
cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
ATTR_DIRECTORY);
pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
- pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
- CIFS_SEARCH_RETURN_RESUME);
+ pSMB->SearchFlags = cpu_to_le16(search_flags);
pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
/* BB what should we set StorageType to? Does it matter? BB */
@@ -4469,8 +4361,8 @@ findFirstRetry:
return rc;
}
-int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
- __u16 searchHandle, struct cifs_search_info *psrch_inf)
+int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
+ __u16 search_flags, struct cifs_search_info *psrch_inf)
{
TRANSACTION2_FNEXT_REQ *pSMB = NULL;
TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
@@ -4513,8 +4405,7 @@ int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
pSMB->ResumeKey = psrch_inf->resume_key;
- pSMB->SearchFlags =
- cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
+ pSMB->SearchFlags = cpu_to_le16(search_flags);
name_len = psrch_inf->resume_name_len;
params += name_len;
@@ -4623,7 +4514,7 @@ CIFSFindClose(const int xid, struct cifs_tcon *tcon,
pSMB->FileID = searchHandle;
pSMB->ByteCount = 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
if (rc)
cERROR(1, "Send error in FindClose = %d", rc);
@@ -4826,8 +4717,12 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
max_len = data_end - temp;
node->node_name = cifs_strndup_from_utf16(temp, max_len,
is_unicode, nls_codepage);
- if (!node->node_name)
+ if (!node->node_name) {
rc = -ENOMEM;
+ goto parse_DFS_referrals_exit;
+ }
+
+ ref++;
}
parse_DFS_referrals_exit:
@@ -5644,7 +5539,7 @@ CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
pSMB->Reserved4 = 0;
inc_rfc1001_len(pSMB, byte_count);
pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
if (rc) {
cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
}
@@ -5688,7 +5583,8 @@ CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
offset = param_offset + params;
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
+ data_offset = (char *)pSMB +
+ offsetof(struct smb_hdr, Protocol) + offset;
count = sizeof(FILE_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -5713,7 +5609,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
inc_rfc1001_len(pSMB, byte_count);
pSMB->ByteCount = cpu_to_le16(byte_count);
memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
if (rc)
cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
@@ -5772,7 +5668,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
inc_rfc1001_len(pSMB, byte_count);
pSMB->ByteCount = cpu_to_le16(byte_count);
*data_offset = delete_file ? 1 : 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
if (rc)
cFYI(1, "Send error in SetFileDisposition = %d", rc);
@@ -5957,7 +5853,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
u16 fid, u32 pid_of_opener)
{
struct smb_com_transaction2_sfi_req *pSMB = NULL;
- FILE_UNIX_BASIC_INFO *data_offset;
+ char *data_offset;
int rc = 0;
u16 params, param_offset, offset, byte_count, count;
@@ -5979,8 +5875,9 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
offset = param_offset + params;
- data_offset = (FILE_UNIX_BASIC_INFO *)
- ((char *)(&pSMB->hdr.Protocol) + offset);
+ data_offset = (char *)pSMB +
+ offsetof(struct smb_hdr, Protocol) + offset;
+
count = sizeof(FILE_UNIX_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -6002,9 +5899,9 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
inc_rfc1001_len(pSMB, byte_count);
pSMB->ByteCount = cpu_to_le16(byte_count);
- cifs_fill_unix_set_info(data_offset, args);
+ cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
- rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
if (rc)
cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);