aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:24 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:18 -0500
commit79eb4dde742fe2e9c9e301432b894a7410261ce7 (patch)
tree89150e92450fd10f7bd55348459d9f36be544ec0 /fs/cifs
parentfe15ce446beb3a33583af81ffe6c9d01a75314ed (diff)
cifs: dont overwrite dentry name in d_revalidate
Use vfat's method for dealing with negative dentries to preserve case, rather than overwrite dentry name in d_revalidate, which is a bit ugly and also gets in the way of doing lock-free path walking. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/dir.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 3840eddbfb7a..521d841b1fd1 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -656,22 +656,34 @@ lookup_out:
656static int 656static int
657cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 657cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
658{ 658{
659 int isValid = 1;
660
661 if (direntry->d_inode) { 659 if (direntry->d_inode) {
662 if (cifs_revalidate_dentry(direntry)) 660 if (cifs_revalidate_dentry(direntry))
663 return 0; 661 return 0;
664 } else { 662 else
665 cFYI(1, "neg dentry 0x%p name = %s", 663 return 1;
666 direntry, direntry->d_name.name);
667 if (time_after(jiffies, direntry->d_time + HZ) ||
668 !lookupCacheEnabled) {
669 d_drop(direntry);
670 isValid = 0;
671 }
672 } 664 }
673 665
674 return isValid; 666 /*
667 * This may be nfsd (or something), anyway, we can't see the
668 * intent of this. So, since this can be for creation, drop it.
669 */
670 if (!nd)
671 return 0;
672
673 /*
674 * Drop the negative dentry, in order to make sure to use the
675 * case sensitive name which is specified by user if this is
676 * for creation.
677 */
678 if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
679 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
680 return 0;
681 }
682
683 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
684 return 0;
685
686 return 1;
675} 687}
676 688
677/* static int cifs_d_delete(struct dentry *direntry) 689/* static int cifs_d_delete(struct dentry *direntry)
@@ -709,15 +721,8 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
709 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; 721 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
710 722
711 if ((a->len == b->len) && 723 if ((a->len == b->len) &&
712 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) { 724 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0))
713 /*
714 * To preserve case, don't let an existing negative dentry's
715 * case take precedence. If a is not a negative dentry, this
716 * should have no side effects
717 */
718 memcpy((void *)a->name, b->name, a->len);
719 return 0; 725 return 0;
720 }
721 return 1; 726 return 1;
722} 727}
723 728