root/morphix/trunk/mini_fo/dentry.c

Revision 2, 7.2 kB (checked in by nextime, 2 years ago)

Initial import, branching from morphix svn

Line 
1 /*
2  * Copyright (c) 1997-2004 Erez Zadok <ezk@cs.stonybrook.edu>
3  * Copyright (c) 2001-2004 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/fistgen/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 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: dentry.c 1364 2004-12-04 10:18:10Z alextreme $
22  */
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif /* HAVE_CONFIG_H */
27 #ifdef FISTGEN
28 # include "fist_mini_fo.h"
29 #endif /* FISTGEN */
30 #include "fist.h"
31 #include "mini_fo.h"
32
33 /* HL
34    d_revalidate: check for lower_dentry!=NULL
35
36
37 */
38
39 /*
40  * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise.
41  */
42 STATIC int
43 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
44 mini_fo_d_revalidate(dentry_t *dentry, struct nameidata *nd)
45 #else
46 mini_fo_d_revalidate(dentry_t *dentry, int flags)
47 #endif
48 {
49         int err         = 1; // default is valid (1); invalid is 0.
50         int err_sto = 1; // default is valid (1); invalid is 0.
51         dentry_t *lower_dentry;
52         dentry_t *lower_sto_dentry;
53
54         print_entry_location();
55
56         lower_dentry  = DENTRY_TO_LOWER(dentry); //mini_fo_lower_dentry(dentry); /* CPW: Moved to after print_entry_location */
57         lower_sto_dentry  = DENTRY_TO_LOWER_STO(dentry);   //mini_fo_lower_sto_dentry(dentry); /* CPW: Moved to after print_entry_location */
58
59         if (lower_dentry && lower_dentry->d_op && lower_dentry->d_op->d_revalidate)
60 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
61                 err = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
62 #else
63                 err = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
64 #endif
65
66         if (lower_sto_dentry && lower_sto_dentry->d_op && lower_sto_dentry->d_op->d_revalidate)
67 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
68                 err_sto = lower_sto_dentry->d_op->d_revalidate(lower_sto_dentry, nd);
69 #else
70                 err_sto = lower_sto_dentry->d_op->d_revalidate(lower_sto_dentry, flags);
71 #endif
72
73 out:
74         /* mk: if one of the lower level dentries are vaid,
75          * the mini_fo dentry is too.
76          */
77         err=(err || err_sto);
78         print_exit_status(err);
79         return (err);
80 }
81
82
83 STATIC int
84 mini_fo_d_hash(dentry_t *dentry, qstr_t *name)
85 {
86         int err = 0;
87         dentry_t *lower_dentry;
88         dentry_t *lower_sto_dentry;
89
90         print_entry_location();
91         /* lower_dentry = mini_fo_lower_dentry(dentry);
92          * lower_sto_dentry = mini_fo_lower_sto_dentry(dentry); */
93
94         /* state 1, 3, 5: build the hash for the storage dentry */
95         if ((DENTRY_TO_PRIVATE(dentry)->state == 1) ||
96                 (DENTRY_TO_PRIVATE(dentry)->state == 3) ||
97                 (DENTRY_TO_PRIVATE(dentry)->state == 5)) {
98                 lower_sto_dentry = mini_fo_lower_sto_dentry(dentry);
99                 if(lower_sto_dentry &&
100                    lower_sto_dentry->d_op &&
101                    lower_sto_dentry->d_op->d_hash) {
102                         err = lower_sto_dentry->d_op->d_hash(lower_sto_dentry, name);
103                 }
104                 goto out;
105         }
106         /* state 2 or 4: build the hash for the base dentry */
107         if((DENTRY_TO_PRIVATE(dentry)->state == 2) || (DENTRY_TO_PRIVATE(dentry)->state == 4)) {
108                 lower_dentry = mini_fo_lower_dentry(dentry);
109                 if(lower_dentry &&
110                    lower_dentry->d_op &&
111                    lower_dentry->d_op->d_hash) {
112                         err = lower_dentry->d_op->d_hash(lower_dentry, name);
113                 }
114                 goto out;
115         }
116         /* state 6: build hash for the dentry that exists */
117         if(DENTRY_TO_PRIVATE(dentry)->state == 6) {
118                 lower_sto_dentry = DENTRY_TO_LOWER_STO(dentry);
119                 if(lower_sto_dentry &&
120                    lower_sto_dentry->d_op &&
121                    lower_sto_dentry->d_op->d_hash) {
122                         err = lower_sto_dentry->d_op->d_hash(lower_sto_dentry, name);
123                         goto out;
124                 }
125                 lower_dentry = DENTRY_TO_LOWER(dentry);
126                 if(lower_dentry &&
127                    lower_dentry->d_op &&
128                    lower_dentry->d_op->d_hash) {
129                         err = lower_dentry->d_op->d_hash(lower_dentry, name);
130                         goto out;
131                 }
132         }
133
134         printk(KERN_CRIT "mini_fo: d_hash: invalid state detected.\n");
135
136  out:
137         print_exit_status(err);
138         return err;
139 }
140
141
142 STATIC int
143 mini_fo_d_compare(dentry_t *dentry, qstr_t *a, qstr_t *b)
144 {
145         int err;
146         dentry_t *lower_dentry;
147
148         print_entry_location();
149
150         //lower_dentry = mini_fo_lower_dentry(dentry);  /* CPW: Moved to after print_entry_location */
151         lower_dentry= DENTRY_TO_LOWER_STO(dentry);
152         if (!lower_dentry)
153                 lower_dentry= DENTRY_TO_LOWER(dentry);
154
155         if (lower_dentry && lower_dentry->d_op && lower_dentry->d_op->d_compare) {
156                 // XXX: WRONG: should encode_filename on a&b strings
157                 err = lower_dentry->d_op->d_compare(lower_dentry, a, b);
158         } else {
159                 err = ((a->len != b->len) || memcmp(a->name, b->name, b->len));
160         }
161
162         print_exit_status(err);
163         return err;
164 }
165
166
167 int
168 mini_fo_d_delete(dentry_t *dentry)
169 {
170
171         dentry_t *lower_dentry = 0;
172         dentry_t *lower_sto_dentry = 0;
173         int err = 0;
174
175         print_entry_location();
176
177
178     /* dentry can be NULL */
179     if (!dentry)
180         goto out;
181
182         /* this could be a negative dentry, so check first */
183         if (!DENTRY_TO_PRIVATE(dentry)) {
184                 fist_dprint(6, "dentry without private data: %*s", dentry->d_name.len, dentry->d_name.name);
185                 goto out;
186         }
187
188 /* mk: fan out (after) */
189         lower_dentry = DENTRY_TO_LOWER(dentry);
190         lower_sto_dentry = DENTRY_TO_LOWER_STO(dentry);
191
192         if(lower_dentry) {
193                 if(lower_dentry->d_op &&
194                    lower_dentry->d_op->d_delete) {
195                         err = lower_dentry->d_op->d_delete(lower_dentry);
196                 }
197         }
198         if(lower_sto_dentry) {
199                 if(lower_sto_dentry->d_op &&
200                    lower_sto_dentry->d_op->d_delete) {
201                         err = lower_sto_dentry->d_op->d_delete(lower_sto_dentry);
202                 }
203         }
204 out:
205         //fist_dprint(8, "exit d_delete\n");
206         print_exit_status(err);
207         return err;
208 }
209
210
211 void
212 mini_fo_d_release(dentry_t *dentry)
213 {
214         dentry_t *lower_dentry          =NULL;
215         dentry_t *lower_sto_dentry      =NULL;
216
217         print_entry_location();
218         fist_print_dentry("mini_fo_d_release IN dentry", dentry);
219
220         /* this could be a null dentry, so check first */
221         if (!dentry) {
222                 fist_dprint(6, "null dentry");
223                 goto out;
224         }
225         /* this could be a negative dentry, so check first */
226         if (!DENTRY_TO_PRIVATE(dentry)) {
227                 fist_dprint(6, "dentry without private data: %*s", dentry->d_name.len, dentry->d_name.name);
228                 goto out;
229         }
230         lower_dentry = DENTRY_TO_LOWER(dentry);
231         lower_sto_dentry = DENTRY_TO_LOWER_STO(dentry);
232
233         fist_print_dentry("mini_fo_d_release IN lower_dentry", lower_dentry);
234
235
236         /* decrement lower dentry's counter and free its inode */
237         if (lower_dentry)
238                 dput(lower_dentry);
239
240         if (lower_sto_dentry)
241                 dput(lower_sto_dentry);
242
243         /* free private data (mini_fo_dentry_info) here */
244         KFREE(DENTRY_TO_PRIVATE(dentry));
245         DENTRY_TO_PRIVATE_SM(dentry) = NULL;    /* just to be safe */
246 out:
247         print_exit_location();
248 }
249
250
251 /*
252  * we don't really need mini_fo_d_iput, because dentry_iput will call iput() if
253  * mini_fo_d_iput is not defined. We left this implemented for ease of
254  * tracing/debugging.
255  */
256 void
257 mini_fo_d_iput(dentry_t *dentry, inode_t *inode)
258 {
259         print_entry_location();
260         iput(inode);
261         print_exit_location();
262 }
263
264
265 struct dentry_operations mini_fo_dops = {
266         d_revalidate:   mini_fo_d_revalidate,
267         d_hash:         mini_fo_d_hash,
268         d_compare:      mini_fo_d_compare,
269         d_release:      mini_fo_d_release,
270         d_delete:       mini_fo_d_delete,
271         d_iput:     mini_fo_d_iput,
272 };
273
274
275 /*
276  * Local variables:
277  * c-basic-offset: 4
278  * End:
279  */
Note: See TracBrowser for help on using the browser.