Root/
1 | /* |
2 | * Copyright (c) 1997-2003 Erez Zadok |
3 | * Copyright (c) 2001-2003 Stony Brook University |
4 | * |
5 | * For specific licensing information, see the COPYING file distributed with |
6 | * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. |
7 | * |
8 | * This Copyright notice must be kept intact and distributed with all |
9 | * fistgen sources INCLUDING sources generated by fistgen. |
10 | */ |
11 | /* |
12 | * Copyright (C) 2004, 2005 Markus Klotzbuecher <mk@creamnet.de> |
13 | * |
14 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License |
16 | * as published by the Free Software Foundation; either version |
17 | * 2 of the License, or (at your option) any later version. |
18 | */ |
19 | |
20 | /* |
21 | * $Id$ |
22 | */ |
23 | |
24 | #ifdef HAVE_CONFIG_H |
25 | # include <config.h> |
26 | #endif |
27 | |
28 | #include "fist.h" |
29 | #include "mini_fo.h" |
30 | |
31 | /* |
32 | * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise. |
33 | */ |
34 | STATIC int |
35 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
36 | mini_fo_d_revalidate(dentry_t *dentry, struct nameidata *nd) |
37 | #else |
38 | mini_fo_d_revalidate(dentry_t *dentry, int flags) |
39 | #endif |
40 | { |
41 | int err1 = 1; /* valid = 1, invalid = 0 */ |
42 | int err2 = 1; |
43 | dentry_t *hidden_dentry; |
44 | dentry_t *hidden_sto_dentry; |
45 | |
46 | |
47 | check_mini_fo_dentry(dentry); |
48 | |
49 | hidden_dentry = dtohd(dentry); |
50 | hidden_sto_dentry = dtohd2(dentry); |
51 | |
52 | if(hidden_dentry && |
53 | hidden_dentry->d_op && |
54 | hidden_dentry->d_op->d_revalidate) { |
55 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
56 | err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, nd); |
57 | #else |
58 | err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, flags); |
59 | #endif |
60 | } |
61 | if(hidden_sto_dentry && |
62 | hidden_sto_dentry->d_op && |
63 | hidden_sto_dentry->d_op->d_revalidate) { |
64 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
65 | err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, |
66 | nd); |
67 | #else |
68 | err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, |
69 | flags); |
70 | #endif |
71 | } |
72 | |
73 | /* mk: if one of the lower level dentries are valid, |
74 | * the mini_fo dentry is too. |
75 | */ |
76 | return (err1 || err2); |
77 | } |
78 | |
79 | |
80 | STATIC int |
81 | mini_fo_d_hash(dentry_t *dentry, qstr_t *name) |
82 | { |
83 | int err = 0; |
84 | dentry_t *hidden_dentry; |
85 | dentry_t *hidden_sto_dentry; |
86 | |
87 | /* hidden_dentry = mini_fo_hidden_dentry(dentry); |
88 | * hidden_sto_dentry = mini_fo_hidden_sto_dentry(dentry); */ |
89 | |
90 | /* state 1, 3, 4, 5: build the hash for the storage dentry */ |
91 | if((dtopd(dentry)->state == MODIFIED) || |
92 | (dtopd(dentry)->state == CREATED) || |
93 | (dtopd(dentry)->state == DEL_REWRITTEN) || |
94 | (dtopd(dentry)->state == DELETED)) { |
95 | hidden_sto_dentry = dtohd2(dentry); |
96 | if(hidden_sto_dentry && |
97 | hidden_sto_dentry->d_op && |
98 | hidden_sto_dentry->d_op->d_hash) { |
99 | err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name); |
100 | } |
101 | goto out; |
102 | } |
103 | /* state 2: build the hash for the base dentry */ |
104 | if(dtopd(dentry)->state == UNMODIFIED) { |
105 | hidden_dentry = dtohd(dentry); |
106 | if(hidden_dentry && |
107 | hidden_dentry->d_op && |
108 | hidden_dentry->d_op->d_hash) { |
109 | err = hidden_dentry->d_op->d_hash(hidden_dentry, name); |
110 | } |
111 | goto out; |
112 | } |
113 | /* state 6: build hash for the dentry that exists */ |
114 | if(dtopd(dentry)->state == NON_EXISTANT) { |
115 | hidden_sto_dentry = dtohd2(dentry); |
116 | if(hidden_sto_dentry && |
117 | hidden_sto_dentry->d_op && |
118 | hidden_sto_dentry->d_op->d_hash) { |
119 | err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name); |
120 | goto out; |
121 | } |
122 | hidden_dentry = dtohd(dentry); |
123 | if(hidden_dentry && |
124 | hidden_dentry->d_op && |
125 | hidden_dentry->d_op->d_hash) { |
126 | err = hidden_dentry->d_op->d_hash(hidden_dentry, name); |
127 | goto out; |
128 | } |
129 | } |
130 | |
131 | printk(KERN_CRIT "mini_fo: d_hash: invalid state detected.\n"); |
132 | |
133 | out: |
134 | return err; |
135 | } |
136 | |
137 | |
138 | STATIC int |
139 | mini_fo_d_compare(dentry_t *dentry, qstr_t *a, qstr_t *b) |
140 | { |
141 | int err; |
142 | dentry_t *hidden_dentry=NULL; |
143 | |
144 | /* hidden_dentry = mini_fo_hidden_dentry(dentry); */ |
145 | if(dtohd2(dentry)) |
146 | hidden_dentry = dtohd2(dentry); |
147 | else if(dtohd(dentry)) |
148 | hidden_dentry = dtohd(dentry); |
149 | |
150 | if (hidden_dentry && hidden_dentry->d_op && hidden_dentry->d_op->d_compare) { |
151 | err = hidden_dentry->d_op->d_compare(hidden_dentry, a, b); |
152 | } else { |
153 | err = ((a->len != b->len) || memcmp(a->name, b->name, b->len)); |
154 | } |
155 | |
156 | return err; |
157 | } |
158 | |
159 | |
160 | int |
161 | mini_fo_d_delete(dentry_t *dentry) |
162 | { |
163 | dentry_t *hidden_dentry; |
164 | dentry_t *hidden_sto_dentry; |
165 | int err = 0; |
166 | |
167 | /* this could be a negative dentry, so check first */ |
168 | if (!dtopd(dentry)) { |
169 | printk(KERN_CRIT "mini_fo_d_delete: negative dentry passed.\n"); |
170 | goto out; |
171 | } |
172 | hidden_dentry = dtohd(dentry); |
173 | hidden_sto_dentry = dtohd2(dentry); |
174 | |
175 | if(hidden_dentry) { |
176 | if(hidden_dentry->d_op && |
177 | hidden_dentry->d_op->d_delete) { |
178 | err = hidden_dentry->d_op->d_delete(hidden_dentry); |
179 | } |
180 | } |
181 | if(hidden_sto_dentry) { |
182 | if(hidden_sto_dentry->d_op && |
183 | hidden_sto_dentry->d_op->d_delete) { |
184 | err = hidden_sto_dentry->d_op->d_delete(hidden_sto_dentry); |
185 | } |
186 | } |
187 | |
188 | out: |
189 | return err; |
190 | } |
191 | |
192 | |
193 | void |
194 | mini_fo_d_release(dentry_t *dentry) |
195 | { |
196 | dentry_t *hidden_dentry; |
197 | dentry_t *hidden_sto_dentry; |
198 | |
199 | |
200 | /* this could be a negative dentry, so check first */ |
201 | if (!dtopd(dentry)) { |
202 | printk(KERN_CRIT "mini_fo_d_release: no private data.\n"); |
203 | goto out; |
204 | } |
205 | hidden_dentry = dtohd(dentry); |
206 | hidden_sto_dentry = dtohd2(dentry); |
207 | |
208 | if(hidden_dentry) { |
209 | /* decrement hidden dentry's counter and free its inode */ |
210 | dput(hidden_dentry); |
211 | } |
212 | if(hidden_sto_dentry) { |
213 | /* decrement hidden dentry's counter and free its inode */ |
214 | dput(hidden_sto_dentry); |
215 | } |
216 | |
217 | /* free private data (mini_fo_dentry_info) here */ |
218 | kfree(dtopd(dentry)); |
219 | __dtopd(dentry) = NULL; /* just to be safe */ |
220 | out: |
221 | return; |
222 | } |
223 | |
224 | |
225 | /* |
226 | * we don't really need mini_fo_d_iput, because dentry_iput will call iput() if |
227 | * mini_fo_d_iput is not defined. We left this implemented for ease of |
228 | * tracing/debugging. |
229 | */ |
230 | void |
231 | mini_fo_d_iput(dentry_t *dentry, inode_t *inode) |
232 | { |
233 | iput(inode); |
234 | } |
235 | |
236 | |
237 | struct dentry_operations mini_fo_dops = { |
238 | d_revalidate: mini_fo_d_revalidate, |
239 | d_hash: mini_fo_d_hash, |
240 | d_compare: mini_fo_d_compare, |
241 | d_release: mini_fo_d_release, |
242 | d_delete: mini_fo_d_delete, |
243 | d_iput: mini_fo_d_iput, |
244 | }; |
245 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9