[CIFS] When file is deleted locally but later recreated on the server fix cifs negative dentries so they are freed faster (not requiring umount or readdir e.g.) so the client recognizes the new file on the server more quickly.

Signed-off-by: Steve French <sfrench@us.ibm.com>

+35 -20
+5 -3
fs/cifs/CHANGES
··· 1 Version 1.39 2 ------------ 3 - Defer close of a file handle slightly if pending writes depend on that file handle 4 (this reduces the EBADF bad file handle errors that can be logged under heavy 5 stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 6 - Fix SFU style symlinks and mknod needed for servers which do not support the CIFS 7 - Unix Extensions. Fix setfacl/getfacl on bigendian. 8 9 Version 1.38 10 ------------
··· 1 Version 1.39 2 ------------ 3 + Defer close of a file handle slightly if pending writes depend on that handle 4 (this reduces the EBADF bad file handle errors that can be logged under heavy 5 stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 6 + Fix SFU style symlinks and mknod needed for servers which do not support the 7 + CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative 8 + dentries so files that the client sees as deleted but that later get created 9 + on the server will be recognized. 10 11 Version 1.38 12 ------------
+16 -9
fs/cifs/dir.c
··· 465 direntry->d_op = &cifs_dentry_ops; 466 d_add(direntry, newInode); 467 468 - /* since paths are not looked up by component - the parent directories are presumed to be good here */ 469 renew_parental_timestamps(direntry); 470 471 } else if (rc == -ENOENT) { 472 rc = 0; 473 d_add(direntry, NULL); 474 } else { 475 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", 476 rc,full_path)); ··· 497 { 498 int isValid = 1; 499 500 - /* lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */ 501 - 502 if (direntry->d_inode) { 503 if (cifs_revalidate(direntry)) { 504 - /* unlock_kernel(); */ 505 return 0; 506 } 507 } else { 508 - cFYI(1, 509 - ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p", 510 - direntry->d_name.name, direntry)); 511 } 512 - 513 - /* unlock_kernel(); */ 514 515 return isValid; 516 }
··· 465 direntry->d_op = &cifs_dentry_ops; 466 d_add(direntry, newInode); 467 468 + /* since paths are not looked up by component - the parent 469 + directories are presumed to be good here */ 470 renew_parental_timestamps(direntry); 471 472 } else if (rc == -ENOENT) { 473 rc = 0; 474 + direntry->d_time = jiffies; 475 + if (pTcon->nocase) 476 + direntry->d_op = &cifs_ci_dentry_ops; 477 + else 478 + direntry->d_op = &cifs_dentry_ops; 479 d_add(direntry, NULL); 480 + /* if it was once a directory (but how can we tell?) we could do 481 + shrink_dcache_parent(direntry); */ 482 } else { 483 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", 484 rc,full_path)); ··· 489 { 490 int isValid = 1; 491 492 if (direntry->d_inode) { 493 if (cifs_revalidate(direntry)) { 494 return 0; 495 } 496 } else { 497 + cFYI(1, ("neg dentry 0x%p name = %s", 498 + direntry, direntry->d_name.name)); 499 + if(time_after(jiffies, direntry->d_time + HZ) || 500 + !lookupCacheEnabled) { 501 + d_drop(direntry); 502 + isValid = 0; 503 + } 504 } 505 506 return isValid; 507 }
+14 -8
fs/cifs/inode.c
··· 1039 filemap_fdatawrite(direntry->d_inode->i_mapping); 1040 } 1041 if (invalidate_inode) { 1042 - if (direntry->d_inode->i_mapping) 1043 - filemap_fdatawait(direntry->d_inode->i_mapping); 1044 - /* may eventually have to do this for open files too */ 1045 - if (list_empty(&(cifsInode->openFileList))) { 1046 - /* Has changed on server - flush read ahead pages */ 1047 - cFYI(1, ("Invalidating read ahead data on " 1048 - "closed file")); 1049 - invalidate_remote_inode(direntry->d_inode); 1050 } 1051 } 1052 /* up(&direntry->d_inode->i_sem); */
··· 1039 filemap_fdatawrite(direntry->d_inode->i_mapping); 1040 } 1041 if (invalidate_inode) { 1042 + /* shrink_dcache not necessary now that cifs dentry ops 1043 + are exported for negative dentries */ 1044 + /* if(S_ISDIR(direntry->d_inode->i_mode)) 1045 + shrink_dcache_parent(direntry); */ 1046 + if (S_ISREG(direntry->d_inode->i_mode)) { 1047 + if (direntry->d_inode->i_mapping) 1048 + filemap_fdatawait(direntry->d_inode->i_mapping); 1049 + /* may eventually have to do this for open files too */ 1050 + if (list_empty(&(cifsInode->openFileList))) { 1051 + /* changed on server - flush read ahead pages */ 1052 + cFYI(1, ("Invalidating read ahead data on " 1053 + "closed file")); 1054 + invalidate_remote_inode(direntry->d_inode); 1055 + } 1056 } 1057 } 1058 /* up(&direntry->d_inode->i_sem); */