diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:27 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:19 -0500 |
commit | 621e155a3591962420eacdd39f6f0aa29ceb221e (patch) | |
tree | 387a9fb396f1bf24514b712c294182e36ba51076 /fs/ncpfs/dir.c | |
parent | fb2d5b86aff355a27ebfc132d3c99f4a940cc3fe (diff) |
fs: change d_compare for rcu-walk
Change d_compare so it may be called from lock-free RCU lookups. This
does put significant restrictions on what may be done from the callback,
however there don't seem to have been any problems with in-tree fses.
If some strange use case pops up that _really_ cannot cope with the
rcu-walk rules, we can just add new rcu-unaware callbacks, which would
cause name lookup to drop out of rcu-walk mode.
For in-tree filesystems, this is just a mechanical change.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/ncpfs/dir.c')
-rw-r--r-- | fs/ncpfs/dir.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index e80ea4e37c48..3bcc68aed416 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -75,7 +75,9 @@ const struct inode_operations ncp_dir_inode_operations = | |||
75 | */ | 75 | */ |
76 | static int ncp_lookup_validate(struct dentry *, struct nameidata *); | 76 | static int ncp_lookup_validate(struct dentry *, struct nameidata *); |
77 | static int ncp_hash_dentry(struct dentry *, struct qstr *); | 77 | static int ncp_hash_dentry(struct dentry *, struct qstr *); |
78 | static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); | 78 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, |
79 | const struct dentry *, const struct inode *, | ||
80 | unsigned int, const char *, const struct qstr *); | ||
79 | static int ncp_delete_dentry(const struct dentry *); | 81 | static int ncp_delete_dentry(const struct dentry *); |
80 | 82 | ||
81 | static const struct dentry_operations ncp_dentry_operations = | 83 | static const struct dentry_operations ncp_dentry_operations = |
@@ -113,10 +115,10 @@ static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator) | |||
113 | 115 | ||
114 | #define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS) | 116 | #define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS) |
115 | 117 | ||
116 | static inline int ncp_case_sensitive(struct dentry *dentry) | 118 | static inline int ncp_case_sensitive(const struct inode *i) |
117 | { | 119 | { |
118 | #ifdef CONFIG_NCPFS_NFS_NS | 120 | #ifdef CONFIG_NCPFS_NFS_NS |
119 | return ncp_namespace(dentry->d_inode) == NW_NS_NFS; | 121 | return ncp_namespace(i) == NW_NS_NFS; |
120 | #else | 122 | #else |
121 | return 0; | 123 | return 0; |
122 | #endif /* CONFIG_NCPFS_NFS_NS */ | 124 | #endif /* CONFIG_NCPFS_NFS_NS */ |
@@ -129,12 +131,13 @@ static inline int ncp_case_sensitive(struct dentry *dentry) | |||
129 | static int | 131 | static int |
130 | ncp_hash_dentry(struct dentry *dentry, struct qstr *this) | 132 | ncp_hash_dentry(struct dentry *dentry, struct qstr *this) |
131 | { | 133 | { |
132 | if (!ncp_case_sensitive(dentry)) { | 134 | if (!ncp_case_sensitive(dentry->d_inode)) { |
135 | struct super_block *sb = dentry->d_sb; | ||
133 | struct nls_table *t; | 136 | struct nls_table *t; |
134 | unsigned long hash; | 137 | unsigned long hash; |
135 | int i; | 138 | int i; |
136 | 139 | ||
137 | t = NCP_IO_TABLE(dentry); | 140 | t = NCP_IO_TABLE(sb); |
138 | hash = init_name_hash(); | 141 | hash = init_name_hash(); |
139 | for (i=0; i<this->len ; i++) | 142 | for (i=0; i<this->len ; i++) |
140 | hash = partial_name_hash(ncp_tolower(t, this->name[i]), | 143 | hash = partial_name_hash(ncp_tolower(t, this->name[i]), |
@@ -145,15 +148,17 @@ ncp_hash_dentry(struct dentry *dentry, struct qstr *this) | |||
145 | } | 148 | } |
146 | 149 | ||
147 | static int | 150 | static int |
148 | ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) | 151 | ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode, |
152 | const struct dentry *dentry, const struct inode *inode, | ||
153 | unsigned int len, const char *str, const struct qstr *name) | ||
149 | { | 154 | { |
150 | if (a->len != b->len) | 155 | if (len != name->len) |
151 | return 1; | 156 | return 1; |
152 | 157 | ||
153 | if (ncp_case_sensitive(dentry)) | 158 | if (ncp_case_sensitive(pinode)) |
154 | return strncmp(a->name, b->name, a->len); | 159 | return strncmp(str, name->name, len); |
155 | 160 | ||
156 | return ncp_strnicmp(NCP_IO_TABLE(dentry), a->name, b->name, a->len); | 161 | return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len); |
157 | } | 162 | } |
158 | 163 | ||
159 | /* | 164 | /* |