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: when renaming don't try to unlink negative dentry
cifs: remove unneeded bcc_ptr update in CIFSTCon
cifs: add cFYI messages with some of the saved strings from ssetup/tcon
cifs: fix buffer size for tcon->nativeFileSystem field
cifs: fix unicode string area word alignment in session setup
[CIFS] Fix build break caused by change to new current_umask helper function
[CIFS] Fix sparse warnings
[CIFS] Add support for posix open during lookup
cifs: no need to use rcu_assign_pointer on immutable keys
cifs: remove dnotify thread code
[CIFS] remove some build warnings
cifs: vary timeout on writes past EOF based on offset (try #5)
[CIFS] Fix build break from recent DFS patch when DFS support not enabled
Remote DFS root support.
[CIFS] Endian convert UniqueId when reporting inode numbers from server files
cifs: remove some pointless conditionals before kfree()
cifs: flush data on any setattr

+405 -270
+2 -1
fs/cifs/CHANGES
··· 15 fails to support it properly, as with Samba server versions prior to 3.3.2) 16 Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too 17 little memory for the "nativeFileSystem" field returned by the server 18 - during mount). 19 20 Version 1.56 21 ------------
··· 15 fails to support it properly, as with Samba server versions prior to 3.3.2) 16 Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too 17 little memory for the "nativeFileSystem" field returned by the server 18 + during mount). Endian convert inode numbers if necessary (makes it easier 19 + to compare inode numbers on network files from big endian systems). 20 21 Version 1.56 22 ------------
+1 -1
fs/cifs/cifs_spnego.c
··· 41 42 /* attach the data */ 43 memcpy(payload, data, datalen); 44 - rcu_assign_pointer(key->payload.data, payload); 45 ret = 0; 46 47 error:
··· 41 42 /* attach the data */ 43 memcpy(payload, data, datalen); 44 + key->payload.data = payload; 45 ret = 0; 46 47 error:
+1 -47
fs/cifs/cifsfs.c
··· 66 extern struct task_struct *oplockThread; /* remove sparse warning */ 67 struct task_struct *oplockThread = NULL; 68 /* extern struct task_struct * dnotifyThread; remove sparse warning */ 69 - #ifdef CONFIG_CIFS_EXPERIMENTAL 70 - static struct task_struct *dnotifyThread = NULL; 71 - #endif 72 static const struct super_operations cifs_super_ops; 73 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 74 module_param(CIFSMaxBufSize, int, 0); ··· 313 cifs_inode->clientCanCacheAll = false; 314 cifs_inode->delete_pending = false; 315 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 316 317 /* Can not set i_flags here - they get immediately overwritten 318 to zero by the VFS */ ··· 1038 return 0; 1039 } 1040 1041 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1042 - static int cifs_dnotify_thread(void *dummyarg) 1043 - { 1044 - struct list_head *tmp; 1045 - struct TCP_Server_Info *server; 1046 - 1047 - do { 1048 - if (try_to_freeze()) 1049 - continue; 1050 - set_current_state(TASK_INTERRUPTIBLE); 1051 - schedule_timeout(15*HZ); 1052 - /* check if any stuck requests that need 1053 - to be woken up and wakeq so the 1054 - thread can wake up and error out */ 1055 - read_lock(&cifs_tcp_ses_lock); 1056 - list_for_each(tmp, &cifs_tcp_ses_list) { 1057 - server = list_entry(tmp, struct TCP_Server_Info, 1058 - tcp_ses_list); 1059 - if (atomic_read(&server->inFlight)) 1060 - wake_up_all(&server->response_q); 1061 - } 1062 - read_unlock(&cifs_tcp_ses_lock); 1063 - } while (!kthread_should_stop()); 1064 - 1065 - return 0; 1066 - } 1067 - #endif 1068 - 1069 static int __init 1070 init_cifs(void) 1071 { ··· 1114 goto out_unregister_dfs_key_type; 1115 } 1116 1117 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1118 - dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); 1119 - if (IS_ERR(dnotifyThread)) { 1120 - rc = PTR_ERR(dnotifyThread); 1121 - cERROR(1, ("error %d create dnotify thread", rc)); 1122 - goto out_stop_oplock_thread; 1123 - } 1124 - #endif 1125 - 1126 return 0; 1127 1128 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1129 - out_stop_oplock_thread: 1130 - #endif 1131 - kthread_stop(oplockThread); 1132 out_unregister_dfs_key_type: 1133 #ifdef CONFIG_CIFS_DFS_UPCALL 1134 unregister_key_type(&key_type_dns_resolver); ··· 1153 cifs_destroy_inodecache(); 1154 cifs_destroy_mids(); 1155 cifs_destroy_request_bufs(); 1156 - #ifdef CONFIG_CIFS_EXPERIMENTAL 1157 - kthread_stop(dnotifyThread); 1158 - #endif 1159 kthread_stop(oplockThread); 1160 } 1161
··· 66 extern struct task_struct *oplockThread; /* remove sparse warning */ 67 struct task_struct *oplockThread = NULL; 68 /* extern struct task_struct * dnotifyThread; remove sparse warning */ 69 static const struct super_operations cifs_super_ops; 70 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 71 module_param(CIFSMaxBufSize, int, 0); ··· 316 cifs_inode->clientCanCacheAll = false; 317 cifs_inode->delete_pending = false; 318 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 319 + cifs_inode->server_eof = 0; 320 321 /* Can not set i_flags here - they get immediately overwritten 322 to zero by the VFS */ ··· 1040 return 0; 1041 } 1042 1043 static int __init 1044 init_cifs(void) 1045 { ··· 1144 goto out_unregister_dfs_key_type; 1145 } 1146 1147 return 0; 1148 1149 out_unregister_dfs_key_type: 1150 #ifdef CONFIG_CIFS_DFS_UPCALL 1151 unregister_key_type(&key_type_dns_resolver); ··· 1196 cifs_destroy_inodecache(); 1197 cifs_destroy_mids(); 1198 cifs_destroy_request_bufs(); 1199 kthread_stop(oplockThread); 1200 } 1201
+2 -1
fs/cifs/cifsglob.h
··· 350 bool invalidHandle:1; /* file closed via session abend */ 351 bool messageMode:1; /* for pipes: message vs byte mode */ 352 atomic_t wrtPending; /* handle in use - defer close */ 353 - struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 354 struct cifs_search_info srch_inf; 355 }; 356 ··· 370 bool clientCanCacheAll:1; /* read and writebehind oplock */ 371 bool oplockPending:1; 372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 373 struct inode vfs_inode; 374 }; 375
··· 350 bool invalidHandle:1; /* file closed via session abend */ 351 bool messageMode:1; /* for pipes: message vs byte mode */ 352 atomic_t wrtPending; /* handle in use - defer close */ 353 + struct mutex fh_mutex; /* prevents reopen race after dead ses*/ 354 struct cifs_search_info srch_inf; 355 }; 356 ··· 370 bool clientCanCacheAll:1; /* read and writebehind oplock */ 371 bool oplockPending:1; 372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 373 + u64 server_eof; /* current file size on server */ 374 struct inode vfs_inode; 375 }; 376
+4 -4
fs/cifs/cifspdu.h
··· 2163 __le32 Type; 2164 __le64 DevMajor; 2165 __le64 DevMinor; 2166 - __u64 UniqueId; 2167 __le64 Permissions; 2168 __le64 Nlinks; 2169 } __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */ ··· 2308 } __attribute__((packed)); 2309 2310 struct file_internal_info { 2311 - __u64 UniqueId; /* inode number */ 2312 } __attribute__((packed)); /* level 0x3ee */ 2313 2314 struct file_mode_info { ··· 2338 __le32 Type; 2339 __le64 DevMajor; 2340 __le64 DevMinor; 2341 - __u64 UniqueId; 2342 __le64 Permissions; 2343 __le64 Nlinks; 2344 char FileName[1]; ··· 2386 __le32 FileNameLength; 2387 __le32 EaSize; /* EA size */ 2388 __le32 Reserved; 2389 - __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2390 char FileName[1]; 2391 } __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */ 2392
··· 2163 __le32 Type; 2164 __le64 DevMajor; 2165 __le64 DevMinor; 2166 + __le64 UniqueId; 2167 __le64 Permissions; 2168 __le64 Nlinks; 2169 } __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */ ··· 2308 } __attribute__((packed)); 2309 2310 struct file_internal_info { 2311 + __le64 UniqueId; /* inode number */ 2312 } __attribute__((packed)); /* level 0x3ee */ 2313 2314 struct file_mode_info { ··· 2338 __le32 Type; 2339 __le64 DevMajor; 2340 __le64 DevMinor; 2341 + __le64 UniqueId; 2342 __le64 Permissions; 2343 __le64 Nlinks; 2344 char FileName[1]; ··· 2386 __le32 FileNameLength; 2387 __le32 EaSize; /* EA size */ 2388 __le32 Reserved; 2389 + __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2390 char FileName[1]; 2391 } __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */ 2392
+3 -3
fs/cifs/cifssmb.c
··· 1626 int smb_hdr_len; 1627 int resp_buf_type = 0; 1628 1629 cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count)); 1630 1631 if (tcon->ses->capabilities & CAP_LARGE_FILES) { ··· 1684 cifs_stats_inc(&tcon->num_writes); 1685 if (rc) { 1686 cFYI(1, ("Send error Write2 = %d", rc)); 1687 - *nbytes = 0; 1688 } else if (resp_buf_type == 0) { 1689 /* presumably this can not happen, but best to be safe */ 1690 rc = -EIO; 1691 - *nbytes = 0; 1692 } else { 1693 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base; 1694 *nbytes = le16_to_cpu(pSMBr->CountHigh); ··· 3918 } 3919 pfinfo = (struct file_internal_info *) 3920 (data_offset + (char *) &pSMBr->hdr.Protocol); 3921 - *inode_number = pfinfo->UniqueId; 3922 } 3923 } 3924 GetInodeNumOut:
··· 1626 int smb_hdr_len; 1627 int resp_buf_type = 0; 1628 1629 + *nbytes = 0; 1630 + 1631 cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count)); 1632 1633 if (tcon->ses->capabilities & CAP_LARGE_FILES) { ··· 1682 cifs_stats_inc(&tcon->num_writes); 1683 if (rc) { 1684 cFYI(1, ("Send error Write2 = %d", rc)); 1685 } else if (resp_buf_type == 0) { 1686 /* presumably this can not happen, but best to be safe */ 1687 rc = -EIO; 1688 } else { 1689 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base; 1690 *nbytes = le16_to_cpu(pSMBr->CountHigh); ··· 3918 } 3919 pfinfo = (struct file_internal_info *) 3920 (data_offset + (char *) &pSMBr->hdr.Protocol); 3921 + *inode_number = le64_to_cpu(pfinfo->UniqueId); 3922 } 3923 } 3924 GetInodeNumOut:
+143 -62
fs/cifs/connect.c
··· 2214 return rc; 2215 } 2216 2217 int 2218 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2219 - char *mount_data, const char *devname) 2220 { 2221 int rc = 0; 2222 int xid; ··· 2274 struct cifsTconInfo *tcon = NULL; 2275 struct TCP_Server_Info *srvTcp = NULL; 2276 char *full_path; 2277 2278 xid = GetXid(); 2279 ··· 2427 } 2428 } 2429 2430 - /* check for null share name ie connect to dfs root */ 2431 if ((strchr(volume_info->UNC + 3, '\\') == NULL) 2432 && (strchr(volume_info->UNC + 3, '/') == NULL)) { 2433 - /* rc = connect_to_dfs_path(...) */ 2434 - cFYI(1, ("DFS root not supported")); 2435 rc = -ENODEV; 2436 goto mount_fail_check; 2437 } else { ··· 2446 } 2447 } 2448 if (rc) 2449 - goto mount_fail_check; 2450 tcon->seal = volume_info->seal; 2451 write_lock(&cifs_tcp_ses_lock); 2452 list_add(&tcon->tcon_list, &pSesInfo->tcon_list); ··· 2471 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 2472 sb->s_time_gran = 100; 2473 2474 - mount_fail_check: 2475 - /* on error free sesinfo and tcon struct if needed */ 2476 - if (rc) { 2477 - /* If find_unc succeeded then rc == 0 so we can not end */ 2478 - /* up accidently freeing someone elses tcon struct */ 2479 - if (tcon) 2480 - cifs_put_tcon(tcon); 2481 - else if (pSesInfo) 2482 - cifs_put_smb_ses(pSesInfo); 2483 - else 2484 - cifs_put_tcp_session(srvTcp); 2485 - goto out; 2486 - } 2487 cifs_sb->tcon = tcon; 2488 2489 /* do not care if following two calls succeed - informational */ ··· 2505 cifs_sb->rsize = min(cifs_sb->rsize, 2506 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 2507 2508 - if (!rc && cifs_sb->prepathlen) { 2509 /* build_path_to_root works only when we have a valid tcon */ 2510 full_path = cifs_build_path_to_root(cifs_sb); 2511 if (full_path == NULL) { ··· 2515 goto mount_fail_check; 2516 } 2517 rc = is_path_accessible(xid, tcon, cifs_sb, full_path); 2518 - if (rc) { 2519 - cERROR(1, ("Path %s in not accessible: %d", 2520 - full_path, rc)); 2521 kfree(full_path); 2522 goto mount_fail_check; 2523 } 2524 kfree(full_path); 2525 } 2526 2527 /* volume_info->password is freed above when existing session found ··· 2587 password will be freed at unmount time) */ 2588 out: 2589 /* zero out password before freeing */ 2590 - if (volume_info) { 2591 - if (volume_info->password != NULL) { 2592 - memset(volume_info->password, 0, 2593 - strlen(volume_info->password)); 2594 - kfree(volume_info->password); 2595 - } 2596 - kfree(volume_info->UNC); 2597 - kfree(volume_info->prepath); 2598 - kfree(volume_info); 2599 - } 2600 FreeXid(xid); 2601 return rc; 2602 } ··· 2767 /* We look for obvious messed up bcc or strings in response so we do not go off 2768 the end since (at least) WIN2K and Windows XP have a major bug in not null 2769 terminating last Unicode string in response */ 2770 - if (ses->serverOS) 2771 - kfree(ses->serverOS); 2772 ses->serverOS = kzalloc(2 * (len + 1), 2773 GFP_KERNEL); 2774 if (ses->serverOS == NULL) ··· 2803 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2804 /* last string is not always null terminated 2805 (for e.g. for Windows XP & 2000) */ 2806 - if (ses->serverDomain) 2807 - kfree(ses->serverDomain); 2808 ses->serverDomain = 2809 kzalloc(2*(len+1), 2810 GFP_KERNEL); ··· 2817 ses->serverDomain[1+(2*len)] = 0; 2818 } else { /* else no more room so create 2819 dummy domain string */ 2820 - if (ses->serverDomain) 2821 - kfree(ses->serverDomain); 2822 ses->serverDomain = 2823 kzalloc(2, GFP_KERNEL); 2824 } ··· 2863 bcc_ptr++; 2864 2865 len = strnlen(bcc_ptr, 1024); 2866 - if (ses->serverDomain) 2867 - kfree(ses->serverDomain); 2868 ses->serverDomain = kzalloc(len + 1, 2869 GFP_KERNEL); 2870 if (ses->serverDomain == NULL) ··· 3103 /* We look for obvious messed up bcc or strings in response so we do not go off 3104 the end since (at least) WIN2K and Windows XP have a major bug in not null 3105 terminating last Unicode string in response */ 3106 - if (ses->serverOS) 3107 - kfree(ses->serverOS); 3108 ses->serverOS = 3109 kzalloc(2 * (len + 1), GFP_KERNEL); 3110 cifs_strfromUCS_le(ses->serverOS, ··· 3175 if (((long) bcc_ptr + len) - (long) 3176 pByteArea(smb_buffer_response) 3177 <= BCC(smb_buffer_response)) { 3178 - if (ses->serverOS) 3179 - kfree(ses->serverOS); 3180 ses->serverOS = 3181 kzalloc(len + 1, 3182 GFP_KERNEL); ··· 3502 /* We look for obvious messed up bcc or strings in response so we do not go off 3503 the end since (at least) WIN2K and Windows XP have a major bug in not null 3504 terminating last Unicode string in response */ 3505 - if (ses->serverOS) 3506 - kfree(ses->serverOS); 3507 ses->serverOS = 3508 kzalloc(2 * (len + 1), GFP_KERNEL); 3509 cifs_strfromUCS_le(ses->serverOS, ··· 3535 if (remaining_words > 0) { 3536 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 3537 /* last string not always null terminated (e.g. for Windows XP & 2000) */ 3538 - if (ses->serverDomain) 3539 - kfree(ses->serverDomain); 3540 ses->serverDomain = 3541 kzalloc(2 * 3542 (len + ··· 3562 = 0; 3563 } /* else no more room so create dummy domain string */ 3564 else { 3565 - if (ses->serverDomain) 3566 - kfree(ses->serverDomain); 3567 ses->serverDomain = kzalloc(2,GFP_KERNEL); 3568 } 3569 } else { /* no room so create dummy domain and NOS string */ 3570 - if (ses->serverDomain) 3571 - kfree(ses->serverDomain); 3572 ses->serverDomain = kzalloc(2, GFP_KERNEL); 3573 kfree(ses->serverNOS); 3574 ses->serverNOS = kzalloc(2, GFP_KERNEL); ··· 3576 if (((long) bcc_ptr + len) - 3577 (long) pByteArea(smb_buffer_response) 3578 <= BCC(smb_buffer_response)) { 3579 - if (ses->serverOS) 3580 - kfree(ses->serverOS); 3581 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 3582 strncpy(ses->serverOS,bcc_ptr, len); 3583 ··· 3595 bcc_ptr++; 3596 3597 len = strnlen(bcc_ptr, 1024); 3598 - if (ses->serverDomain) 3599 - kfree(ses->serverDomain); 3600 ses->serverDomain = 3601 kzalloc(len+1, 3602 GFP_KERNEL); ··· 3756 BCC(smb_buffer_response)) { 3757 kfree(tcon->nativeFileSystem); 3758 tcon->nativeFileSystem = 3759 - kzalloc(2*(length + 1), GFP_KERNEL); 3760 - if (tcon->nativeFileSystem) 3761 cifs_strfromUCS_le( 3762 tcon->nativeFileSystem, 3763 (__le16 *) bcc_ptr, 3764 length, nls_codepage); 3765 - bcc_ptr += 2 * length; 3766 - bcc_ptr[0] = 0; /* null terminate the string */ 3767 - bcc_ptr[1] = 0; 3768 - bcc_ptr += 2; 3769 } 3770 /* else do not bother copying these information fields*/ 3771 } else {
··· 2214 return rc; 2215 } 2216 2217 + static void 2218 + cleanup_volume_info(struct smb_vol **pvolume_info) 2219 + { 2220 + struct smb_vol *volume_info; 2221 + 2222 + if (!pvolume_info && !*pvolume_info) 2223 + return; 2224 + 2225 + volume_info = *pvolume_info; 2226 + kzfree(volume_info->password); 2227 + kfree(volume_info->UNC); 2228 + kfree(volume_info->prepath); 2229 + kfree(volume_info); 2230 + *pvolume_info = NULL; 2231 + return; 2232 + } 2233 + 2234 + #ifdef CONFIG_CIFS_DFS_UPCALL 2235 + /* build_path_to_root returns full path to root when 2236 + * we do not have an exiting connection (tcon) */ 2237 + static char * 2238 + build_unc_path_to_root(const struct smb_vol *volume_info, 2239 + const struct cifs_sb_info *cifs_sb) 2240 + { 2241 + char *full_path; 2242 + 2243 + int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); 2244 + full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL); 2245 + if (full_path == NULL) 2246 + return ERR_PTR(-ENOMEM); 2247 + 2248 + strncpy(full_path, volume_info->UNC, unc_len); 2249 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { 2250 + int i; 2251 + for (i = 0; i < unc_len; i++) { 2252 + if (full_path[i] == '\\') 2253 + full_path[i] = '/'; 2254 + } 2255 + } 2256 + 2257 + if (cifs_sb->prepathlen) 2258 + strncpy(full_path + unc_len, cifs_sb->prepath, 2259 + cifs_sb->prepathlen); 2260 + 2261 + full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */ 2262 + return full_path; 2263 + } 2264 + #endif 2265 + 2266 int 2267 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2268 + char *mount_data_global, const char *devname) 2269 { 2270 int rc = 0; 2271 int xid; ··· 2225 struct cifsTconInfo *tcon = NULL; 2226 struct TCP_Server_Info *srvTcp = NULL; 2227 char *full_path; 2228 + char *mount_data = mount_data_global; 2229 + #ifdef CONFIG_CIFS_DFS_UPCALL 2230 + struct dfs_info3_param *referrals = NULL; 2231 + unsigned int num_referrals = 0; 2232 + try_mount_again: 2233 + #endif 2234 + full_path = NULL; 2235 2236 xid = GetXid(); 2237 ··· 2371 } 2372 } 2373 2374 if ((strchr(volume_info->UNC + 3, '\\') == NULL) 2375 && (strchr(volume_info->UNC + 3, '/') == NULL)) { 2376 + cERROR(1, ("Missing share name")); 2377 rc = -ENODEV; 2378 goto mount_fail_check; 2379 } else { ··· 2392 } 2393 } 2394 if (rc) 2395 + goto remote_path_check; 2396 tcon->seal = volume_info->seal; 2397 write_lock(&cifs_tcp_ses_lock); 2398 list_add(&tcon->tcon_list, &pSesInfo->tcon_list); ··· 2417 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 2418 sb->s_time_gran = 100; 2419 2420 + if (rc) 2421 + goto remote_path_check; 2422 + 2423 cifs_sb->tcon = tcon; 2424 2425 /* do not care if following two calls succeed - informational */ ··· 2461 cifs_sb->rsize = min(cifs_sb->rsize, 2462 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 2463 2464 + remote_path_check: 2465 + /* check if a whole path (including prepath) is not remote */ 2466 + if (!rc && cifs_sb->prepathlen && tcon) { 2467 /* build_path_to_root works only when we have a valid tcon */ 2468 full_path = cifs_build_path_to_root(cifs_sb); 2469 if (full_path == NULL) { ··· 2469 goto mount_fail_check; 2470 } 2471 rc = is_path_accessible(xid, tcon, cifs_sb, full_path); 2472 + if (rc != -EREMOTE) { 2473 kfree(full_path); 2474 goto mount_fail_check; 2475 } 2476 kfree(full_path); 2477 + } 2478 + 2479 + /* get referral if needed */ 2480 + if (rc == -EREMOTE) { 2481 + #ifdef CONFIG_CIFS_DFS_UPCALL 2482 + /* convert forward to back slashes in prepath here if needed */ 2483 + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) 2484 + convert_delimiter(cifs_sb->prepath, 2485 + CIFS_DIR_SEP(cifs_sb)); 2486 + full_path = build_unc_path_to_root(volume_info, cifs_sb); 2487 + if (IS_ERR(full_path)) { 2488 + rc = PTR_ERR(full_path); 2489 + goto mount_fail_check; 2490 + } 2491 + 2492 + cFYI(1, ("Getting referral for: %s", full_path)); 2493 + rc = get_dfs_path(xid, pSesInfo , full_path + 1, 2494 + cifs_sb->local_nls, &num_referrals, &referrals, 2495 + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 2496 + if (!rc && num_referrals > 0) { 2497 + char *fake_devname = NULL; 2498 + 2499 + if (mount_data != mount_data_global) 2500 + kfree(mount_data); 2501 + mount_data = cifs_compose_mount_options( 2502 + cifs_sb->mountdata, full_path + 1, 2503 + referrals, &fake_devname); 2504 + kfree(fake_devname); 2505 + free_dfs_info_array(referrals, num_referrals); 2506 + 2507 + if (tcon) 2508 + cifs_put_tcon(tcon); 2509 + else if (pSesInfo) 2510 + cifs_put_smb_ses(pSesInfo); 2511 + 2512 + cleanup_volume_info(&volume_info); 2513 + FreeXid(xid); 2514 + kfree(full_path); 2515 + goto try_mount_again; 2516 + } 2517 + #else /* No DFS support, return error on mount */ 2518 + rc = -EOPNOTSUPP; 2519 + #endif 2520 + } 2521 + 2522 + mount_fail_check: 2523 + /* on error free sesinfo and tcon struct if needed */ 2524 + if (rc) { 2525 + if (mount_data != mount_data_global) 2526 + kfree(mount_data); 2527 + /* If find_unc succeeded then rc == 0 so we can not end */ 2528 + /* up accidently freeing someone elses tcon struct */ 2529 + if (tcon) 2530 + cifs_put_tcon(tcon); 2531 + else if (pSesInfo) 2532 + cifs_put_smb_ses(pSesInfo); 2533 + else 2534 + cifs_put_tcp_session(srvTcp); 2535 + goto out; 2536 } 2537 2538 /* volume_info->password is freed above when existing session found ··· 2484 password will be freed at unmount time) */ 2485 out: 2486 /* zero out password before freeing */ 2487 + cleanup_volume_info(&volume_info); 2488 FreeXid(xid); 2489 return rc; 2490 } ··· 2673 /* We look for obvious messed up bcc or strings in response so we do not go off 2674 the end since (at least) WIN2K and Windows XP have a major bug in not null 2675 terminating last Unicode string in response */ 2676 + kfree(ses->serverOS); 2677 ses->serverOS = kzalloc(2 * (len + 1), 2678 GFP_KERNEL); 2679 if (ses->serverOS == NULL) ··· 2710 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 2711 /* last string is not always null terminated 2712 (for e.g. for Windows XP & 2000) */ 2713 + kfree(ses->serverDomain); 2714 ses->serverDomain = 2715 kzalloc(2*(len+1), 2716 GFP_KERNEL); ··· 2725 ses->serverDomain[1+(2*len)] = 0; 2726 } else { /* else no more room so create 2727 dummy domain string */ 2728 + kfree(ses->serverDomain); 2729 ses->serverDomain = 2730 kzalloc(2, GFP_KERNEL); 2731 } ··· 2772 bcc_ptr++; 2773 2774 len = strnlen(bcc_ptr, 1024); 2775 + kfree(ses->serverDomain); 2776 ses->serverDomain = kzalloc(len + 1, 2777 GFP_KERNEL); 2778 if (ses->serverDomain == NULL) ··· 3013 /* We look for obvious messed up bcc or strings in response so we do not go off 3014 the end since (at least) WIN2K and Windows XP have a major bug in not null 3015 terminating last Unicode string in response */ 3016 + kfree(ses->serverOS); 3017 ses->serverOS = 3018 kzalloc(2 * (len + 1), GFP_KERNEL); 3019 cifs_strfromUCS_le(ses->serverOS, ··· 3086 if (((long) bcc_ptr + len) - (long) 3087 pByteArea(smb_buffer_response) 3088 <= BCC(smb_buffer_response)) { 3089 + kfree(ses->serverOS); 3090 ses->serverOS = 3091 kzalloc(len + 1, 3092 GFP_KERNEL); ··· 3414 /* We look for obvious messed up bcc or strings in response so we do not go off 3415 the end since (at least) WIN2K and Windows XP have a major bug in not null 3416 terminating last Unicode string in response */ 3417 + kfree(ses->serverOS); 3418 ses->serverOS = 3419 kzalloc(2 * (len + 1), GFP_KERNEL); 3420 cifs_strfromUCS_le(ses->serverOS, ··· 3448 if (remaining_words > 0) { 3449 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 3450 /* last string not always null terminated (e.g. for Windows XP & 2000) */ 3451 + kfree(ses->serverDomain); 3452 ses->serverDomain = 3453 kzalloc(2 * 3454 (len + ··· 3476 = 0; 3477 } /* else no more room so create dummy domain string */ 3478 else { 3479 + kfree(ses->serverDomain); 3480 ses->serverDomain = kzalloc(2,GFP_KERNEL); 3481 } 3482 } else { /* no room so create dummy domain and NOS string */ 3483 + kfree(ses->serverDomain); 3484 ses->serverDomain = kzalloc(2, GFP_KERNEL); 3485 kfree(ses->serverNOS); 3486 ses->serverNOS = kzalloc(2, GFP_KERNEL); ··· 3492 if (((long) bcc_ptr + len) - 3493 (long) pByteArea(smb_buffer_response) 3494 <= BCC(smb_buffer_response)) { 3495 + kfree(ses->serverOS); 3496 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 3497 strncpy(ses->serverOS,bcc_ptr, len); 3498 ··· 3512 bcc_ptr++; 3513 3514 len = strnlen(bcc_ptr, 1024); 3515 + kfree(ses->serverDomain); 3516 ses->serverDomain = 3517 kzalloc(len+1, 3518 GFP_KERNEL); ··· 3674 BCC(smb_buffer_response)) { 3675 kfree(tcon->nativeFileSystem); 3676 tcon->nativeFileSystem = 3677 + kzalloc((4 * length) + 2, GFP_KERNEL); 3678 + if (tcon->nativeFileSystem) { 3679 cifs_strfromUCS_le( 3680 tcon->nativeFileSystem, 3681 (__le16 *) bcc_ptr, 3682 length, nls_codepage); 3683 + cFYI(1, ("nativeFileSystem=%s", 3684 + tcon->nativeFileSystem)); 3685 + } 3686 } 3687 /* else do not bother copying these information fields*/ 3688 } else {
+97 -48
fs/cifs/dir.c
··· 129 return full_path; 130 } 131 132 int cifs_posix_open(char *full_path, struct inode **pinode, 133 struct super_block *sb, int mode, int oflags, 134 int *poplock, __u16 *pnetfid, int xid) 135 { 136 int rc; 137 __u32 oplock; 138 FILE_UNIX_BASIC_INFO *presp_data; 139 __u32 posix_flags = 0; 140 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); ··· 222 if (oflags & O_DIRECT) 223 posix_flags |= SMB_O_DIRECT; 224 225 226 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, 227 pnetfid, presp_data, &oplock, full_path, ··· 239 if (!pinode) 240 goto posix_open_ret; /* caller does not need info */ 241 242 - if (*pinode == NULL) 243 - *pinode = cifs_new_inode(sb, &presp_data->UniqueId); 244 /* else an inode was passed in. Update its info, don't create one */ 245 246 /* We do not need to close the file if new_inode fails since ··· 251 goto posix_open_ret; 252 253 posix_fill_in_inode(*pinode, presp_data, 1); 254 255 posix_open_ret: 256 kfree(presp_data); ··· 295 char *full_path = NULL; 296 FILE_ALL_INFO *buf = NULL; 297 struct inode *newinode = NULL; 298 - struct cifsInodeInfo *pCifsInode; 299 int disposition = FILE_OVERWRITE_IF; 300 bool write_only = false; 301 ··· 465 /* mknod case - do not leave file open */ 466 CIFSSMBClose(xid, tcon, fileHandle); 467 } else if (newinode) { 468 - struct cifsFileInfo *pCifsFile = 469 - kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 470 - 471 - if (pCifsFile == NULL) 472 - goto cifs_create_out; 473 - pCifsFile->netfid = fileHandle; 474 - pCifsFile->pid = current->tgid; 475 - pCifsFile->pInode = newinode; 476 - pCifsFile->invalidHandle = false; 477 - pCifsFile->closePend = false; 478 - init_MUTEX(&pCifsFile->fh_sem); 479 - mutex_init(&pCifsFile->lock_mutex); 480 - INIT_LIST_HEAD(&pCifsFile->llist); 481 - atomic_set(&pCifsFile->wrtPending, 0); 482 - 483 - /* set the following in open now 484 - pCifsFile->pfile = file; */ 485 - write_lock(&GlobalSMBSeslock); 486 - list_add(&pCifsFile->tlist, &tcon->openFileList); 487 - pCifsInode = CIFS_I(newinode); 488 - if (pCifsInode) { 489 - /* if readable file instance put first in list*/ 490 - if (write_only) { 491 - list_add_tail(&pCifsFile->flist, 492 - &pCifsInode->openFileList); 493 - } else { 494 - list_add(&pCifsFile->flist, 495 - &pCifsInode->openFileList); 496 - } 497 - if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { 498 - pCifsInode->clientCanCacheAll = true; 499 - pCifsInode->clientCanCacheRead = true; 500 - cFYI(1, ("Exclusive Oplock inode %p", 501 - newinode)); 502 - } else if ((oplock & 0xF) == OPLOCK_READ) 503 - pCifsInode->clientCanCacheRead = true; 504 - } 505 - write_unlock(&GlobalSMBSeslock); 506 } 507 cifs_create_out: 508 kfree(buf); ··· 599 return rc; 600 } 601 602 - 603 struct dentry * 604 cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, 605 struct nameidata *nd) 606 { 607 int xid; 608 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 609 struct cifs_sb_info *cifs_sb; 610 struct cifsTconInfo *pTcon; 611 struct inode *newInode = NULL; 612 char *full_path = NULL; 613 614 xid = GetXid(); 615 ··· 655 } 656 cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); 657 658 - if (pTcon->unix_ext) 659 - rc = cifs_get_inode_info_unix(&newInode, full_path, 660 - parent_dir_inode->i_sb, xid); 661 - else 662 rc = cifs_get_inode_info(&newInode, full_path, NULL, 663 - parent_dir_inode->i_sb, xid, NULL); 664 665 if ((rc == 0) && (newInode != NULL)) { 666 if (pTcon->nocase) ··· 693 else 694 direntry->d_op = &cifs_dentry_ops; 695 d_add(direntry, newInode); 696 - 697 /* since paths are not looked up by component - the parent 698 directories are presumed to be good here */ 699 renew_parental_timestamps(direntry);
··· 129 return full_path; 130 } 131 132 + static void 133 + cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle, 134 + struct cifsTconInfo *tcon, bool write_only) 135 + { 136 + int oplock = 0; 137 + struct cifsFileInfo *pCifsFile; 138 + struct cifsInodeInfo *pCifsInode; 139 + 140 + pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 141 + 142 + if (pCifsFile == NULL) 143 + return; 144 + 145 + if (oplockEnabled) 146 + oplock = REQ_OPLOCK; 147 + 148 + pCifsFile->netfid = fileHandle; 149 + pCifsFile->pid = current->tgid; 150 + pCifsFile->pInode = newinode; 151 + pCifsFile->invalidHandle = false; 152 + pCifsFile->closePend = false; 153 + mutex_init(&pCifsFile->fh_mutex); 154 + mutex_init(&pCifsFile->lock_mutex); 155 + INIT_LIST_HEAD(&pCifsFile->llist); 156 + atomic_set(&pCifsFile->wrtPending, 0); 157 + 158 + /* set the following in open now 159 + pCifsFile->pfile = file; */ 160 + write_lock(&GlobalSMBSeslock); 161 + list_add(&pCifsFile->tlist, &tcon->openFileList); 162 + pCifsInode = CIFS_I(newinode); 163 + if (pCifsInode) { 164 + /* if readable file instance put first in list*/ 165 + if (write_only) 166 + list_add_tail(&pCifsFile->flist, 167 + &pCifsInode->openFileList); 168 + else 169 + list_add(&pCifsFile->flist, &pCifsInode->openFileList); 170 + 171 + if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { 172 + pCifsInode->clientCanCacheAll = true; 173 + pCifsInode->clientCanCacheRead = true; 174 + cFYI(1, ("Exclusive Oplock inode %p", newinode)); 175 + } else if ((oplock & 0xF) == OPLOCK_READ) 176 + pCifsInode->clientCanCacheRead = true; 177 + } 178 + write_unlock(&GlobalSMBSeslock); 179 + } 180 + 181 int cifs_posix_open(char *full_path, struct inode **pinode, 182 struct super_block *sb, int mode, int oflags, 183 int *poplock, __u16 *pnetfid, int xid) 184 { 185 int rc; 186 __u32 oplock; 187 + bool write_only = false; 188 FILE_UNIX_BASIC_INFO *presp_data; 189 __u32 posix_flags = 0; 190 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); ··· 172 if (oflags & O_DIRECT) 173 posix_flags |= SMB_O_DIRECT; 174 175 + if (!(oflags & FMODE_READ)) 176 + write_only = true; 177 178 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, 179 pnetfid, presp_data, &oplock, full_path, ··· 187 if (!pinode) 188 goto posix_open_ret; /* caller does not need info */ 189 190 + if (*pinode == NULL) { 191 + __u64 unique_id = le64_to_cpu(presp_data->UniqueId); 192 + *pinode = cifs_new_inode(sb, &unique_id); 193 + } 194 /* else an inode was passed in. Update its info, don't create one */ 195 196 /* We do not need to close the file if new_inode fails since ··· 197 goto posix_open_ret; 198 199 posix_fill_in_inode(*pinode, presp_data, 1); 200 + 201 + cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only); 202 203 posix_open_ret: 204 kfree(presp_data); ··· 239 char *full_path = NULL; 240 FILE_ALL_INFO *buf = NULL; 241 struct inode *newinode = NULL; 242 int disposition = FILE_OVERWRITE_IF; 243 bool write_only = false; 244 ··· 410 /* mknod case - do not leave file open */ 411 CIFSSMBClose(xid, tcon, fileHandle); 412 } else if (newinode) { 413 + cifs_fill_fileinfo(newinode, fileHandle, 414 + cifs_sb->tcon, write_only); 415 } 416 cifs_create_out: 417 kfree(buf); ··· 580 return rc; 581 } 582 583 struct dentry * 584 cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, 585 struct nameidata *nd) 586 { 587 int xid; 588 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 589 + int oplock = 0; 590 + int mode; 591 + __u16 fileHandle = 0; 592 + bool posix_open = false; 593 struct cifs_sb_info *cifs_sb; 594 struct cifsTconInfo *pTcon; 595 struct inode *newInode = NULL; 596 char *full_path = NULL; 597 + struct file *filp; 598 599 xid = GetXid(); 600 ··· 632 } 633 cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); 634 635 + if (pTcon->unix_ext) { 636 + if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && 637 + (nd->flags & LOOKUP_OPEN)) { 638 + if (!((nd->intent.open.flags & O_CREAT) && 639 + (nd->intent.open.flags & O_EXCL))) { 640 + mode = nd->intent.open.create_mode & 641 + ~current_umask(); 642 + rc = cifs_posix_open(full_path, &newInode, 643 + parent_dir_inode->i_sb, mode, 644 + nd->intent.open.flags, &oplock, 645 + &fileHandle, xid); 646 + /* 647 + * This code works around a bug in 648 + * samba posix open in samba versions 3.3.1 649 + * and earlier where create works 650 + * but open fails with invalid parameter. 651 + * If either of these error codes are 652 + * returned, follow the normal lookup. 653 + * Otherwise, the error during posix open 654 + * is handled. 655 + */ 656 + if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) 657 + posix_open = true; 658 + } 659 + } 660 + if (!posix_open) 661 + rc = cifs_get_inode_info_unix(&newInode, full_path, 662 + parent_dir_inode->i_sb, xid); 663 + } else 664 rc = cifs_get_inode_info(&newInode, full_path, NULL, 665 + parent_dir_inode->i_sb, xid, NULL); 666 667 if ((rc == 0) && (newInode != NULL)) { 668 if (pTcon->nocase) ··· 645 else 646 direntry->d_op = &cifs_dentry_ops; 647 d_add(direntry, newInode); 648 + if (posix_open) 649 + filp = lookup_instantiate_filp(nd, direntry, NULL); 650 /* since paths are not looked up by component - the parent 651 directories are presumed to be good here */ 652 renew_parental_timestamps(direntry);
+1 -1
fs/cifs/dns_resolve.c
··· 78 } 79 80 key->type_data.x[0] = datalen; 81 - rcu_assign_pointer(key->payload.data, ip); 82 83 return rc; 84 }
··· 78 } 79 80 key->type_data.x[0] = datalen; 81 + key->payload.data = ip; 82 83 return rc; 84 }
+78 -45
fs/cifs/file.c
··· 46 memset(private_data, 0, sizeof(struct cifsFileInfo)); 47 private_data->netfid = netfid; 48 private_data->pid = current->tgid; 49 - init_MUTEX(&private_data->fh_sem); 50 mutex_init(&private_data->lock_mutex); 51 INIT_LIST_HEAD(&private_data->llist); 52 private_data->pfile = file; /* needed for writepage */ ··· 284 cifs_sb = CIFS_SB(inode->i_sb); 285 tcon = cifs_sb->tcon; 286 287 - if (file->f_flags & O_CREAT) { 288 - /* search inode for this file and fill in file->private_data */ 289 - pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 290 - read_lock(&GlobalSMBSeslock); 291 - list_for_each(tmp, &pCifsInode->openFileList) { 292 - pCifsFile = list_entry(tmp, struct cifsFileInfo, 293 - flist); 294 - if ((pCifsFile->pfile == NULL) && 295 - (pCifsFile->pid == current->tgid)) { 296 - /* mode set in cifs_create */ 297 298 - /* needed for writepage */ 299 - pCifsFile->pfile = file; 300 301 - file->private_data = pCifsFile; 302 - break; 303 - } 304 - } 305 - read_unlock(&GlobalSMBSeslock); 306 - if (file->private_data != NULL) { 307 - rc = 0; 308 - FreeXid(xid); 309 - return rc; 310 - } else { 311 - if (file->f_flags & O_EXCL) 312 - cERROR(1, ("could not find file instance for " 313 - "new file %p", file)); 314 } 315 } 316 317 full_path = build_path_from_dentry(file->f_path.dentry); 318 if (full_path == NULL) { ··· 497 return -EBADF; 498 499 xid = GetXid(); 500 - down(&pCifsFile->fh_sem); 501 if (!pCifsFile->invalidHandle) { 502 - up(&pCifsFile->fh_sem); 503 FreeXid(xid); 504 return 0; 505 } ··· 530 if (full_path == NULL) { 531 rc = -ENOMEM; 532 reopen_error_exit: 533 - up(&pCifsFile->fh_sem); 534 FreeXid(xid); 535 return rc; 536 } ··· 572 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 573 CIFS_MOUNT_MAP_SPECIAL_CHR); 574 if (rc) { 575 - up(&pCifsFile->fh_sem); 576 cFYI(1, ("cifs_open returned 0x%x", rc)); 577 cFYI(1, ("oplock: %d", oplock)); 578 } else { 579 reopen_success: 580 pCifsFile->netfid = netfid; 581 pCifsFile->invalidHandle = false; 582 - up(&pCifsFile->fh_sem); 583 pCifsInode = CIFS_I(inode); 584 if (pCifsInode) { 585 if (can_flush) { ··· 968 return rc; 969 } 970 971 ssize_t cifs_user_write(struct file *file, const char __user *write_data, 972 size_t write_size, loff_t *poffset) 973 { ··· 1012 struct cifsTconInfo *pTcon; 1013 int xid, long_op; 1014 struct cifsFileInfo *open_file; 1015 1016 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1017 ··· 1032 1033 xid = GetXid(); 1034 1035 - if (*poffset > file->f_path.dentry->d_inode->i_size) 1036 - long_op = CIFS_VLONG_OP; /* writes past EOF take long time */ 1037 - else 1038 - long_op = CIFS_LONG_OP; 1039 - 1040 for (total_written = 0; write_size > total_written; 1041 total_written += bytes_written) { 1042 rc = -EAGAIN; ··· 1076 FreeXid(xid); 1077 return rc; 1078 } 1079 - } else 1080 *poffset += bytes_written; 1081 long_op = CIFS_STD_OP; /* subsequent writes fast - 1082 15 seconds is plenty */ 1083 } ··· 1115 struct cifsTconInfo *pTcon; 1116 int xid, long_op; 1117 struct cifsFileInfo *open_file; 1118 1119 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1120 ··· 1130 1131 xid = GetXid(); 1132 1133 - if (*poffset > file->f_path.dentry->d_inode->i_size) 1134 - long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */ 1135 - else 1136 - long_op = CIFS_LONG_OP; 1137 - 1138 for (total_written = 0; write_size > total_written; 1139 total_written += bytes_written) { 1140 rc = -EAGAIN; ··· 1193 FreeXid(xid); 1194 return rc; 1195 } 1196 - } else 1197 *poffset += bytes_written; 1198 long_op = CIFS_STD_OP; /* subsequent writes fast - 1199 15 seconds is plenty */ 1200 } ··· 1409 int nr_pages; 1410 __u64 offset = 0; 1411 struct cifsFileInfo *open_file; 1412 struct page *page; 1413 struct pagevec pvec; 1414 int rc = 0; 1415 int scanned = 0; 1416 - int xid; 1417 1418 cifs_sb = CIFS_SB(mapping->host->i_sb); 1419 ··· 1558 cERROR(1, ("No writable handles for inode")); 1559 rc = -EBADF; 1560 } else { 1561 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1562 open_file->netfid, 1563 bytes_to_write, offset, 1564 &bytes_written, iov, n_iov, 1565 - CIFS_LONG_OP); 1566 atomic_dec(&open_file->wrtPending); 1567 if (rc || bytes_written < bytes_to_write) { 1568 cERROR(1, ("Write2 ret %d, wrote %d", 1569 rc, bytes_written));
··· 46 memset(private_data, 0, sizeof(struct cifsFileInfo)); 47 private_data->netfid = netfid; 48 private_data->pid = current->tgid; 49 + mutex_init(&private_data->fh_mutex); 50 mutex_init(&private_data->lock_mutex); 51 INIT_LIST_HEAD(&private_data->llist); 52 private_data->pfile = file; /* needed for writepage */ ··· 284 cifs_sb = CIFS_SB(inode->i_sb); 285 tcon = cifs_sb->tcon; 286 287 + /* search inode for this file and fill in file->private_data */ 288 + pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 289 + read_lock(&GlobalSMBSeslock); 290 + list_for_each(tmp, &pCifsInode->openFileList) { 291 + pCifsFile = list_entry(tmp, struct cifsFileInfo, 292 + flist); 293 + if ((pCifsFile->pfile == NULL) && 294 + (pCifsFile->pid == current->tgid)) { 295 + /* mode set in cifs_create */ 296 297 + /* needed for writepage */ 298 + pCifsFile->pfile = file; 299 300 + file->private_data = pCifsFile; 301 + break; 302 } 303 } 304 + read_unlock(&GlobalSMBSeslock); 305 + 306 + if (file->private_data != NULL) { 307 + rc = 0; 308 + FreeXid(xid); 309 + return rc; 310 + } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) 311 + cERROR(1, ("could not find file instance for " 312 + "new file %p", file)); 313 314 full_path = build_path_from_dentry(file->f_path.dentry); 315 if (full_path == NULL) { ··· 500 return -EBADF; 501 502 xid = GetXid(); 503 + mutex_unlock(&pCifsFile->fh_mutex); 504 if (!pCifsFile->invalidHandle) { 505 + mutex_lock(&pCifsFile->fh_mutex); 506 FreeXid(xid); 507 return 0; 508 } ··· 533 if (full_path == NULL) { 534 rc = -ENOMEM; 535 reopen_error_exit: 536 + mutex_lock(&pCifsFile->fh_mutex); 537 FreeXid(xid); 538 return rc; 539 } ··· 575 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 576 CIFS_MOUNT_MAP_SPECIAL_CHR); 577 if (rc) { 578 + mutex_lock(&pCifsFile->fh_mutex); 579 cFYI(1, ("cifs_open returned 0x%x", rc)); 580 cFYI(1, ("oplock: %d", oplock)); 581 } else { 582 reopen_success: 583 pCifsFile->netfid = netfid; 584 pCifsFile->invalidHandle = false; 585 + mutex_lock(&pCifsFile->fh_mutex); 586 pCifsInode = CIFS_I(inode); 587 if (pCifsInode) { 588 if (can_flush) { ··· 971 return rc; 972 } 973 974 + /* 975 + * Set the timeout on write requests past EOF. For some servers (Windows) 976 + * these calls can be very long. 977 + * 978 + * If we're writing >10M past the EOF we give a 180s timeout. Anything less 979 + * than that gets a 45s timeout. Writes not past EOF get 15s timeouts. 980 + * The 10M cutoff is totally arbitrary. A better scheme for this would be 981 + * welcome if someone wants to suggest one. 982 + * 983 + * We may be able to do a better job with this if there were some way to 984 + * declare that a file should be sparse. 985 + */ 986 + static int 987 + cifs_write_timeout(struct cifsInodeInfo *cifsi, loff_t offset) 988 + { 989 + if (offset <= cifsi->server_eof) 990 + return CIFS_STD_OP; 991 + else if (offset > (cifsi->server_eof + (10 * 1024 * 1024))) 992 + return CIFS_VLONG_OP; 993 + else 994 + return CIFS_LONG_OP; 995 + } 996 + 997 + /* update the file size (if needed) after a write */ 998 + static void 999 + cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 1000 + unsigned int bytes_written) 1001 + { 1002 + loff_t end_of_write = offset + bytes_written; 1003 + 1004 + if (end_of_write > cifsi->server_eof) 1005 + cifsi->server_eof = end_of_write; 1006 + } 1007 + 1008 ssize_t cifs_user_write(struct file *file, const char __user *write_data, 1009 size_t write_size, loff_t *poffset) 1010 { ··· 981 struct cifsTconInfo *pTcon; 982 int xid, long_op; 983 struct cifsFileInfo *open_file; 984 + struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); 985 986 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 987 ··· 1000 1001 xid = GetXid(); 1002 1003 + long_op = cifs_write_timeout(cifsi, *poffset); 1004 for (total_written = 0; write_size > total_written; 1005 total_written += bytes_written) { 1006 rc = -EAGAIN; ··· 1048 FreeXid(xid); 1049 return rc; 1050 } 1051 + } else { 1052 + cifs_update_eof(cifsi, *poffset, bytes_written); 1053 *poffset += bytes_written; 1054 + } 1055 long_op = CIFS_STD_OP; /* subsequent writes fast - 1056 15 seconds is plenty */ 1057 } ··· 1085 struct cifsTconInfo *pTcon; 1086 int xid, long_op; 1087 struct cifsFileInfo *open_file; 1088 + struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); 1089 1090 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1091 ··· 1099 1100 xid = GetXid(); 1101 1102 + long_op = cifs_write_timeout(cifsi, *poffset); 1103 for (total_written = 0; write_size > total_written; 1104 total_written += bytes_written) { 1105 rc = -EAGAIN; ··· 1166 FreeXid(xid); 1167 return rc; 1168 } 1169 + } else { 1170 + cifs_update_eof(cifsi, *poffset, bytes_written); 1171 *poffset += bytes_written; 1172 + } 1173 long_op = CIFS_STD_OP; /* subsequent writes fast - 1174 15 seconds is plenty */ 1175 } ··· 1380 int nr_pages; 1381 __u64 offset = 0; 1382 struct cifsFileInfo *open_file; 1383 + struct cifsInodeInfo *cifsi = CIFS_I(mapping->host); 1384 struct page *page; 1385 struct pagevec pvec; 1386 int rc = 0; 1387 int scanned = 0; 1388 + int xid, long_op; 1389 1390 cifs_sb = CIFS_SB(mapping->host->i_sb); 1391 ··· 1528 cERROR(1, ("No writable handles for inode")); 1529 rc = -EBADF; 1530 } else { 1531 + long_op = cifs_write_timeout(cifsi, offset); 1532 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1533 open_file->netfid, 1534 bytes_to_write, offset, 1535 &bytes_written, iov, n_iov, 1536 + long_op); 1537 atomic_dec(&open_file->wrtPending); 1538 + cifs_update_eof(cifsi, offset, bytes_written); 1539 + 1540 if (rc || bytes_written < bytes_to_write) { 1541 cERROR(1, ("Write2 ret %d, wrote %d", 1542 rc, bytes_written));
+42 -35
fs/cifs/inode.c
··· 143 144 inode->i_nlink = le64_to_cpu(info->Nlinks); 145 146 spin_lock(&inode->i_lock); 147 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 148 /* ··· 277 278 /* get new inode */ 279 if (*pinode == NULL) { 280 - *pinode = cifs_new_inode(sb, &find_data.UniqueId); 281 if (*pinode == NULL) { 282 rc = -ENOMEM; 283 goto cgiiu_exit; ··· 607 inode->i_mode |= S_IFREG; 608 } 609 610 spin_lock(&inode->i_lock); 611 - if (is_size_safe_to_change(cifsInfo, 612 - le64_to_cpu(pfindData->EndOfFile))) { 613 /* can not safely shrink the file size here if the 614 client is writing to it due to potential races */ 615 - i_size_write(inode, le64_to_cpu(pfindData->EndOfFile)); 616 617 /* 512 bytes (2**9) is the fake blocksize that must be 618 used for this calculation */ ··· 1140 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1141 d_drop(direntry); 1142 } else { 1143 if (pInfo->Type == cpu_to_le32(-1)) { 1144 /* no return info, go query for it */ 1145 kfree(pInfo); ··· 1154 else 1155 direntry->d_op = &cifs_dentry_ops; 1156 1157 - newinode = cifs_new_inode(inode->i_sb, 1158 - &pInfo->UniqueId); 1159 if (newinode == NULL) { 1160 kfree(pInfo); 1161 goto mkdir_get_info; ··· 1453 checking the UniqueId via FILE_INTERNAL_INFO */ 1454 1455 unlink_target: 1456 - if ((rc == -EACCES) || (rc == -EEXIST)) { 1457 tmprc = cifs_unlink(target_dir, target_dentry); 1458 if (tmprc) 1459 goto cifs_rename_exit; ··· 1757 } 1758 1759 if (rc == 0) { 1760 rc = cifs_vmtruncate(inode, attrs->ia_size); 1761 cifs_truncate_page(inode->i_mapping, inode->i_size); 1762 } ··· 1797 goto out; 1798 } 1799 1800 - if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) { 1801 - /* 1802 - Flush data before changing file size or changing the last 1803 - write time of the file on the server. If the 1804 - flush returns error, store it to report later and continue. 1805 - BB: This should be smarter. Why bother flushing pages that 1806 - will be truncated anyway? Also, should we error out here if 1807 - the flush returns error? 1808 - */ 1809 - rc = filemap_write_and_wait(inode->i_mapping); 1810 - if (rc != 0) { 1811 - cifsInode->write_behind_rc = rc; 1812 - rc = 0; 1813 - } 1814 } 1815 1816 if (attrs->ia_valid & ATTR_SIZE) { ··· 1909 return -ENOMEM; 1910 } 1911 1912 - if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) { 1913 - /* 1914 - Flush data before changing file size or changing the last 1915 - write time of the file on the server. If the 1916 - flush returns error, store it to report later and continue. 1917 - BB: This should be smarter. Why bother flushing pages that 1918 - will be truncated anyway? Also, should we error out here if 1919 - the flush returns error? 1920 - */ 1921 - rc = filemap_write_and_wait(inode->i_mapping); 1922 - if (rc != 0) { 1923 - cifsInode->write_behind_rc = rc; 1924 - rc = 0; 1925 - } 1926 } 1927 1928 if (attrs->ia_valid & ATTR_SIZE) {
··· 143 144 inode->i_nlink = le64_to_cpu(info->Nlinks); 145 146 + cifsInfo->server_eof = end_of_file; 147 spin_lock(&inode->i_lock); 148 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 149 /* ··· 276 277 /* get new inode */ 278 if (*pinode == NULL) { 279 + __u64 unique_id = le64_to_cpu(find_data.UniqueId); 280 + *pinode = cifs_new_inode(sb, &unique_id); 281 if (*pinode == NULL) { 282 rc = -ENOMEM; 283 goto cgiiu_exit; ··· 605 inode->i_mode |= S_IFREG; 606 } 607 608 + cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile); 609 spin_lock(&inode->i_lock); 610 + if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) { 611 /* can not safely shrink the file size here if the 612 client is writing to it due to potential races */ 613 + i_size_write(inode, cifsInfo->server_eof); 614 615 /* 512 bytes (2**9) is the fake blocksize that must be 616 used for this calculation */ ··· 1138 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1139 d_drop(direntry); 1140 } else { 1141 + __u64 unique_id; 1142 if (pInfo->Type == cpu_to_le32(-1)) { 1143 /* no return info, go query for it */ 1144 kfree(pInfo); ··· 1151 else 1152 direntry->d_op = &cifs_dentry_ops; 1153 1154 + unique_id = le64_to_cpu(pInfo->UniqueId); 1155 + newinode = cifs_new_inode(inode->i_sb, &unique_id); 1156 if (newinode == NULL) { 1157 kfree(pInfo); 1158 goto mkdir_get_info; ··· 1450 checking the UniqueId via FILE_INTERNAL_INFO */ 1451 1452 unlink_target: 1453 + /* Try unlinking the target dentry if it's not negative */ 1454 + if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) { 1455 tmprc = cifs_unlink(target_dir, target_dentry); 1456 if (tmprc) 1457 goto cifs_rename_exit; ··· 1753 } 1754 1755 if (rc == 0) { 1756 + cifsInode->server_eof = attrs->ia_size; 1757 rc = cifs_vmtruncate(inode, attrs->ia_size); 1758 cifs_truncate_page(inode->i_mapping, inode->i_size); 1759 } ··· 1792 goto out; 1793 } 1794 1795 + /* 1796 + * Attempt to flush data before changing attributes. We need to do 1797 + * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the 1798 + * ownership or mode then we may also need to do this. Here, we take 1799 + * the safe way out and just do the flush on all setattr requests. If 1800 + * the flush returns error, store it to report later and continue. 1801 + * 1802 + * BB: This should be smarter. Why bother flushing pages that 1803 + * will be truncated anyway? Also, should we error out here if 1804 + * the flush returns error? 1805 + */ 1806 + rc = filemap_write_and_wait(inode->i_mapping); 1807 + if (rc != 0) { 1808 + cifsInode->write_behind_rc = rc; 1809 + rc = 0; 1810 } 1811 1812 if (attrs->ia_valid & ATTR_SIZE) { ··· 1903 return -ENOMEM; 1904 } 1905 1906 + /* 1907 + * Attempt to flush data before changing attributes. We need to do 1908 + * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the 1909 + * ownership or mode then we may also need to do this. Here, we take 1910 + * the safe way out and just do the flush on all setattr requests. If 1911 + * the flush returns error, store it to report later and continue. 1912 + * 1913 + * BB: This should be smarter. Why bother flushing pages that 1914 + * will be truncated anyway? Also, should we error out here if 1915 + * the flush returns error? 1916 + */ 1917 + rc = filemap_write_and_wait(inode->i_mapping); 1918 + if (rc != 0) { 1919 + cifsInode->write_behind_rc = rc; 1920 + rc = 0; 1921 } 1922 1923 if (attrs->ia_valid & ATTR_SIZE) {
+4 -2
fs/cifs/readdir.c
··· 239 if (atomic_read(&cifsInfo->inUse) == 0) 240 atomic_set(&cifsInfo->inUse, 1); 241 242 spin_lock(&tmp_inode->i_lock); 243 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 244 /* can not safely change the file size here if the ··· 376 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 377 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 378 379 spin_lock(&tmp_inode->i_lock); 380 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 381 /* can not safely change the file size here if the ··· 842 len = strnlen(filename, PATH_MAX); 843 } 844 845 - *pinum = pFindData->UniqueId; 846 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 847 FILE_DIRECTORY_INFO *pFindData = 848 (FILE_DIRECTORY_INFO *)current_entry; ··· 858 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 859 filename = &pFindData->FileName[0]; 860 len = le32_to_cpu(pFindData->FileNameLength); 861 - *pinum = pFindData->UniqueId; 862 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 863 FILE_BOTH_DIRECTORY_INFO *pFindData = 864 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
··· 239 if (atomic_read(&cifsInfo->inUse) == 0) 240 atomic_set(&cifsInfo->inUse, 1); 241 242 + cifsInfo->server_eof = end_of_file; 243 spin_lock(&tmp_inode->i_lock); 244 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 245 /* can not safely change the file size here if the ··· 375 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 376 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 377 378 + cifsInfo->server_eof = end_of_file; 379 spin_lock(&tmp_inode->i_lock); 380 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 381 /* can not safely change the file size here if the ··· 840 len = strnlen(filename, PATH_MAX); 841 } 842 843 + *pinum = le64_to_cpu(pFindData->UniqueId); 844 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 845 FILE_DIRECTORY_INFO *pFindData = 846 (FILE_DIRECTORY_INFO *)current_entry; ··· 856 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 857 filename = &pFindData->FileName[0]; 858 len = le32_to_cpu(pFindData->FileNameLength); 859 + *pinum = le64_to_cpu(pFindData->UniqueId); 860 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 861 FILE_BOTH_DIRECTORY_INFO *pFindData = 862 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
+27 -20
fs/cifs/sess.c
··· 285 int words_left, len; 286 char *data = *pbcc_area; 287 288 - 289 - 290 cFYI(1, ("bleft %d", bleft)); 291 292 - 293 - /* SMB header is unaligned, so cifs servers word align start of 294 - Unicode strings */ 295 - data++; 296 - bleft--; /* Windows servers do not always double null terminate 297 - their final Unicode string - in which case we 298 - now will not attempt to decode the byte of junk 299 - which follows it */ 300 301 words_left = bleft / 2; 302 303 /* save off server operating system */ 304 len = UniStrnlen((wchar_t *) data, words_left); 305 306 - /* We look for obvious messed up bcc or strings in response so we do not go off 307 - the end since (at least) WIN2K and Windows XP have a major bug in not null 308 - terminating last Unicode string in response */ 309 if (len >= words_left) 310 return rc; 311 312 kfree(ses->serverOS); 313 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 314 ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); 315 - if (ses->serverOS != NULL) 316 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); 317 data += 2 * (len + 1); 318 words_left -= len + 1; 319 ··· 329 if (ses->serverNOS != NULL) { 330 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 331 nls_cp); 332 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) { 333 cFYI(1, ("NT4 server")); 334 ses->flags |= CIFS_SES_NT4; ··· 345 return rc; 346 347 kfree(ses->serverDomain); 348 - ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 349 if (ses->serverDomain != NULL) { 350 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 351 nls_cp); 352 - ses->serverDomain[2*len] = 0; 353 - ses->serverDomain[(2*len) + 1] = 0; 354 } 355 data += 2 * (len + 1); 356 words_left -= len + 1; ··· 703 } 704 705 /* BB check if Unicode and decode strings */ 706 - if (smb_buf->Flags2 & SMBFLG2_UNICODE) 707 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 708 - ses, nls_cp); 709 - else 710 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, 711 ses, nls_cp); 712 713 ssetup_exit: 714 if (spnego_key) {
··· 285 int words_left, len; 286 char *data = *pbcc_area; 287 288 cFYI(1, ("bleft %d", bleft)); 289 290 + /* 291 + * Windows servers do not always double null terminate their final 292 + * Unicode string. Check to see if there are an uneven number of bytes 293 + * left. If so, then add an extra NULL pad byte to the end of the 294 + * response. 295 + * 296 + * See section 2.7.2 in "Implementing CIFS" for details 297 + */ 298 + if (bleft % 2) { 299 + data[bleft] = 0; 300 + ++bleft; 301 + } 302 303 words_left = bleft / 2; 304 305 /* save off server operating system */ 306 len = UniStrnlen((wchar_t *) data, words_left); 307 308 if (len >= words_left) 309 return rc; 310 311 kfree(ses->serverOS); 312 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 313 ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); 314 + if (ses->serverOS != NULL) { 315 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); 316 + cFYI(1, ("serverOS=%s", ses->serverOS)); 317 + } 318 data += 2 * (len + 1); 319 words_left -= len + 1; 320 ··· 328 if (ses->serverNOS != NULL) { 329 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 330 nls_cp); 331 + cFYI(1, ("serverNOS=%s", ses->serverNOS)); 332 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) { 333 cFYI(1, ("NT4 server")); 334 ses->flags |= CIFS_SES_NT4; ··· 343 return rc; 344 345 kfree(ses->serverDomain); 346 + ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL); 347 if (ses->serverDomain != NULL) { 348 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 349 nls_cp); 350 + cFYI(1, ("serverDomain=%s", ses->serverDomain)); 351 } 352 data += 2 * (len + 1); 353 words_left -= len + 1; ··· 702 } 703 704 /* BB check if Unicode and decode strings */ 705 + if (smb_buf->Flags2 & SMBFLG2_UNICODE) { 706 + /* unicode string area must be word-aligned */ 707 + if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) { 708 + ++bcc_ptr; 709 + --bytes_remaining; 710 + } 711 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, 712 + ses, nls_cp); 713 + } else { 714 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, 715 ses, nls_cp); 716 + } 717 718 ssetup_exit: 719 if (spnego_key) {