Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: cifs: fix dentry hash calculation for case-insensitive mounts [CIFS] Don't cache timestamps on utimes due to coarse granularity [CIFS] Maximum username length check in session setup does not match cifs: fix length calculation for converted unicode readdir names [CIFS] Add support for TCP_NODELAY
This commit is contained in:
commit
5551638acb
7 changed files with 54 additions and 14 deletions
|
@ -1,3 +1,7 @@
|
|||
Version 1.62
|
||||
------------
|
||||
Add sockopt=TCP_NODELAY mount option.
|
||||
|
||||
Version 1.61
|
||||
------------
|
||||
Fix append problem to Samba servers (files opened with O_APPEND could
|
||||
|
|
|
@ -113,5 +113,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
|
|||
extern const struct export_operations cifs_export_ops;
|
||||
#endif /* EXPERIMENTAL */
|
||||
|
||||
#define CIFS_VERSION "1.61"
|
||||
#define CIFS_VERSION "1.62"
|
||||
#endif /* _CIFSFS_H */
|
||||
|
|
|
@ -149,6 +149,7 @@ struct TCP_Server_Info {
|
|||
bool svlocal:1; /* local server or remote */
|
||||
bool noblocksnd; /* use blocking sendmsg */
|
||||
bool noautotune; /* do not autotune send buf sizes */
|
||||
bool tcp_nodelay;
|
||||
atomic_t inFlight; /* number of requests on the wire to server */
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_t inSend; /* requests trying to send */
|
||||
|
|
|
@ -98,7 +98,7 @@ struct smb_vol {
|
|||
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
|
||||
unsigned int rsize;
|
||||
unsigned int wsize;
|
||||
unsigned int sockopt;
|
||||
bool sockopt_tcp_nodelay:1;
|
||||
unsigned short int port;
|
||||
char *prepath;
|
||||
};
|
||||
|
@ -1142,9 +1142,11 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
simple_strtoul(value, &value, 0);
|
||||
}
|
||||
} else if (strnicmp(data, "sockopt", 5) == 0) {
|
||||
if (value && *value) {
|
||||
vol->sockopt =
|
||||
simple_strtoul(value, &value, 0);
|
||||
if (!value || !*value) {
|
||||
cERROR(1, ("no socket option specified"));
|
||||
continue;
|
||||
} else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
|
||||
vol->sockopt_tcp_nodelay = 1;
|
||||
}
|
||||
} else if (strnicmp(data, "netbiosname", 4) == 0) {
|
||||
if (!value || !*value || (*value == ' ')) {
|
||||
|
@ -1514,6 +1516,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
|
|||
|
||||
tcp_ses->noblocksnd = volume_info->noblocksnd;
|
||||
tcp_ses->noautotune = volume_info->noautotune;
|
||||
tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
|
||||
atomic_set(&tcp_ses->inFlight, 0);
|
||||
init_waitqueue_head(&tcp_ses->response_q);
|
||||
init_waitqueue_head(&tcp_ses->request_q);
|
||||
|
@ -1764,6 +1767,7 @@ static int
|
|||
ipv4_connect(struct TCP_Server_Info *server)
|
||||
{
|
||||
int rc = 0;
|
||||
int val;
|
||||
bool connected = false;
|
||||
__be16 orig_port = 0;
|
||||
struct socket *socket = server->ssocket;
|
||||
|
@ -1845,6 +1849,14 @@ ipv4_connect(struct TCP_Server_Info *server)
|
|||
socket->sk->sk_rcvbuf = 140 * 1024;
|
||||
}
|
||||
|
||||
if (server->tcp_nodelay) {
|
||||
val = 1;
|
||||
rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
|
||||
(char *)&val, sizeof(val));
|
||||
if (rc)
|
||||
cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
|
||||
}
|
||||
|
||||
cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
|
||||
socket->sk->sk_sndbuf,
|
||||
socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
|
||||
|
@ -1916,6 +1928,7 @@ static int
|
|||
ipv6_connect(struct TCP_Server_Info *server)
|
||||
{
|
||||
int rc = 0;
|
||||
int val;
|
||||
bool connected = false;
|
||||
__be16 orig_port = 0;
|
||||
struct socket *socket = server->ssocket;
|
||||
|
@ -1987,6 +2000,15 @@ ipv6_connect(struct TCP_Server_Info *server)
|
|||
*/
|
||||
socket->sk->sk_rcvtimeo = 7 * HZ;
|
||||
socket->sk->sk_sndtimeo = 5 * HZ;
|
||||
|
||||
if (server->tcp_nodelay) {
|
||||
val = 1;
|
||||
rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
|
||||
(char *)&val, sizeof(val));
|
||||
if (rc)
|
||||
cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
|
||||
}
|
||||
|
||||
server->ssocket = socket;
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -1762,8 +1762,18 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
|||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
if (!rc) {
|
||||
rc = inode_setattr(inode, attrs);
|
||||
|
||||
/* force revalidate when any of these times are set since some
|
||||
of the fs types (eg ext3, fat) do not have fine enough
|
||||
time granularity to match protocol, and we do not have a
|
||||
a way (yet) to query the server fs's time granularity (and
|
||||
whether it rounds times down).
|
||||
*/
|
||||
if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
|
||||
cifsInode->time = 0;
|
||||
}
|
||||
out:
|
||||
kfree(args);
|
||||
kfree(full_path);
|
||||
|
|
|
@ -77,6 +77,11 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
|
|||
|
||||
cFYI(1, ("For %s", name->name));
|
||||
|
||||
if (parent->d_op && parent->d_op->d_hash)
|
||||
parent->d_op->d_hash(parent, name);
|
||||
else
|
||||
name->hash = full_name_hash(name->name, name->len);
|
||||
|
||||
dentry = d_lookup(parent, name);
|
||||
if (dentry) {
|
||||
/* FIXME: check for inode number changes? */
|
||||
|
@ -666,12 +671,11 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
|
|||
min(len, max_len), nlt,
|
||||
cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
pqst->len -= nls_nullsize(nlt);
|
||||
} else {
|
||||
pqst->name = filename;
|
||||
pqst->len = len;
|
||||
}
|
||||
pqst->hash = full_name_hash(pqst->name, pqst->len);
|
||||
/* cFYI(1, ("filldir on %s",pqst->name)); */
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,9 +223,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
|
|||
/* null user mount */
|
||||
*bcc_ptr = 0;
|
||||
*(bcc_ptr+1) = 0;
|
||||
} else { /* 300 should be long enough for any conceivable user name */
|
||||
} else {
|
||||
bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
|
||||
300, nls_cp);
|
||||
MAX_USERNAME_SIZE, nls_cp);
|
||||
}
|
||||
bcc_ptr += 2 * bytes_ret;
|
||||
bcc_ptr += 2; /* account for null termination */
|
||||
|
@ -246,11 +246,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
|
|||
/* copy user */
|
||||
if (ses->userName == NULL) {
|
||||
/* BB what about null user mounts - check that we do this BB */
|
||||
} else { /* 300 should be long enough for any conceivable user name */
|
||||
strncpy(bcc_ptr, ses->userName, 300);
|
||||
} else {
|
||||
strncpy(bcc_ptr, ses->userName, MAX_USERNAME_SIZE);
|
||||
}
|
||||
/* BB improve check for overflow */
|
||||
bcc_ptr += strnlen(ses->userName, 300);
|
||||
bcc_ptr += strnlen(ses->userName, MAX_USERNAME_SIZE);
|
||||
*bcc_ptr = 0;
|
||||
bcc_ptr++; /* account for null termination */
|
||||
|
||||
|
|
Loading…
Reference in a new issue