Commit 8d4ab5daca4b3bf9c9166908db0c436722d52e77

Authored by Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: 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

Showing 13 changed files Side-by-side Diff

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