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

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
[CIFS] Fix mem leak on dfs referral
[CIFS] file create with acl support enabled is slow
[CIFS] Fix mtime on cp -p when file data cached but written out too late
[CIFS] Fix build problem
[CIFS] cifs: replace remaining __FUNCTION__ occurrences
[CIFS] DFS patch that connects inode with dfs handling ops

+130 -102
+9 -9
fs/cifs/cifs_dfs_ref.c
··· 74 74 pSep = memchr(UNC+2, '\\', len-2); 75 75 if (!pSep) { 76 76 cERROR(1, ("%s: no server name end in node name: %s", 77 - __FUNCTION__, node_name)); 77 + __func__, node_name)); 78 78 kfree(UNC); 79 79 return NULL; 80 80 } ··· 84 84 pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); 85 85 if (!pSep) { 86 86 cERROR(1, ("%s:2 cant find share name in node name: %s", 87 - __FUNCTION__, node_name)); 87 + __func__, node_name)); 88 88 kfree(UNC); 89 89 return NULL; 90 90 } ··· 127 127 rc = dns_resolve_server_name_to_ip(*devname, &srvIP); 128 128 if (rc != 0) { 129 129 cERROR(1, ("%s: Failed to resolve server part of %s to IP", 130 - __FUNCTION__, *devname)); 130 + __func__, *devname)); 131 131 mountdata = ERR_PTR(rc); 132 132 goto compose_mount_options_out; 133 133 } ··· 181 181 } 182 182 } 183 183 184 - /*cFYI(1,("%s: parent mountdata: %s", __FUNCTION__,sb_mountdata));*/ 185 - /*cFYI(1, ("%s: submount mountdata: %s", __FUNCTION__, mountdata ));*/ 184 + /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ 185 + /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/ 186 186 187 187 compose_mount_options_out: 188 188 kfree(srvIP); ··· 302 302 int rc = 0; 303 303 struct vfsmount *mnt = ERR_PTR(-ENOENT); 304 304 305 - cFYI(1, ("in %s", __FUNCTION__)); 305 + cFYI(1, ("in %s", __func__)); 306 306 BUG_ON(IS_ROOT(dentry)); 307 307 308 308 xid = GetXid(); ··· 336 336 len = strlen(referrals[i].node_name); 337 337 if (len < 2) { 338 338 cERROR(1, ("%s: Net Address path too short: %s", 339 - __FUNCTION__, referrals[i].node_name)); 339 + __func__, referrals[i].node_name)); 340 340 rc = -EINVAL; 341 341 goto out_err; 342 342 } ··· 344 344 nd->path.dentry, 345 345 referrals[i].node_name); 346 346 cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", 347 - __FUNCTION__, 347 + __func__, 348 348 referrals[i].node_name, mnt)); 349 349 350 350 /* complete mount procedure if we accured submount */ ··· 365 365 FreeXid(xid); 366 366 free_dfs_info_array(referrals, num_referrals); 367 367 kfree(full_path); 368 - cFYI(1, ("leaving %s" , __FUNCTION__)); 368 + cFYI(1, ("leaving %s" , __func__)); 369 369 return ERR_PTR(rc); 370 370 out_err: 371 371 path_put(&nd->path);
+15 -10
fs/cifs/cifsacl.c
··· 1 1 /* 2 2 * fs/cifs/cifsacl.c 3 3 * 4 - * Copyright (C) International Business Machines Corp., 2007 4 + * Copyright (C) International Business Machines Corp., 2007,2008 5 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * Contains the routines for mapping CIFS/NTFS ACLs ··· 556 556 557 557 /* Retrieve an ACL from the server */ 558 558 static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, 559 - const char *path) 559 + const char *path, const __u16 *pfid) 560 560 { 561 - struct cifsFileInfo *open_file; 561 + struct cifsFileInfo *open_file = NULL; 562 562 int unlock_file = FALSE; 563 563 int xid; 564 564 int rc = -EIO; ··· 573 573 return NULL; 574 574 575 575 xid = GetXid(); 576 - open_file = find_readable_file(CIFS_I(inode)); 576 + if (pfid == NULL) 577 + open_file = find_readable_file(CIFS_I(inode)); 578 + else 579 + fid = *pfid; 580 + 577 581 sb = inode->i_sb; 578 582 if (sb == NULL) { 579 583 FreeXid(xid); ··· 588 584 if (open_file) { 589 585 unlock_file = TRUE; 590 586 fid = open_file->netfid; 591 - } else { 587 + } else if (pfid == NULL) { 592 588 int oplock = FALSE; 593 589 /* open file */ 594 590 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, ··· 604 600 605 601 rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); 606 602 cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); 607 - if (unlock_file == TRUE) 603 + if (unlock_file == TRUE) /* find_readable_file increments ref count */ 608 604 atomic_dec(&open_file->wrtPending); 609 - else 605 + else if (pfid == NULL) /* if opened above we have to close the handle */ 610 606 CIFSSMBClose(xid, cifs_sb->tcon, fid); 607 + /* else handle was passed in by caller */ 611 608 612 609 FreeXid(xid); 613 610 return pntsd; ··· 669 664 } 670 665 671 666 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ 672 - void acl_to_uid_mode(struct inode *inode, const char *path) 667 + void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) 673 668 { 674 669 struct cifs_ntsd *pntsd = NULL; 675 670 u32 acllen = 0; 676 671 int rc = 0; 677 672 678 673 cFYI(DBG2, ("converting ACL to mode for %s", path)); 679 - pntsd = get_cifs_acl(&acllen, inode, path); 674 + pntsd = get_cifs_acl(&acllen, inode, path, pfid); 680 675 681 676 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ 682 677 if (pntsd) ··· 699 694 cFYI(DBG2, ("set ACL from mode for %s", path)); 700 695 701 696 /* Get the security descriptor */ 702 - pntsd = get_cifs_acl(&acllen, inode, path); 697 + pntsd = get_cifs_acl(&acllen, inode, path, NULL); 703 698 704 699 /* Add three ACEs for owner, group, everyone getting rid of 705 700 other ACEs as chmod disables ACEs and set the security descriptor */
+5 -4
fs/cifs/cifsproto.h
··· 39 39 unsigned int /* length */ , struct sockaddr *); 40 40 extern unsigned int _GetXid(void); 41 41 extern void _FreeXid(unsigned int); 42 - #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); 43 - #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));} 42 + #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid)); 43 + #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} 44 44 extern char *build_path_from_dentry(struct dentry *); 45 45 extern char *build_wildcard_path_from_dentry(struct dentry *direntry); 46 46 /* extern void renew_parental_timestamps(struct dentry *direntry);*/ ··· 92 92 extern int cifs_get_inode_info(struct inode **pinode, 93 93 const unsigned char *search_path, 94 94 FILE_ALL_INFO * pfile_info, 95 - struct super_block *sb, int xid); 95 + struct super_block *sb, int xid, const __u16 *pfid); 96 96 extern int cifs_get_inode_info_unix(struct inode **pinode, 97 97 const unsigned char *search_path, 98 98 struct super_block *sb, int xid); 99 - extern void acl_to_uid_mode(struct inode *inode, const char *search_path); 99 + extern void acl_to_uid_mode(struct inode *inode, const char *path, 100 + const __u16 *pfid); 100 101 extern int mode_to_acl(struct inode *inode, const char *path, __u64); 101 102 102 103 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
+3 -2
fs/cifs/dir.c
··· 229 229 inode->i_sb, xid); 230 230 else { 231 231 rc = cifs_get_inode_info(&newinode, full_path, 232 - buf, inode->i_sb, xid); 232 + buf, inode->i_sb, xid, 233 + &fileHandle); 233 234 if (newinode) { 234 235 newinode->i_mode = mode; 235 236 if ((oplock & CIFS_CREATE_ACTION) && ··· 484 483 parent_dir_inode->i_sb, xid); 485 484 else 486 485 rc = cifs_get_inode_info(&newInode, full_path, NULL, 487 - parent_dir_inode->i_sb, xid); 486 + parent_dir_inode->i_sb, xid, NULL); 488 487 489 488 if ((rc == 0) && (newInode != NULL)) { 490 489 if (pTcon->nocase)
+4 -4
fs/cifs/dns_resolve.c
··· 77 77 /* search for server name delimiter */ 78 78 len = strlen(unc); 79 79 if (len < 3) { 80 - cFYI(1, ("%s: unc is too short: %s", __FUNCTION__, unc)); 80 + cFYI(1, ("%s: unc is too short: %s", __func__, unc)); 81 81 return -EINVAL; 82 82 } 83 83 len -= 2; 84 84 name = memchr(unc+2, '\\', len); 85 85 if (!name) { 86 86 cFYI(1, ("%s: probably server name is whole unc: %s", 87 - __FUNCTION__, unc)); 87 + __func__, unc)); 88 88 } else { 89 89 len = (name - unc) - 2/* leading // */; 90 90 } ··· 104 104 if (*ip_addr) { 105 105 memcpy(*ip_addr, rkey->payload.data, len); 106 106 (*ip_addr)[len] = '\0'; 107 - cFYI(1, ("%s: resolved: %s to %s", __FUNCTION__, 107 + cFYI(1, ("%s: resolved: %s to %s", __func__, 108 108 rkey->description, 109 109 *ip_addr 110 110 )); ··· 114 114 } 115 115 key_put(rkey); 116 116 } else { 117 - cERROR(1, ("%s: unable to resolve: %s", __FUNCTION__, name)); 117 + cERROR(1, ("%s: unable to resolve: %s", __func__, name)); 118 118 } 119 119 120 120 kfree(name);
+2 -2
fs/cifs/file.c
··· 145 145 full_path, inode->i_sb, xid); 146 146 else 147 147 rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, 148 - full_path, buf, inode->i_sb, xid); 148 + full_path, buf, inode->i_sb, xid, NULL); 149 149 150 150 if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { 151 151 pCifsInode->clientCanCacheAll = TRUE; ··· 440 440 else 441 441 rc = cifs_get_inode_info(&inode, 442 442 full_path, NULL, inode->i_sb, 443 - xid); 443 + xid, NULL); 444 444 } /* else we are writing out data to server already 445 445 and could deadlock if we tried to flush data, and 446 446 since we do not know if we have data that would
+91 -70
fs/cifs/inode.c
··· 30 30 #include "cifs_fs_sb.h" 31 31 32 32 33 - static void cifs_set_ops(struct inode *inode) 33 + static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) 34 34 { 35 35 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 36 36 ··· 57 57 inode->i_data.a_ops = &cifs_addr_ops; 58 58 break; 59 59 case S_IFDIR: 60 - inode->i_op = &cifs_dir_inode_ops; 61 - inode->i_fop = &cifs_dir_ops; 60 + #ifdef CONFIG_CIFS_DFS_UPCALL 61 + if (is_dfs_referral) { 62 + inode->i_op = &cifs_dfs_referral_inode_operations; 63 + } else { 64 + #else /* NO DFS support, treat as a directory */ 65 + { 66 + #endif 67 + inode->i_op = &cifs_dir_inode_ops; 68 + inode->i_fop = &cifs_dir_ops; 69 + } 62 70 break; 63 71 case S_IFLNK: 64 72 inode->i_op = &cifs_symlink_inode_ops; ··· 161 153 spin_unlock(&inode->i_lock); 162 154 } 163 155 156 + static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon, 157 + const char *search_path) 158 + { 159 + int tree_len; 160 + int path_len; 161 + char *tmp_path; 162 + 163 + if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS)) 164 + return search_path; 165 + 166 + /* use full path name for working with DFS */ 167 + tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1); 168 + path_len = strnlen(search_path, MAX_PATHCONF); 169 + 170 + tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL); 171 + if (tmp_path == NULL) 172 + return search_path; 173 + 174 + strncpy(tmp_path, pTcon->treeName, tree_len); 175 + strncpy(tmp_path+tree_len, search_path, path_len); 176 + tmp_path[tree_len+path_len] = 0; 177 + return tmp_path; 178 + } 179 + 164 180 int cifs_get_inode_info_unix(struct inode **pinode, 165 181 const unsigned char *search_path, struct super_block *sb, int xid) 166 182 { ··· 193 161 struct cifsTconInfo *pTcon; 194 162 struct inode *inode; 195 163 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 196 - char *tmp_path; 164 + const unsigned char *full_path; 165 + bool is_dfs_referral = false; 197 166 198 167 pTcon = cifs_sb->tcon; 199 168 cFYI(1, ("Getting info on %s", search_path)); 169 + 170 + full_path = cifs_get_search_path(pTcon, search_path); 171 + 172 + try_again_CIFSSMBUnixQPathInfo: 200 173 /* could have done a find first instead but this returns more info */ 201 - rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 174 + rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData, 202 175 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 203 176 CIFS_MOUNT_MAP_SPECIAL_CHR); 204 177 /* dump_mem("\nUnixQPathInfo return data", &findData, 205 178 sizeof(findData)); */ 206 179 if (rc) { 207 - if (rc == -EREMOTE) { 208 - tmp_path = 209 - kmalloc(strnlen(pTcon->treeName, 210 - MAX_TREE_SIZE + 1) + 211 - strnlen(search_path, MAX_PATHCONF) + 1, 212 - GFP_KERNEL); 213 - if (tmp_path == NULL) 214 - return -ENOMEM; 215 - 216 - /* have to skip first of the double backslash of 217 - UNC name */ 218 - strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); 219 - strncat(tmp_path, search_path, MAX_PATHCONF); 220 - rc = connect_to_dfs_path(xid, pTcon->ses, 221 - /* treename + */ tmp_path, 222 - cifs_sb->local_nls, 223 - cifs_sb->mnt_cifs_flags & 224 - CIFS_MOUNT_MAP_SPECIAL_CHR); 225 - kfree(tmp_path); 226 - 227 - /* BB fix up inode etc. */ 228 - } else if (rc) { 229 - return rc; 180 + if (rc == -EREMOTE && !is_dfs_referral) { 181 + is_dfs_referral = true; 182 + if (full_path != search_path) { 183 + kfree(full_path); 184 + full_path = search_path; 185 + } 186 + goto try_again_CIFSSMBUnixQPathInfo; 230 187 } 188 + goto cgiiu_exit; 231 189 } else { 232 190 struct cifsInodeInfo *cifsInfo; 233 191 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes); ··· 226 204 /* get new inode */ 227 205 if (*pinode == NULL) { 228 206 *pinode = new_inode(sb); 229 - if (*pinode == NULL) 230 - return -ENOMEM; 207 + if (*pinode == NULL) { 208 + rc = -ENOMEM; 209 + goto cgiiu_exit; 210 + } 231 211 /* Is an i_ino of zero legal? */ 232 212 /* Are there sanity checks we can use to ensure that 233 213 the server is really filling in that field? */ ··· 261 237 (unsigned long) inode->i_size, 262 238 (unsigned long long)inode->i_blocks)); 263 239 264 - cifs_set_ops(inode); 240 + cifs_set_ops(inode, is_dfs_referral); 265 241 } 242 + cgiiu_exit: 243 + if (full_path != search_path) 244 + kfree(full_path); 266 245 return rc; 267 246 } 268 247 ··· 374 347 375 348 int cifs_get_inode_info(struct inode **pinode, 376 349 const unsigned char *search_path, FILE_ALL_INFO *pfindData, 377 - struct super_block *sb, int xid) 350 + struct super_block *sb, int xid, const __u16 *pfid) 378 351 { 379 352 int rc = 0; 380 353 struct cifsTconInfo *pTcon; 381 354 struct inode *inode; 382 355 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 383 - char *tmp_path; 356 + const unsigned char *full_path = NULL; 384 357 char *buf = NULL; 385 358 int adjustTZ = FALSE; 359 + bool is_dfs_referral = false; 386 360 387 361 pTcon = cifs_sb->tcon; 388 362 cFYI(1, ("Getting info on %s", search_path)); ··· 401 373 if (buf == NULL) 402 374 return -ENOMEM; 403 375 pfindData = (FILE_ALL_INFO *)buf; 376 + 377 + full_path = cifs_get_search_path(pTcon, search_path); 378 + 379 + try_again_CIFSSMBQPathInfo: 404 380 /* could do find first instead but this returns more info */ 405 - rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 381 + rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, 406 382 0 /* not legacy */, 407 383 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 408 384 CIFS_MOUNT_MAP_SPECIAL_CHR); ··· 414 382 when server claims no NT SMB support and the above call 415 383 failed at least once - set flag in tcon or mount */ 416 384 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { 417 - rc = SMBQueryInformation(xid, pTcon, search_path, 385 + rc = SMBQueryInformation(xid, pTcon, full_path, 418 386 pfindData, cifs_sb->local_nls, 419 387 cifs_sb->mnt_cifs_flags & 420 388 CIFS_MOUNT_MAP_SPECIAL_CHR); ··· 423 391 } 424 392 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 425 393 if (rc) { 426 - if (rc == -EREMOTE) { 427 - tmp_path = 428 - kmalloc(strnlen 429 - (pTcon->treeName, 430 - MAX_TREE_SIZE + 1) + 431 - strnlen(search_path, MAX_PATHCONF) + 1, 432 - GFP_KERNEL); 433 - if (tmp_path == NULL) { 434 - kfree(buf); 435 - return -ENOMEM; 394 + if (rc == -EREMOTE && !is_dfs_referral) { 395 + is_dfs_referral = true; 396 + if (full_path != search_path) { 397 + kfree(full_path); 398 + full_path = search_path; 436 399 } 437 - 438 - strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); 439 - strncat(tmp_path, search_path, MAX_PATHCONF); 440 - rc = connect_to_dfs_path(xid, pTcon->ses, 441 - /* treename + */ tmp_path, 442 - cifs_sb->local_nls, 443 - cifs_sb->mnt_cifs_flags & 444 - CIFS_MOUNT_MAP_SPECIAL_CHR); 445 - kfree(tmp_path); 446 - /* BB fix up inode etc. */ 447 - } else if (rc) { 448 - kfree(buf); 449 - return rc; 400 + goto try_again_CIFSSMBQPathInfo; 450 401 } 402 + goto cgii_exit; 451 403 } else { 452 404 struct cifsInodeInfo *cifsInfo; 453 405 __u32 attr = le32_to_cpu(pfindData->Attributes); ··· 440 424 if (*pinode == NULL) { 441 425 *pinode = new_inode(sb); 442 426 if (*pinode == NULL) { 443 - kfree(buf); 444 - return -ENOMEM; 427 + rc = -ENOMEM; 428 + goto cgii_exit; 445 429 } 446 430 /* Is an i_ino of zero legal? Can we use that to check 447 431 if the server supports returning inode numbers? Are ··· 575 559 /* fill in 0777 bits from ACL */ 576 560 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 577 561 cFYI(1, ("Getting mode bits from ACL")); 578 - acl_to_uid_mode(inode, search_path); 562 + acl_to_uid_mode(inode, search_path, pfid); 579 563 } 580 564 #endif 581 565 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { ··· 589 573 atomic_set(&cifsInfo->inUse, 1); 590 574 } 591 575 592 - cifs_set_ops(inode); 576 + cifs_set_ops(inode, is_dfs_referral); 593 577 } 578 + cgii_exit: 579 + if (full_path != search_path) 580 + kfree(full_path); 594 581 kfree(buf); 595 582 return rc; 596 583 } ··· 622 603 if (cifs_sb->tcon->unix_ext) 623 604 rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); 624 605 else 625 - rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); 606 + rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid, 607 + NULL); 626 608 if (rc && cifs_sb->tcon->ipc) { 627 609 cFYI(1, ("ipc connection - fake read inode")); 628 610 inode->i_mode |= S_IFDIR; ··· 824 804 local_size = tmp_inode->i_size; 825 805 826 806 cifs_unix_info_to_inode(tmp_inode, pData, 1); 827 - cifs_set_ops(tmp_inode); 807 + cifs_set_ops(tmp_inode, false); 828 808 829 809 if (!S_ISREG(tmp_inode->i_mode)) 830 810 return; ··· 956 936 inode->i_sb, xid); 957 937 else 958 938 rc = cifs_get_inode_info(&newinode, full_path, NULL, 959 - inode->i_sb, xid); 939 + inode->i_sb, xid, NULL); 960 940 961 941 if (pTcon->nocase) 962 942 direntry->d_op = &cifs_ci_dentry_ops; ··· 1238 1218 } 1239 1219 } else { 1240 1220 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, 1241 - direntry->d_sb, xid); 1221 + direntry->d_sb, xid, NULL); 1242 1222 if (rc) { 1243 1223 cFYI(1, ("error on getting revalidate info %d", rc)); 1244 1224 /* if (rc != -ENOENT) ··· 1427 1407 } 1428 1408 cifsInode = CIFS_I(direntry->d_inode); 1429 1409 1430 - /* BB check if we need to refresh inode from server now ? BB */ 1431 - 1432 - if (attrs->ia_valid & ATTR_SIZE) { 1410 + if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) { 1433 1411 /* 1434 - Flush data before changing file size on server. If the 1412 + Flush data before changing file size or changing the last 1413 + write time of the file on the server. If the 1435 1414 flush returns error, store it to report later and continue. 1436 1415 BB: This should be smarter. Why bother flushing pages that 1437 1416 will be truncated anyway? Also, should we error out here if ··· 1441 1422 CIFS_I(direntry->d_inode)->write_behind_rc = rc; 1442 1423 rc = 0; 1443 1424 } 1425 + } 1444 1426 1427 + if (attrs->ia_valid & ATTR_SIZE) { 1445 1428 /* To avoid spurious oplock breaks from server, in the case of 1446 1429 inodes that we already have open, avoid doing path based 1447 1430 setting of file size if we can do it by handle.
+1 -1
fs/cifs/link.c
··· 205 205 inode->i_sb, xid); 206 206 else 207 207 rc = cifs_get_inode_info(&newinode, full_path, NULL, 208 - inode->i_sb, xid); 208 + inode->i_sb, xid, NULL); 209 209 210 210 if (rc != 0) { 211 211 cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d",