提交 5551638a 编写于 作者: L Linus Torvalds

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
Version 1.62
------------
Add sockopt=TCP_NODELAY mount option.
Version 1.61 Version 1.61
------------ ------------
Fix append problem to Samba servers (files opened with O_APPEND could 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); ...@@ -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; extern const struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */ #endif /* EXPERIMENTAL */
#define CIFS_VERSION "1.61" #define CIFS_VERSION "1.62"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
...@@ -149,6 +149,7 @@ struct TCP_Server_Info { ...@@ -149,6 +149,7 @@ struct TCP_Server_Info {
bool svlocal:1; /* local server or remote */ bool svlocal:1; /* local server or remote */
bool noblocksnd; /* use blocking sendmsg */ bool noblocksnd; /* use blocking sendmsg */
bool noautotune; /* do not autotune send buf sizes */ bool noautotune; /* do not autotune send buf sizes */
bool tcp_nodelay;
atomic_t inFlight; /* number of requests on the wire to server */ atomic_t inFlight; /* number of requests on the wire to server */
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
atomic_t inSend; /* requests trying to send */ atomic_t inSend; /* requests trying to send */
......
...@@ -98,7 +98,7 @@ struct smb_vol { ...@@ -98,7 +98,7 @@ struct smb_vol {
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
unsigned int rsize; unsigned int rsize;
unsigned int wsize; unsigned int wsize;
unsigned int sockopt; bool sockopt_tcp_nodelay:1;
unsigned short int port; unsigned short int port;
char *prepath; char *prepath;
}; };
...@@ -1142,9 +1142,11 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1142,9 +1142,11 @@ cifs_parse_mount_options(char *options, const char *devname,
simple_strtoul(value, &value, 0); simple_strtoul(value, &value, 0);
} }
} else if (strnicmp(data, "sockopt", 5) == 0) { } else if (strnicmp(data, "sockopt", 5) == 0) {
if (value && *value) { if (!value || !*value) {
vol->sockopt = cERROR(1, ("no socket option specified"));
simple_strtoul(value, &value, 0); continue;
} else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
vol->sockopt_tcp_nodelay = 1;
} }
} else if (strnicmp(data, "netbiosname", 4) == 0) { } else if (strnicmp(data, "netbiosname", 4) == 0) {
if (!value || !*value || (*value == ' ')) { if (!value || !*value || (*value == ' ')) {
...@@ -1514,6 +1516,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) ...@@ -1514,6 +1516,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
tcp_ses->noblocksnd = volume_info->noblocksnd; tcp_ses->noblocksnd = volume_info->noblocksnd;
tcp_ses->noautotune = volume_info->noautotune; tcp_ses->noautotune = volume_info->noautotune;
tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
atomic_set(&tcp_ses->inFlight, 0); atomic_set(&tcp_ses->inFlight, 0);
init_waitqueue_head(&tcp_ses->response_q); init_waitqueue_head(&tcp_ses->response_q);
init_waitqueue_head(&tcp_ses->request_q); init_waitqueue_head(&tcp_ses->request_q);
...@@ -1764,6 +1767,7 @@ static int ...@@ -1764,6 +1767,7 @@ static int
ipv4_connect(struct TCP_Server_Info *server) ipv4_connect(struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
int val;
bool connected = false; bool connected = false;
__be16 orig_port = 0; __be16 orig_port = 0;
struct socket *socket = server->ssocket; struct socket *socket = server->ssocket;
...@@ -1845,6 +1849,14 @@ ipv4_connect(struct TCP_Server_Info *server) ...@@ -1845,6 +1849,14 @@ ipv4_connect(struct TCP_Server_Info *server)
socket->sk->sk_rcvbuf = 140 * 1024; 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", cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
socket->sk->sk_sndbuf, socket->sk->sk_sndbuf,
socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo)); socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
...@@ -1916,6 +1928,7 @@ static int ...@@ -1916,6 +1928,7 @@ static int
ipv6_connect(struct TCP_Server_Info *server) ipv6_connect(struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
int val;
bool connected = false; bool connected = false;
__be16 orig_port = 0; __be16 orig_port = 0;
struct socket *socket = server->ssocket; struct socket *socket = server->ssocket;
...@@ -1987,6 +2000,15 @@ ipv6_connect(struct TCP_Server_Info *server) ...@@ -1987,6 +2000,15 @@ ipv6_connect(struct TCP_Server_Info *server)
*/ */
socket->sk->sk_rcvtimeo = 7 * HZ; socket->sk->sk_rcvtimeo = 7 * HZ;
socket->sk->sk_sndtimeo = 5 * 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; server->ssocket = socket;
return rc; return rc;
......
...@@ -1762,8 +1762,18 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) ...@@ -1762,8 +1762,18 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
} }
if (!rc) if (!rc) {
rc = inode_setattr(inode, attrs); 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: out:
kfree(args); kfree(args);
kfree(full_path); kfree(full_path);
......
...@@ -77,6 +77,11 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, ...@@ -77,6 +77,11 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
cFYI(1, ("For %s", name->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); dentry = d_lookup(parent, name);
if (dentry) { if (dentry) {
/* FIXME: check for inode number changes? */ /* FIXME: check for inode number changes? */
...@@ -666,12 +671,11 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, ...@@ -666,12 +671,11 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
min(len, max_len), nlt, min(len, max_len), nlt,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
pqst->len -= nls_nullsize(nlt);
} else { } else {
pqst->name = filename; pqst->name = filename;
pqst->len = len; pqst->len = len;
} }
pqst->hash = full_name_hash(pqst->name, pqst->len);
/* cFYI(1, ("filldir on %s",pqst->name)); */
return rc; return rc;
} }
......
...@@ -223,9 +223,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, ...@@ -223,9 +223,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
/* null user mount */ /* null user mount */
*bcc_ptr = 0; *bcc_ptr = 0;
*(bcc_ptr+1) = 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, 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 * bytes_ret;
bcc_ptr += 2; /* account for null termination */ bcc_ptr += 2; /* account for null termination */
...@@ -246,11 +246,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, ...@@ -246,11 +246,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
/* copy user */ /* copy user */
if (ses->userName == NULL) { if (ses->userName == NULL) {
/* BB what about null user mounts - check that we do this BB */ /* BB what about null user mounts - check that we do this BB */
} else { /* 300 should be long enough for any conceivable user name */ } else {
strncpy(bcc_ptr, ses->userName, 300); strncpy(bcc_ptr, ses->userName, MAX_USERNAME_SIZE);
} }
/* BB improve check for overflow */ bcc_ptr += strnlen(ses->userName, MAX_USERNAME_SIZE);
bcc_ptr += strnlen(ses->userName, 300);
*bcc_ptr = 0; *bcc_ptr = 0;
bcc_ptr++; /* account for null termination */ bcc_ptr++; /* account for null termination */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册