diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/CHANGES | 4 | ||||
-rw-r--r-- | fs/cifs/cifsencrypt.c | 18 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/connect.c | 24 | ||||
-rw-r--r-- | fs/cifs/dir.c | 56 | ||||
-rw-r--r-- | fs/cifs/inode.c | 5 | ||||
-rw-r--r-- | fs/cifs/md5.c | 38 | ||||
-rw-r--r-- | fs/cifs/md5.h | 6 | ||||
-rw-r--r-- | fs/cifs/transport.c | 127 |
9 files changed, 121 insertions, 161 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 080703a15f44..73ac7ebd1dfc 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -5,7 +5,9 @@ rather than posix (advisory) byte range locks, even though server would | |||
5 | support posix byte range locks. Fix query of root inode when prefixpath | 5 | support posix byte range locks. Fix query of root inode when prefixpath |
6 | specified and user does not have access to query information about the | 6 | specified and user does not have access to query information about the |
7 | top of the share. Fix problem in 2.6.28 resolving DFS paths to | 7 | top of the share. Fix problem in 2.6.28 resolving DFS paths to |
8 | Samba servers (worked to Windows). | 8 | Samba servers (worked to Windows). Fix rmdir so that pending search |
9 | (readdir) requests do not get invalid results which include the now | ||
10 | removed directory. | ||
9 | 11 | ||
10 | Version 1.55 | 12 | Version 1.55 |
11 | ------------ | 13 | ------------ |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index d4839cf0cb2c..7c9809523f42 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -48,11 +48,11 @@ static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, | |||
48 | if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) | 48 | if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) |
49 | return -EINVAL; | 49 | return -EINVAL; |
50 | 50 | ||
51 | MD5Init(&context); | 51 | cifs_MD5_init(&context); |
52 | MD5Update(&context, (char *)&key->data, key->len); | 52 | cifs_MD5_update(&context, (char *)&key->data, key->len); |
53 | MD5Update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); | 53 | cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); |
54 | 54 | ||
55 | MD5Final(signature, &context); | 55 | cifs_MD5_final(signature, &context); |
56 | return 0; | 56 | return 0; |
57 | } | 57 | } |
58 | 58 | ||
@@ -96,8 +96,8 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, | |||
96 | if ((iov == NULL) || (signature == NULL) || (key == NULL)) | 96 | if ((iov == NULL) || (signature == NULL) || (key == NULL)) |
97 | return -EINVAL; | 97 | return -EINVAL; |
98 | 98 | ||
99 | MD5Init(&context); | 99 | cifs_MD5_init(&context); |
100 | MD5Update(&context, (char *)&key->data, key->len); | 100 | cifs_MD5_update(&context, (char *)&key->data, key->len); |
101 | for (i = 0; i < n_vec; i++) { | 101 | for (i = 0; i < n_vec; i++) { |
102 | if (iov[i].iov_len == 0) | 102 | if (iov[i].iov_len == 0) |
103 | continue; | 103 | continue; |
@@ -110,13 +110,13 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, | |||
110 | if (i == 0) { | 110 | if (i == 0) { |
111 | if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ | 111 | if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ |
112 | break; /* nothing to sign or corrupt header */ | 112 | break; /* nothing to sign or corrupt header */ |
113 | MD5Update(&context, iov[0].iov_base+4, | 113 | cifs_MD5_update(&context, iov[0].iov_base+4, |
114 | iov[0].iov_len-4); | 114 | iov[0].iov_len-4); |
115 | } else | 115 | } else |
116 | MD5Update(&context, iov[i].iov_base, iov[i].iov_len); | 116 | cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); |
117 | } | 117 | } |
118 | 118 | ||
119 | MD5Final(signature, &context); | 119 | cifs_MD5_final(signature, &context); |
120 | 120 | ||
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 06f6779988bf..382ba6298809 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -35,8 +35,8 @@ extern struct smb_hdr *cifs_buf_get(void); | |||
35 | extern void cifs_buf_release(void *); | 35 | extern void cifs_buf_release(void *); |
36 | extern struct smb_hdr *cifs_small_buf_get(void); | 36 | extern struct smb_hdr *cifs_small_buf_get(void); |
37 | extern void cifs_small_buf_release(void *); | 37 | extern void cifs_small_buf_release(void *); |
38 | extern int smb_send(struct socket *, struct smb_hdr *, | 38 | extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *, |
39 | unsigned int /* length */ , struct sockaddr *, bool); | 39 | unsigned int /* length */); |
40 | extern unsigned int _GetXid(void); | 40 | extern unsigned int _GetXid(void); |
41 | extern void _FreeXid(unsigned int); | 41 | extern void _FreeXid(unsigned int); |
42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); | 42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e9ea394ee075..2209be943051 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1354,7 +1354,7 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | static struct TCP_Server_Info * | 1356 | static struct TCP_Server_Info * |
1357 | cifs_find_tcp_session(struct sockaddr *addr) | 1357 | cifs_find_tcp_session(struct sockaddr_storage *addr) |
1358 | { | 1358 | { |
1359 | struct list_head *tmp; | 1359 | struct list_head *tmp; |
1360 | struct TCP_Server_Info *server; | 1360 | struct TCP_Server_Info *server; |
@@ -1374,11 +1374,11 @@ cifs_find_tcp_session(struct sockaddr *addr) | |||
1374 | if (server->tcpStatus == CifsNew) | 1374 | if (server->tcpStatus == CifsNew) |
1375 | continue; | 1375 | continue; |
1376 | 1376 | ||
1377 | if (addr->sa_family == AF_INET && | 1377 | if (addr->ss_family == AF_INET && |
1378 | (addr4->sin_addr.s_addr != | 1378 | (addr4->sin_addr.s_addr != |
1379 | server->addr.sockAddr.sin_addr.s_addr)) | 1379 | server->addr.sockAddr.sin_addr.s_addr)) |
1380 | continue; | 1380 | continue; |
1381 | else if (addr->sa_family == AF_INET6 && | 1381 | else if (addr->ss_family == AF_INET6 && |
1382 | memcmp(&server->addr.sockAddr6.sin6_addr, | 1382 | memcmp(&server->addr.sockAddr6.sin6_addr, |
1383 | &addr6->sin6_addr, sizeof(addr6->sin6_addr))) | 1383 | &addr6->sin6_addr, sizeof(addr6->sin6_addr))) |
1384 | continue; | 1384 | continue; |
@@ -1419,12 +1419,12 @@ static struct TCP_Server_Info * | |||
1419 | cifs_get_tcp_session(struct smb_vol *volume_info) | 1419 | cifs_get_tcp_session(struct smb_vol *volume_info) |
1420 | { | 1420 | { |
1421 | struct TCP_Server_Info *tcp_ses = NULL; | 1421 | struct TCP_Server_Info *tcp_ses = NULL; |
1422 | struct sockaddr addr; | 1422 | struct sockaddr_storage addr; |
1423 | struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; | 1423 | struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; |
1424 | struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; | 1424 | struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; |
1425 | int rc; | 1425 | int rc; |
1426 | 1426 | ||
1427 | memset(&addr, 0, sizeof(struct sockaddr)); | 1427 | memset(&addr, 0, sizeof(struct sockaddr_storage)); |
1428 | 1428 | ||
1429 | if (volume_info->UNCip && volume_info->UNC) { | 1429 | if (volume_info->UNCip && volume_info->UNC) { |
1430 | rc = cifs_inet_pton(AF_INET, volume_info->UNCip, | 1430 | rc = cifs_inet_pton(AF_INET, volume_info->UNCip, |
@@ -1435,9 +1435,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
1435 | rc = cifs_inet_pton(AF_INET6, volume_info->UNCip, | 1435 | rc = cifs_inet_pton(AF_INET6, volume_info->UNCip, |
1436 | &sin_server6->sin6_addr.in6_u); | 1436 | &sin_server6->sin6_addr.in6_u); |
1437 | if (rc > 0) | 1437 | if (rc > 0) |
1438 | addr.sa_family = AF_INET6; | 1438 | addr.ss_family = AF_INET6; |
1439 | } else { | 1439 | } else { |
1440 | addr.sa_family = AF_INET; | 1440 | addr.ss_family = AF_INET; |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | if (rc <= 0) { | 1443 | if (rc <= 0) { |
@@ -1502,7 +1502,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
1502 | tcp_ses->tcpStatus = CifsNew; | 1502 | tcp_ses->tcpStatus = CifsNew; |
1503 | ++tcp_ses->srv_count; | 1503 | ++tcp_ses->srv_count; |
1504 | 1504 | ||
1505 | if (addr.sa_family == AF_INET6) { | 1505 | if (addr.ss_family == AF_INET6) { |
1506 | cFYI(1, ("attempting ipv6 connect")); | 1506 | cFYI(1, ("attempting ipv6 connect")); |
1507 | /* BB should we allow ipv6 on port 139? */ | 1507 | /* BB should we allow ipv6 on port 139? */ |
1508 | /* other OS never observed in Wild doing 139 with v6 */ | 1508 | /* other OS never observed in Wild doing 139 with v6 */ |
@@ -1802,7 +1802,7 @@ ipv4_connect(struct TCP_Server_Info *server) | |||
1802 | * user space buffer | 1802 | * user space buffer |
1803 | */ | 1803 | */ |
1804 | socket->sk->sk_rcvtimeo = 7 * HZ; | 1804 | socket->sk->sk_rcvtimeo = 7 * HZ; |
1805 | socket->sk->sk_sndtimeo = 3 * HZ; | 1805 | socket->sk->sk_sndtimeo = 5 * HZ; |
1806 | 1806 | ||
1807 | /* make the bufsizes depend on wsize/rsize and max requests */ | 1807 | /* make the bufsizes depend on wsize/rsize and max requests */ |
1808 | if (server->noautotune) { | 1808 | if (server->noautotune) { |
@@ -1860,9 +1860,7 @@ ipv4_connect(struct TCP_Server_Info *server) | |||
1860 | smb_buf = (struct smb_hdr *)ses_init_buf; | 1860 | smb_buf = (struct smb_hdr *)ses_init_buf; |
1861 | /* sizeof RFC1002_SESSION_REQUEST with no scope */ | 1861 | /* sizeof RFC1002_SESSION_REQUEST with no scope */ |
1862 | smb_buf->smb_buf_length = 0x81000044; | 1862 | smb_buf->smb_buf_length = 0x81000044; |
1863 | rc = smb_send(socket, smb_buf, 0x44, | 1863 | rc = smb_send(server, smb_buf, 0x44); |
1864 | (struct sockaddr *) &server->addr.sockAddr, | ||
1865 | server->noblocksnd); | ||
1866 | kfree(ses_init_buf); | 1864 | kfree(ses_init_buf); |
1867 | msleep(1); /* RFC1001 layer in at least one server | 1865 | msleep(1); /* RFC1001 layer in at least one server |
1868 | requires very short break before negprot | 1866 | requires very short break before negprot |
@@ -1955,7 +1953,7 @@ ipv6_connect(struct TCP_Server_Info *server) | |||
1955 | * user space buffer | 1953 | * user space buffer |
1956 | */ | 1954 | */ |
1957 | socket->sk->sk_rcvtimeo = 7 * HZ; | 1955 | socket->sk->sk_rcvtimeo = 7 * HZ; |
1958 | socket->sk->sk_sndtimeo = 3 * HZ; | 1956 | socket->sk->sk_sndtimeo = 5 * HZ; |
1959 | server->ssocket = socket; | 1957 | server->ssocket = socket; |
1960 | 1958 | ||
1961 | return rc; | 1959 | return rc; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 838d9c720a5c..964aad03c5ad 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -129,6 +129,17 @@ cifs_bp_rename_retry: | |||
129 | return full_path; | 129 | return full_path; |
130 | } | 130 | } |
131 | 131 | ||
132 | static void setup_cifs_dentry(struct cifsTconInfo *tcon, | ||
133 | struct dentry *direntry, | ||
134 | struct inode *newinode) | ||
135 | { | ||
136 | if (tcon->nocase) | ||
137 | direntry->d_op = &cifs_ci_dentry_ops; | ||
138 | else | ||
139 | direntry->d_op = &cifs_dentry_ops; | ||
140 | d_instantiate(direntry, newinode); | ||
141 | } | ||
142 | |||
132 | /* Inode operations in similar order to how they appear in Linux file fs.h */ | 143 | /* Inode operations in similar order to how they appear in Linux file fs.h */ |
133 | 144 | ||
134 | int | 145 | int |
@@ -139,14 +150,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
139 | int xid; | 150 | int xid; |
140 | int create_options = CREATE_NOT_DIR; | 151 | int create_options = CREATE_NOT_DIR; |
141 | int oplock = 0; | 152 | int oplock = 0; |
153 | /* BB below access is too much for the mknod to request */ | ||
142 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; | 154 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; |
143 | __u16 fileHandle; | 155 | __u16 fileHandle; |
144 | struct cifs_sb_info *cifs_sb; | 156 | struct cifs_sb_info *cifs_sb; |
145 | struct cifsTconInfo *pTcon; | 157 | struct cifsTconInfo *tcon; |
146 | char *full_path = NULL; | 158 | char *full_path = NULL; |
147 | FILE_ALL_INFO *buf = NULL; | 159 | FILE_ALL_INFO *buf = NULL; |
148 | struct inode *newinode = NULL; | 160 | struct inode *newinode = NULL; |
149 | struct cifsFileInfo *pCifsFile = NULL; | ||
150 | struct cifsInodeInfo *pCifsInode; | 161 | struct cifsInodeInfo *pCifsInode; |
151 | int disposition = FILE_OVERWRITE_IF; | 162 | int disposition = FILE_OVERWRITE_IF; |
152 | bool write_only = false; | 163 | bool write_only = false; |
@@ -154,7 +165,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
154 | xid = GetXid(); | 165 | xid = GetXid(); |
155 | 166 | ||
156 | cifs_sb = CIFS_SB(inode->i_sb); | 167 | cifs_sb = CIFS_SB(inode->i_sb); |
157 | pTcon = cifs_sb->tcon; | 168 | tcon = cifs_sb->tcon; |
158 | 169 | ||
159 | full_path = build_path_from_dentry(direntry); | 170 | full_path = build_path_from_dentry(direntry); |
160 | if (full_path == NULL) { | 171 | if (full_path == NULL) { |
@@ -162,6 +173,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
162 | return -ENOMEM; | 173 | return -ENOMEM; |
163 | } | 174 | } |
164 | 175 | ||
176 | mode &= ~current->fs->umask; | ||
177 | |||
165 | if (nd && (nd->flags & LOOKUP_OPEN)) { | 178 | if (nd && (nd->flags & LOOKUP_OPEN)) { |
166 | int oflags = nd->intent.open.flags; | 179 | int oflags = nd->intent.open.flags; |
167 | 180 | ||
@@ -196,17 +209,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
196 | return -ENOMEM; | 209 | return -ENOMEM; |
197 | } | 210 | } |
198 | 211 | ||
199 | mode &= ~current->fs->umask; | ||
200 | |||
201 | /* | 212 | /* |
202 | * if we're not using unix extensions, see if we need to set | 213 | * if we're not using unix extensions, see if we need to set |
203 | * ATTR_READONLY on the create call | 214 | * ATTR_READONLY on the create call |
204 | */ | 215 | */ |
205 | if (!pTcon->unix_ext && (mode & S_IWUGO) == 0) | 216 | if (!tcon->unix_ext && (mode & S_IWUGO) == 0) |
206 | create_options |= CREATE_OPTION_READONLY; | 217 | create_options |= CREATE_OPTION_READONLY; |
207 | 218 | ||
208 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) | 219 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) |
209 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 220 | rc = CIFSSMBOpen(xid, tcon, full_path, disposition, |
210 | desiredAccess, create_options, | 221 | desiredAccess, create_options, |
211 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 222 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
212 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 223 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -215,7 +226,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
215 | 226 | ||
216 | if (rc == -EIO) { | 227 | if (rc == -EIO) { |
217 | /* old server, retry the open legacy style */ | 228 | /* old server, retry the open legacy style */ |
218 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, | 229 | rc = SMBLegacyOpen(xid, tcon, full_path, disposition, |
219 | desiredAccess, create_options, | 230 | desiredAccess, create_options, |
220 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 231 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
221 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 232 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -225,7 +236,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
225 | } else { | 236 | } else { |
226 | /* If Open reported that we actually created a file | 237 | /* If Open reported that we actually created a file |
227 | then we now have to set the mode if possible */ | 238 | then we now have to set the mode if possible */ |
228 | if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { | 239 | if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { |
229 | struct cifs_unix_set_info_args args = { | 240 | struct cifs_unix_set_info_args args = { |
230 | .mode = mode, | 241 | .mode = mode, |
231 | .ctime = NO_CHANGE_64, | 242 | .ctime = NO_CHANGE_64, |
@@ -244,20 +255,20 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
244 | args.uid = NO_CHANGE_64; | 255 | args.uid = NO_CHANGE_64; |
245 | args.gid = NO_CHANGE_64; | 256 | args.gid = NO_CHANGE_64; |
246 | } | 257 | } |
247 | CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, | 258 | CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, |
248 | cifs_sb->local_nls, | 259 | cifs_sb->local_nls, |
249 | cifs_sb->mnt_cifs_flags & | 260 | cifs_sb->mnt_cifs_flags & |
250 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 261 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
251 | } else { | 262 | } else { |
252 | /* BB implement mode setting via Windows security | 263 | /* BB implement mode setting via Windows security |
253 | descriptors e.g. */ | 264 | descriptors e.g. */ |
254 | /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/ | 265 | /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ |
255 | 266 | ||
256 | /* Could set r/o dos attribute if mode & 0222 == 0 */ | 267 | /* Could set r/o dos attribute if mode & 0222 == 0 */ |
257 | } | 268 | } |
258 | 269 | ||
259 | /* server might mask mode so we have to query for it */ | 270 | /* server might mask mode so we have to query for it */ |
260 | if (pTcon->unix_ext) | 271 | if (tcon->unix_ext) |
261 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 272 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
262 | inode->i_sb, xid); | 273 | inode->i_sb, xid); |
263 | else { | 274 | else { |
@@ -283,22 +294,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
283 | } | 294 | } |
284 | 295 | ||
285 | if (rc != 0) { | 296 | if (rc != 0) { |
286 | cFYI(1, | 297 | cFYI(1, ("Create worked, get_inode_info failed rc = %d", |
287 | ("Create worked but get_inode_info failed rc = %d", | 298 | rc)); |
288 | rc)); | 299 | } else |
289 | } else { | 300 | setup_cifs_dentry(tcon, direntry, newinode); |
290 | if (pTcon->nocase) | 301 | |
291 | direntry->d_op = &cifs_ci_dentry_ops; | ||
292 | else | ||
293 | direntry->d_op = &cifs_dentry_ops; | ||
294 | d_instantiate(direntry, newinode); | ||
295 | } | ||
296 | if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || | 302 | if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || |
297 | (!(nd->flags & LOOKUP_OPEN))) { | 303 | (!(nd->flags & LOOKUP_OPEN))) { |
298 | /* mknod case - do not leave file open */ | 304 | /* mknod case - do not leave file open */ |
299 | CIFSSMBClose(xid, pTcon, fileHandle); | 305 | CIFSSMBClose(xid, tcon, fileHandle); |
300 | } else if (newinode) { | 306 | } else if (newinode) { |
301 | pCifsFile = | 307 | struct cifsFileInfo *pCifsFile = |
302 | kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); | 308 | kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
303 | 309 | ||
304 | if (pCifsFile == NULL) | 310 | if (pCifsFile == NULL) |
@@ -316,7 +322,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
316 | /* set the following in open now | 322 | /* set the following in open now |
317 | pCifsFile->pfile = file; */ | 323 | pCifsFile->pfile = file; */ |
318 | write_lock(&GlobalSMBSeslock); | 324 | write_lock(&GlobalSMBSeslock); |
319 | list_add(&pCifsFile->tlist, &pTcon->openFileList); | 325 | list_add(&pCifsFile->tlist, &tcon->openFileList); |
320 | pCifsInode = CIFS_I(newinode); | 326 | pCifsInode = CIFS_I(newinode); |
321 | if (pCifsInode) { | 327 | if (pCifsInode) { |
322 | /* if readable file instance put first in list*/ | 328 | /* if readable file instance put first in list*/ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 5ab9896fdcb2..bcf7b5184664 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1285,6 +1285,11 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1285 | cifsInode = CIFS_I(direntry->d_inode); | 1285 | cifsInode = CIFS_I(direntry->d_inode); |
1286 | cifsInode->time = 0; /* force revalidate to go get info when | 1286 | cifsInode->time = 0; /* force revalidate to go get info when |
1287 | needed */ | 1287 | needed */ |
1288 | |||
1289 | cifsInode = CIFS_I(inode); | ||
1290 | cifsInode->time = 0; /* force revalidate to get parent dir info | ||
1291 | since cached search results now invalid */ | ||
1292 | |||
1288 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = | 1293 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = |
1289 | current_fs_time(inode->i_sb); | 1294 | current_fs_time(inode->i_sb); |
1290 | 1295 | ||
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c index 462bbfefd4b6..98b66a54c319 100644 --- a/fs/cifs/md5.c +++ b/fs/cifs/md5.c | |||
@@ -10,8 +10,8 @@ | |||
10 | * with every copy. | 10 | * with every copy. |
11 | * | 11 | * |
12 | * To compute the message digest of a chunk of bytes, declare an | 12 | * To compute the message digest of a chunk of bytes, declare an |
13 | * MD5Context structure, pass it to MD5Init, call MD5Update as | 13 | * MD5Context structure, pass it to cifs_MD5_init, call cifs_MD5_update as |
14 | * needed on buffers full of bytes, and then call MD5Final, which | 14 | * needed on buffers full of bytes, and then call cifs_MD5_final, which |
15 | * will fill a supplied 16-byte array with the digest. | 15 | * will fill a supplied 16-byte array with the digest. |
16 | */ | 16 | */ |
17 | 17 | ||
@@ -45,7 +45,7 @@ byteReverse(unsigned char *buf, unsigned longs) | |||
45 | * initialization constants. | 45 | * initialization constants. |
46 | */ | 46 | */ |
47 | void | 47 | void |
48 | MD5Init(struct MD5Context *ctx) | 48 | cifs_MD5_init(struct MD5Context *ctx) |
49 | { | 49 | { |
50 | ctx->buf[0] = 0x67452301; | 50 | ctx->buf[0] = 0x67452301; |
51 | ctx->buf[1] = 0xefcdab89; | 51 | ctx->buf[1] = 0xefcdab89; |
@@ -61,7 +61,7 @@ MD5Init(struct MD5Context *ctx) | |||
61 | * of bytes. | 61 | * of bytes. |
62 | */ | 62 | */ |
63 | void | 63 | void |
64 | MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) | 64 | cifs_MD5_update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) |
65 | { | 65 | { |
66 | register __u32 t; | 66 | register __u32 t; |
67 | 67 | ||
@@ -110,7 +110,7 @@ MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) | |||
110 | * 1 0* (64-bit count of bits processed, MSB-first) | 110 | * 1 0* (64-bit count of bits processed, MSB-first) |
111 | */ | 111 | */ |
112 | void | 112 | void |
113 | MD5Final(unsigned char digest[16], struct MD5Context *ctx) | 113 | cifs_MD5_final(unsigned char digest[16], struct MD5Context *ctx) |
114 | { | 114 | { |
115 | unsigned int count; | 115 | unsigned int count; |
116 | unsigned char *p; | 116 | unsigned char *p; |
@@ -165,7 +165,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) | |||
165 | 165 | ||
166 | /* | 166 | /* |
167 | * The core of the MD5 algorithm, this alters an existing MD5 hash to | 167 | * The core of the MD5 algorithm, this alters an existing MD5 hash to |
168 | * reflect the addition of 16 longwords of new data. MD5Update blocks | 168 | * reflect the addition of 16 longwords of new data. cifs_MD5_update blocks |
169 | * the data and converts bytes into longwords for this routine. | 169 | * the data and converts bytes into longwords for this routine. |
170 | */ | 170 | */ |
171 | static void | 171 | static void |
@@ -267,9 +267,9 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len, | |||
267 | unsigned char tk[16]; | 267 | unsigned char tk[16]; |
268 | struct MD5Context tctx; | 268 | struct MD5Context tctx; |
269 | 269 | ||
270 | MD5Init(&tctx); | 270 | cifs_MD5_init(&tctx); |
271 | MD5Update(&tctx, key, key_len); | 271 | cifs_MD5_update(&tctx, key, key_len); |
272 | MD5Final(tk, &tctx); | 272 | cifs_MD5_final(tk, &tctx); |
273 | 273 | ||
274 | key = tk; | 274 | key = tk; |
275 | key_len = 16; | 275 | key_len = 16; |
@@ -287,8 +287,8 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len, | |||
287 | ctx->k_opad[i] ^= 0x5c; | 287 | ctx->k_opad[i] ^= 0x5c; |
288 | } | 288 | } |
289 | 289 | ||
290 | MD5Init(&ctx->ctx); | 290 | cifs_MD5_init(&ctx->ctx); |
291 | MD5Update(&ctx->ctx, ctx->k_ipad, 64); | 291 | cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64); |
292 | } | 292 | } |
293 | #endif | 293 | #endif |
294 | 294 | ||
@@ -317,8 +317,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, | |||
317 | ctx->k_opad[i] ^= 0x5c; | 317 | ctx->k_opad[i] ^= 0x5c; |
318 | } | 318 | } |
319 | 319 | ||
320 | MD5Init(&ctx->ctx); | 320 | cifs_MD5_init(&ctx->ctx); |
321 | MD5Update(&ctx->ctx, ctx->k_ipad, 64); | 321 | cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64); |
322 | } | 322 | } |
323 | 323 | ||
324 | /*********************************************************************** | 324 | /*********************************************************************** |
@@ -328,7 +328,7 @@ void | |||
328 | hmac_md5_update(const unsigned char *text, int text_len, | 328 | hmac_md5_update(const unsigned char *text, int text_len, |
329 | struct HMACMD5Context *ctx) | 329 | struct HMACMD5Context *ctx) |
330 | { | 330 | { |
331 | MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */ | 331 | cifs_MD5_update(&ctx->ctx, text, text_len); /* then text of datagram */ |
332 | } | 332 | } |
333 | 333 | ||
334 | /*********************************************************************** | 334 | /*********************************************************************** |
@@ -339,12 +339,12 @@ hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx) | |||
339 | { | 339 | { |
340 | struct MD5Context ctx_o; | 340 | struct MD5Context ctx_o; |
341 | 341 | ||
342 | MD5Final(digest, &ctx->ctx); | 342 | cifs_MD5_final(digest, &ctx->ctx); |
343 | 343 | ||
344 | MD5Init(&ctx_o); | 344 | cifs_MD5_init(&ctx_o); |
345 | MD5Update(&ctx_o, ctx->k_opad, 64); | 345 | cifs_MD5_update(&ctx_o, ctx->k_opad, 64); |
346 | MD5Update(&ctx_o, digest, 16); | 346 | cifs_MD5_update(&ctx_o, digest, 16); |
347 | MD5Final(digest, &ctx_o); | 347 | cifs_MD5_final(digest, &ctx_o); |
348 | } | 348 | } |
349 | 349 | ||
350 | /*********************************************************** | 350 | /*********************************************************** |
diff --git a/fs/cifs/md5.h b/fs/cifs/md5.h index f7d4f4197bac..6fba8cb402fd 100644 --- a/fs/cifs/md5.h +++ b/fs/cifs/md5.h | |||
@@ -20,10 +20,10 @@ struct HMACMD5Context { | |||
20 | }; | 20 | }; |
21 | #endif /* _HMAC_MD5_H */ | 21 | #endif /* _HMAC_MD5_H */ |
22 | 22 | ||
23 | void MD5Init(struct MD5Context *context); | 23 | void cifs_MD5_init(struct MD5Context *context); |
24 | void MD5Update(struct MD5Context *context, unsigned char const *buf, | 24 | void cifs_MD5_update(struct MD5Context *context, unsigned char const *buf, |
25 | unsigned len); | 25 | unsigned len); |
26 | void MD5Final(unsigned char digest[16], struct MD5Context *context); | 26 | void cifs_MD5_final(unsigned char digest[16], struct MD5Context *context); |
27 | 27 | ||
28 | /* The following definitions come from lib/hmacmd5.c */ | 28 | /* The following definitions come from lib/hmacmd5.c */ |
29 | 29 | ||
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 7ebe6599ed3a..0ad3e2d116a6 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -154,81 +154,8 @@ void DeleteTconOplockQEntries(struct cifsTconInfo *tcon) | |||
154 | spin_unlock(&GlobalMid_Lock); | 154 | spin_unlock(&GlobalMid_Lock); |
155 | } | 155 | } |
156 | 156 | ||
157 | int | ||
158 | smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, | ||
159 | unsigned int smb_buf_length, struct sockaddr *sin, bool noblocksnd) | ||
160 | { | ||
161 | int rc = 0; | ||
162 | int i = 0; | ||
163 | struct msghdr smb_msg; | ||
164 | struct kvec iov; | ||
165 | unsigned len = smb_buf_length + 4; | ||
166 | |||
167 | if (ssocket == NULL) | ||
168 | return -ENOTSOCK; /* BB eventually add reconnect code here */ | ||
169 | iov.iov_base = smb_buffer; | ||
170 | iov.iov_len = len; | ||
171 | |||
172 | smb_msg.msg_name = sin; | ||
173 | smb_msg.msg_namelen = sizeof(struct sockaddr); | ||
174 | smb_msg.msg_control = NULL; | ||
175 | smb_msg.msg_controllen = 0; | ||
176 | if (noblocksnd) | ||
177 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; | ||
178 | else | ||
179 | smb_msg.msg_flags = MSG_NOSIGNAL; | ||
180 | |||
181 | /* smb header is converted in header_assemble. bcc and rest of SMB word | ||
182 | area, and byte area if necessary, is converted to littleendian in | ||
183 | cifssmb.c and RFC1001 len is converted to bigendian in smb_send | ||
184 | Flags2 is converted in SendReceive */ | ||
185 | |||
186 | smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); | ||
187 | cFYI(1, ("Sending smb of length %d", smb_buf_length)); | ||
188 | dump_smb(smb_buffer, len); | ||
189 | |||
190 | while (len > 0) { | ||
191 | rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); | ||
192 | if ((rc == -ENOSPC) || (rc == -EAGAIN)) { | ||
193 | i++; | ||
194 | /* smaller timeout here than send2 since smaller size */ | ||
195 | /* Although it may not be required, this also is smaller | ||
196 | oplock break time */ | ||
197 | if (i > 12) { | ||
198 | cERROR(1, | ||
199 | ("sends on sock %p stuck for 7 seconds", | ||
200 | ssocket)); | ||
201 | rc = -EAGAIN; | ||
202 | break; | ||
203 | } | ||
204 | msleep(1 << i); | ||
205 | continue; | ||
206 | } | ||
207 | if (rc < 0) | ||
208 | break; | ||
209 | else | ||
210 | i = 0; /* reset i after each successful send */ | ||
211 | iov.iov_base += rc; | ||
212 | iov.iov_len -= rc; | ||
213 | len -= rc; | ||
214 | } | ||
215 | |||
216 | if (rc < 0) { | ||
217 | cERROR(1, ("Error %d sending data on socket to server", rc)); | ||
218 | } else { | ||
219 | rc = 0; | ||
220 | } | ||
221 | |||
222 | /* Don't want to modify the buffer as a | ||
223 | side effect of this call. */ | ||
224 | smb_buffer->smb_buf_length = smb_buf_length; | ||
225 | |||
226 | return rc; | ||
227 | } | ||
228 | |||
229 | static int | 157 | static int |
230 | smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec, | 158 | smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) |
231 | struct sockaddr *sin, bool noblocksnd) | ||
232 | { | 159 | { |
233 | int rc = 0; | 160 | int rc = 0; |
234 | int i = 0; | 161 | int i = 0; |
@@ -243,11 +170,11 @@ smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec, | |||
243 | if (ssocket == NULL) | 170 | if (ssocket == NULL) |
244 | return -ENOTSOCK; /* BB eventually add reconnect code here */ | 171 | return -ENOTSOCK; /* BB eventually add reconnect code here */ |
245 | 172 | ||
246 | smb_msg.msg_name = sin; | 173 | smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr; |
247 | smb_msg.msg_namelen = sizeof(struct sockaddr); | 174 | smb_msg.msg_namelen = sizeof(struct sockaddr); |
248 | smb_msg.msg_control = NULL; | 175 | smb_msg.msg_control = NULL; |
249 | smb_msg.msg_controllen = 0; | 176 | smb_msg.msg_controllen = 0; |
250 | if (noblocksnd) | 177 | if (server->noblocksnd) |
251 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; | 178 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; |
252 | else | 179 | else |
253 | smb_msg.msg_flags = MSG_NOSIGNAL; | 180 | smb_msg.msg_flags = MSG_NOSIGNAL; |
@@ -272,7 +199,25 @@ smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec, | |||
272 | n_vec - first_vec, total_len); | 199 | n_vec - first_vec, total_len); |
273 | if ((rc == -ENOSPC) || (rc == -EAGAIN)) { | 200 | if ((rc == -ENOSPC) || (rc == -EAGAIN)) { |
274 | i++; | 201 | i++; |
275 | if (i >= 14) { | 202 | /* if blocking send we try 3 times, since each can block |
203 | for 5 seconds. For nonblocking we have to try more | ||
204 | but wait increasing amounts of time allowing time for | ||
205 | socket to clear. The overall time we wait in either | ||
206 | case to send on the socket is about 15 seconds. | ||
207 | Similarly we wait for 15 seconds for | ||
208 | a response from the server in SendReceive[2] | ||
209 | for the server to send a response back for | ||
210 | most types of requests (except SMB Write | ||
211 | past end of file which can be slow, and | ||
212 | blocking lock operations). NFS waits slightly longer | ||
213 | than CIFS, but this can make it take longer for | ||
214 | nonresponsive servers to be detected and 15 seconds | ||
215 | is more than enough time for modern networks to | ||
216 | send a packet. In most cases if we fail to send | ||
217 | after the retries we will kill the socket and | ||
218 | reconnect which may clear the network problem. | ||
219 | */ | ||
220 | if ((i >= 14) || (!server->noblocksnd && (i > 2))) { | ||
276 | cERROR(1, | 221 | cERROR(1, |
277 | ("sends on sock %p stuck for 15 seconds", | 222 | ("sends on sock %p stuck for 15 seconds", |
278 | ssocket)); | 223 | ssocket)); |
@@ -339,6 +284,18 @@ smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec, | |||
339 | return rc; | 284 | return rc; |
340 | } | 285 | } |
341 | 286 | ||
287 | int | ||
288 | smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, | ||
289 | unsigned int smb_buf_length) | ||
290 | { | ||
291 | struct kvec iov; | ||
292 | |||
293 | iov.iov_base = smb_buffer; | ||
294 | iov.iov_len = smb_buf_length + 4; | ||
295 | |||
296 | return smb_sendv(server, &iov, 1); | ||
297 | } | ||
298 | |||
342 | static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) | 299 | static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) |
343 | { | 300 | { |
344 | if (long_op == CIFS_ASYNC_OP) { | 301 | if (long_op == CIFS_ASYNC_OP) { |
@@ -540,9 +497,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
540 | #ifdef CONFIG_CIFS_STATS2 | 497 | #ifdef CONFIG_CIFS_STATS2 |
541 | atomic_inc(&ses->server->inSend); | 498 | atomic_inc(&ses->server->inSend); |
542 | #endif | 499 | #endif |
543 | rc = smb_send2(ses->server, iov, n_vec, | 500 | rc = smb_sendv(ses->server, iov, n_vec); |
544 | (struct sockaddr *) &(ses->server->addr.sockAddr), | ||
545 | ses->server->noblocksnd); | ||
546 | #ifdef CONFIG_CIFS_STATS2 | 501 | #ifdef CONFIG_CIFS_STATS2 |
547 | atomic_dec(&ses->server->inSend); | 502 | atomic_dec(&ses->server->inSend); |
548 | midQ->when_sent = jiffies; | 503 | midQ->when_sent = jiffies; |
@@ -736,9 +691,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
736 | #ifdef CONFIG_CIFS_STATS2 | 691 | #ifdef CONFIG_CIFS_STATS2 |
737 | atomic_inc(&ses->server->inSend); | 692 | atomic_inc(&ses->server->inSend); |
738 | #endif | 693 | #endif |
739 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, | 694 | rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length); |
740 | (struct sockaddr *) &(ses->server->addr.sockAddr), | ||
741 | ses->server->noblocksnd); | ||
742 | #ifdef CONFIG_CIFS_STATS2 | 695 | #ifdef CONFIG_CIFS_STATS2 |
743 | atomic_dec(&ses->server->inSend); | 696 | atomic_dec(&ses->server->inSend); |
744 | midQ->when_sent = jiffies; | 697 | midQ->when_sent = jiffies; |
@@ -879,9 +832,7 @@ send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf, | |||
879 | mutex_unlock(&ses->server->srv_mutex); | 832 | mutex_unlock(&ses->server->srv_mutex); |
880 | return rc; | 833 | return rc; |
881 | } | 834 | } |
882 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, | 835 | rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length); |
883 | (struct sockaddr *) &(ses->server->addr.sockAddr), | ||
884 | ses->server->noblocksnd); | ||
885 | mutex_unlock(&ses->server->srv_mutex); | 836 | mutex_unlock(&ses->server->srv_mutex); |
886 | return rc; | 837 | return rc; |
887 | } | 838 | } |
@@ -973,9 +924,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
973 | #ifdef CONFIG_CIFS_STATS2 | 924 | #ifdef CONFIG_CIFS_STATS2 |
974 | atomic_inc(&ses->server->inSend); | 925 | atomic_inc(&ses->server->inSend); |
975 | #endif | 926 | #endif |
976 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, | 927 | rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length); |
977 | (struct sockaddr *) &(ses->server->addr.sockAddr), | ||
978 | ses->server->noblocksnd); | ||
979 | #ifdef CONFIG_CIFS_STATS2 | 928 | #ifdef CONFIG_CIFS_STATS2 |
980 | atomic_dec(&ses->server->inSend); | 929 | atomic_dec(&ses->server->inSend); |
981 | midQ->when_sent = jiffies; | 930 | midQ->when_sent = jiffies; |