Skip to content

Commit 3abb927

Browse files
author
Steve French
committed
[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 <[email protected]>
1 parent 458af54 commit 3abb927

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

fs/cifs/CHANGES

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
Version 1.39
22
------------
3-
Defer close of a file handle slightly if pending writes depend on that file handle
3+
Defer close of a file handle slightly if pending writes depend on that handle
44
(this reduces the EBADF bad file handle errors that can be logged under heavy
55
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.
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.
810

911
Version 1.38
1012
------------

fs/cifs/dir.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -465,12 +465,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
465465
direntry->d_op = &cifs_dentry_ops;
466466
d_add(direntry, newInode);
467467

468-
/* since paths are not looked up by component - the parent directories are presumed to be good here */
468+
/* since paths are not looked up by component - the parent
469+
directories are presumed to be good here */
469470
renew_parental_timestamps(direntry);
470471

471472
} else if (rc == -ENOENT) {
472473
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;
473479
d_add(direntry, NULL);
480+
/* if it was once a directory (but how can we tell?) we could do
481+
shrink_dcache_parent(direntry); */
474482
} else {
475483
cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
476484
rc,full_path));
@@ -489,21 +497,20 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
489497
{
490498
int isValid = 1;
491499

492-
/* lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */
493-
494500
if (direntry->d_inode) {
495501
if (cifs_revalidate(direntry)) {
496-
/* unlock_kernel(); */
497502
return 0;
498503
}
499504
} else {
500-
cFYI(1,
501-
("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p",
502-
direntry->d_name.name, direntry));
505+
cFYI(1, ("neg dentry 0x%p name = %s",
506+
direntry, direntry->d_name.name));
507+
if(time_after(jiffies, direntry->d_time + HZ) ||
508+
!lookupCacheEnabled) {
509+
d_drop(direntry);
510+
isValid = 0;
511+
}
503512
}
504513

505-
/* unlock_kernel(); */
506-
507514
return isValid;
508515
}
509516

fs/cifs/inode.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,14 +1039,20 @@ int cifs_revalidate(struct dentry *direntry)
10391039
filemap_fdatawrite(direntry->d_inode->i_mapping);
10401040
}
10411041
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);
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+
}
10501056
}
10511057
}
10521058
/* up(&direntry->d_inode->i_sem); */

0 commit comments

Comments
 (0)