Commit 5e6c470d authored by Pavel Shilovsky's avatar Pavel Shilovsky

Update 3.2 sources from stable (v3.2.14)

parent 50bed2c9
......@@ -76,7 +76,7 @@ MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
unsigned int cifs_max_pending = CIFS_MAX_REQ;
module_param(cifs_max_pending, int, 0444);
MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
"Default: 50 Range: 2 to 256");
"Default: 32767 Range: 2 to 32767.");
unsigned short echo_retries = 5;
module_param(echo_retries, ushort, 0644);
MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and "
......@@ -1119,9 +1119,9 @@ init_cifs(void)
if (cifs_max_pending < 2) {
cifs_max_pending = 2;
cFYI(1, "cifs_max_pending set to min of 2");
} else if (cifs_max_pending > 256) {
cifs_max_pending = 256;
cFYI(1, "cifs_max_pending set to max of 256");
} else if (cifs_max_pending > CIFS_MAX_REQ) {
cifs_max_pending = CIFS_MAX_REQ;
cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ);
}
rc = cifs_fscache_register();
......
......@@ -55,14 +55,9 @@
/*
* MAX_REQ is the maximum number of requests that WE will send
* on one socket concurrently. It also matches the most common
* value of max multiplex returned by servers. We may
* eventually want to use the negotiated value (in case
* future servers can handle more) when we are more confident that
* we will not have problems oveloading the socket with pending
* write data.
* on one socket concurrently.
*/
#define CIFS_MAX_REQ 50
#define CIFS_MAX_REQ 32767
#define RFC1001_NAME_LEN 15
#define RFC1001_NAME_LEN_WITH_NULL (RFC1001_NAME_LEN + 1)
......@@ -264,6 +259,7 @@ struct TCP_Server_Info {
bool session_estab; /* mark when very first sess is established */
u16 dialect; /* dialect index that server chose */
enum securityEnum secType;
bool oplocks:1; /* enable oplocks */
unsigned int maxReq; /* Clients should submit no more */
/* than maxReq distinct unanswered SMBs to the server when using */
/* multiplexed reads or writes */
......
......@@ -458,7 +458,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);
server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
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 +567,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);
server->oplocks = server->maxReq > 1 ? enable_oplocks : false;
/* probably no need to store and check maxvcs */
server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
......
......@@ -625,14 +625,10 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
spin_unlock(&GlobalMid_Lock);
wake_up_all(&server->response_q);
/*
* Check if we have blocked requests that need to free. Note that
* cifs_max_pending is normally 50, but can be set at module install
* time to as little as two.
*/
/* Check if we have blocked requests that need to free. */
spin_lock(&GlobalMid_Lock);
if (atomic_read(&server->inFlight) >= cifs_max_pending)
atomic_set(&server->inFlight, cifs_max_pending - 1);
if (atomic_read(&server->inFlight) >= server->maxReq)
atomic_set(&server->inFlight, server->maxReq - 1);
/*
* We do not want to set the max_pending too low or we could end up
* with the counter going negative.
......@@ -756,10 +752,11 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
cifs_dump_mem("Bad SMB: ", buf,
min_t(unsigned int, server->total_read, 48));
if (mid)
handle_mid(mid, server, smb_buffer, length);
if (!mid)
return length;
return length;
handle_mid(mid, server, smb_buffer, length);
return 0;
}
static int
......@@ -1893,6 +1890,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
tcp_ses->noautotune = volume_info->noautotune;
tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
atomic_set(&tcp_ses->inFlight, 0);
tcp_ses->maxReq = 1; /* enough to send negotiate request */
init_waitqueue_head(&tcp_ses->response_q);
init_waitqueue_head(&tcp_ses->request_q);
INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
......@@ -3223,7 +3221,7 @@ cifs_ra_pages(struct cifs_sb_info *cifs_sb)
int
cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
{
int rc = 0;
int rc;
int xid;
struct cifs_ses *pSesInfo;
struct cifs_tcon *tcon;
......@@ -3250,6 +3248,7 @@ try_mount_again:
FreeXid(xid);
}
#endif
rc = 0;
tcon = NULL;
pSesInfo = NULL;
srvTcp = NULL;
......
......@@ -172,7 +172,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
}
tcon = tlink_tcon(tlink);
if (enable_oplocks)
if (tcon->ses->server->oplocks)
oplock = REQ_OPLOCK;
if (nd)
......@@ -495,7 +495,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
{
int xid;
int rc = 0; /* to get around spurious gcc warning, set to zero here */
__u32 oplock = 0;
__u32 oplock;
__u16 fileHandle = 0;
bool posix_open = false;
struct cifs_sb_info *cifs_sb;
......@@ -521,6 +521,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
}
pTcon = tlink_tcon(tlink);
oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
/*
* Don't allow the separator character in a path component.
* The VFS will not allow "/", but "\" is allowed by posix.
......@@ -588,10 +590,26 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
* If either that or op not supported returned, follow
* the normal lookup.
*/
if ((rc == 0) || (rc == -ENOENT))
switch (rc) {
case 0:
/*
* The server may allow us to open things like
* FIFOs, but the client isn't set up to deal
* with that. If it's not a regular file, just
* close it and proceed as if it were a normal
* lookup.
*/
if (newInode && !S_ISREG(newInode->i_mode)) {
CIFSSMBClose(xid, pTcon, fileHandle);
break;
}
case -ENOENT:
posix_open = true;
else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
case -EOPNOTSUPP:
break;
default:
pTcon->broken_posix_open = true;
}
}
if (!posix_open)
rc = cifs_get_inode_info_unix(&newInode, full_path,
......
......@@ -382,7 +382,7 @@ int cifs_open(struct inode *inode, struct file *file)
cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
inode, file->f_flags, full_path);
if (enable_oplocks)
if (tcon->ses->server->oplocks)
oplock = REQ_OPLOCK;
else
oplock = 0;
......@@ -509,7 +509,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
cFYI(1, "inode = 0x%p file flags 0x%x for %s",
inode, pCifsFile->f_flags, full_path);
if (enable_oplocks)
if (tcon->ses->server->oplocks)
oplock = REQ_OPLOCK;
else
oplock = 0;
......@@ -926,16 +926,26 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
for (lockp = &inode->i_flock; *lockp != NULL; \
lockp = &(*lockp)->fl_next)
struct lock_to_push {
struct list_head llist;
__u64 offset;
__u64 length;
__u32 pid;
__u16 netfid;
__u8 type;
};
static int
cifs_push_posix_locks(struct cifsFileInfo *cfile)
{
struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
struct file_lock *flock, **before;
struct cifsLockInfo *lck, *tmp;
unsigned int count = 0, i = 0;
int rc = 0, xid, type;
struct list_head locks_to_send, *el;
struct lock_to_push *lck, *tmp;
__u64 length;
struct list_head locks_to_send;
xid = GetXid();
......@@ -946,29 +956,56 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
return rc;
}
lock_flocks();
cifs_for_each_lock(cfile->dentry->d_inode, before) {
if ((*before)->fl_flags & FL_POSIX)
count++;
}
unlock_flocks();
INIT_LIST_HEAD(&locks_to_send);
/*
* Allocating count locks is enough because no FL_POSIX locks can be
* added to the list while we are holding cinode->lock_mutex that
* protects locking operations of this inode.
*/
for (; i < count; i++) {
lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
if (!lck) {
rc = -ENOMEM;
goto err_out;
}
list_add_tail(&lck->llist, &locks_to_send);
}
el = locks_to_send.next;
lock_flocks();
cifs_for_each_lock(cfile->dentry->d_inode, before) {
flock = *before;
if ((flock->fl_flags & FL_POSIX) == 0)
continue;
if (el == &locks_to_send) {
/*
* The list ended. We don't have enough allocated
* structures - something is really wrong.
*/
cERROR(1, "Can't push all brlocks!");
break;
}
length = 1 + flock->fl_end - flock->fl_start;
if (flock->fl_type == F_RDLCK || flock->fl_type == F_SHLCK)
type = CIFS_RDLCK;
else
type = CIFS_WRLCK;
lck = cifs_lock_init(flock->fl_start, length, type,
cfile->netfid);
if (!lck) {
rc = -ENOMEM;
goto send_locks;
}
lck = list_entry(el, struct lock_to_push, llist);
lck->pid = flock->fl_pid;
list_add_tail(&lck->llist, &locks_to_send);
lck->netfid = cfile->netfid;
lck->length = length;
lck->type = type;
lck->offset = flock->fl_start;
el = el->next;
}
send_locks:
unlock_flocks();
list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
......@@ -985,11 +1022,18 @@ send_locks:
kfree(lck);
}
out:
cinode->can_cache_brlcks = false;
mutex_unlock(&cinode->lock_mutex);
FreeXid(xid);
return rc;
err_out:
list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
list_del(&lck->llist);
kfree(lck);
}
goto out;
}
static int
......
......@@ -265,12 +265,12 @@ static int wait_for_free_request(struct TCP_Server_Info *server,
spin_lock(&GlobalMid_Lock);
while (1) {
if (atomic_read(&server->inFlight) >= cifs_max_pending) {
if (atomic_read(&server->inFlight) >= server->maxReq) {
spin_unlock(&GlobalMid_Lock);
cifs_num_waiters_inc(server);
wait_event(server->request_q,
atomic_read(&server->inFlight)
< cifs_max_pending);
< server->maxReq);
cifs_num_waiters_dec(server);
spin_lock(&GlobalMid_Lock);
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment