diff options
author | Nick Piggin <npiggin@kernel.dk> | 2010-11-11 02:42:16 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-01-06 14:07:52 -0500 |
commit | 262f86adcc0665872812a7458a5d03e19e0efe33 (patch) | |
tree | 3e54502cfec37e9d86f9e92b40d9bc6d25669b16 | |
parent | 3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 (diff) |
cifs: don't overwrite dentry name in d_revalidate
Instead, use fatfs'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>
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r-- | fs/cifs/dir.c | 43 |
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: | |||
656 | static int | 656 | static int |
657 | cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | 657 | cifs_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 | ||