Whamcloud - gitweb
Update smfs:some minor fix in smfs
[fs/lustre-release.git] / lustre / smfs / inode.c
1 /*
2  *  smfs/inode.c
3  *
4  */
5
6 #define DEBUG_SUBSYSTEM S_SM
7
8 #include <linux/kmod.h>
9 #include <linux/init.h>
10 #include <linux/fs.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
13 #include <linux/lustre_idl.h>
14 #include "smfs_internal.h" 
15
16 static void duplicate_inode(struct inode *dst_inode, 
17                      struct inode *src_inode) 
18 {
19         dst_inode->i_mode = src_inode->i_mode;
20         dst_inode->i_uid = src_inode->i_uid;
21         dst_inode->i_gid = src_inode->i_gid;
22         dst_inode->i_nlink = src_inode->i_nlink;
23         dst_inode->i_size = src_inode->i_size;
24         dst_inode->i_atime = src_inode->i_atime;
25         dst_inode->i_ctime = src_inode->i_ctime;
26         dst_inode->i_mtime = src_inode->i_mtime;
27         dst_inode->i_blksize = src_inode->i_blksize;  
28         dst_inode->i_blocks = src_inode->i_blocks;
29         dst_inode->i_version = src_inode->i_version;
30         dst_inode->i_state = src_inode->i_state;
31 }
32
33 void post_smfs_inode(struct inode *inode, 
34                      struct inode *cache_inode)
35 {
36         if (inode && cache_inode) {
37                 duplicate_inode(inode, cache_inode);
38                 /*Here we must release the cache_inode,
39                  *Otherwise we will have no chance to
40                  *do it
41                  */
42                 cache_inode->i_state &=~I_LOCK; 
43         }
44 }
45 void pre_smfs_inode(struct inode *inode,
46                     struct inode *cache_inode)
47 {
48         if (inode && cache_inode) {
49                 duplicate_inode(cache_inode, inode);
50         }
51 }
52
53 static void smfs_read_inode(struct inode *inode)
54 {
55         struct super_block *cache_sb;
56         struct inode *cache_inode;      
57         ENTRY;
58
59         if (!inode) 
60                 return;
61         
62         CDEBUG(D_INODE, "read_inode ino %lu\n", inode->i_ino);
63         cache_sb = S2CSB(inode->i_sb);
64
65         cache_inode = iget(cache_sb, inode->i_ino);
66         I2CI(inode) = cache_inode;
67         
68         if(cache_sb && cache_sb->s_op->read_inode)
69                 cache_sb->s_op->read_inode(cache_inode);
70
71         post_smfs_inode(inode, cache_inode);
72         sm_set_inode_ops(cache_inode, inode);
73         
74         CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", 
75                inode->i_ino, atomic_read(&inode->i_count));
76         
77         iput(cache_inode);      
78         return; 
79 }
80
81 /* Although some filesystem(such as ext3) do not have
82  * clear_inode method, but we need it to free the 
83  * cache inode 
84  */
85 static void smfs_clear_inode(struct inode *inode)
86 {
87         struct super_block *cache_sb;
88         struct inode *cache_inode;      
89
90         ENTRY;
91         
92         if (!inode) return;
93         
94         cache_sb = S2CSB(inode->i_sb);
95         cache_inode = I2CI(inode);
96
97         /*FIXME: because i_count of cache_inode may not 
98          * be 0 or 1 in before smfs_delete inode, So we 
99          * need to dec it to 1 before we call delete_inode
100          * of the bellow cache filesystem Check again latter*/
101
102         if (atomic_read(&cache_inode->i_count) < 1)
103                 BUG();
104         
105         while (atomic_read(&cache_inode->i_count) != 1) {
106                 atomic_dec(&cache_inode->i_count);
107         }
108         iput(cache_inode);
109         
110         I2CI(inode) = NULL;
111         return; 
112 }
113 static void smfs_delete_inode(struct inode *inode)
114 {
115         struct inode *cache_inode;
116         struct super_block *cache_sb;
117
118         ENTRY;
119         cache_inode = I2CI(inode);
120         cache_sb = S2CSB(inode->i_sb);
121
122         if (!cache_inode || !cache_sb)  
123                 return;
124
125         /*FIXME: because i_count of cache_inode may not 
126          * be 0 or 1 in before smfs_delete inode, So we 
127          * need to dec it to 1 before we call delete_inode
128          * of the bellow cache filesystem Check again latter*/
129
130         if (atomic_read(&cache_inode->i_count) < 1)
131                 BUG();
132         
133         while (atomic_read(&cache_inode->i_count) != 1) {
134                 atomic_dec(&cache_inode->i_count);
135         }
136         
137         pre_smfs_inode(inode, cache_inode);
138         
139         list_del(&cache_inode->i_hash);
140         INIT_LIST_HEAD(&cache_inode->i_hash);
141         list_del(&cache_inode->i_list);
142         INIT_LIST_HEAD(&cache_inode->i_list);
143         
144         if (cache_inode->i_data.nrpages)
145                 truncate_inode_pages(&cache_inode->i_data, 0);
146         
147         if (cache_sb->s_op->delete_inode)
148                 cache_sb->s_op->delete_inode(cache_inode);
149
150         post_smfs_inode(inode, cache_inode);
151         
152         I2CI(inode) = NULL;
153         return;
154 }
155 static void smfs_write_inode(struct inode *inode, int wait)
156 {
157         struct inode *cache_inode;
158         struct super_block *cache_sb;
159
160         ENTRY;
161         cache_inode = I2CI(inode);
162         cache_sb = S2CSB(inode->i_sb);
163
164         if (!cache_inode || !cache_sb)
165                 return;
166                 
167         pre_smfs_inode(inode, cache_inode);
168         
169         if (cache_sb->s_op->write_inode)
170                 cache_sb->s_op->write_inode(cache_inode, wait);
171
172         post_smfs_inode(inode, cache_inode);
173         
174         return;
175 }
176 static void smfs_dirty_inode(struct inode *inode)
177 {
178         struct inode *cache_inode;
179         struct super_block *cache_sb;
180
181         ENTRY;
182         cache_inode = I2CI(inode);
183         cache_sb = S2CSB(inode->i_sb);
184
185         if (!cache_inode || !cache_sb)
186                 return;
187                 
188         pre_smfs_inode(inode, cache_inode);
189         if (cache_sb->s_op->dirty_inode)
190                 cache_sb->s_op->dirty_inode(cache_inode);
191
192         post_smfs_inode(inode, cache_inode);
193         return;
194 }
195
196 static void smfs_put_inode(struct inode *inode)
197 {
198         struct inode *cache_inode;
199         struct super_block *cache_sb;
200
201         ENTRY;
202         cache_inode = I2CI(inode);
203         cache_sb = S2CSB(inode->i_sb);
204
205         if (!cache_inode || !cache_sb)
206                 return;
207         if (cache_sb->s_op->put_inode)
208                 cache_sb->s_op->put_inode(cache_inode);
209
210         return;
211 }
212
213 static void smfs_write_super(struct super_block *sb)
214 {
215         struct super_block *cache_sb;
216
217         ENTRY;
218         cache_sb = S2CSB(sb);
219
220         if (!cache_sb)
221                 return;
222                 
223         if (cache_sb->s_op->write_super)
224                 cache_sb->s_op->write_super(cache_sb);
225
226         duplicate_sb(cache_sb, sb);
227         return;
228 }
229
230 static void smfs_write_super_lockfs(struct super_block *sb)
231 {
232         struct super_block *cache_sb;
233
234         ENTRY;
235         cache_sb = S2CSB(sb);
236
237         if (!cache_sb)
238                 return;
239                 
240         if (cache_sb->s_op->write_super_lockfs)
241                 cache_sb->s_op->write_super_lockfs(cache_sb);
242
243         duplicate_sb(cache_sb, sb);
244         return;
245 }
246
247 static void smfs_unlockfs(struct super_block *sb)
248 {
249         struct super_block *cache_sb;
250
251         ENTRY;
252         cache_sb = S2CSB(sb);
253
254         if (!cache_sb)
255                 return;
256                 
257         if (cache_sb->s_op->unlockfs)
258                 cache_sb->s_op->unlockfs(cache_sb);
259
260         duplicate_sb(cache_sb, sb);
261         return;
262 }
263 static int smfs_statfs(struct super_block * sb, struct statfs * buf) 
264 {
265         struct super_block *cache_sb;
266         int     rc = 0;
267
268         ENTRY;
269         cache_sb = S2CSB(sb);
270
271         if (!cache_sb)
272                 RETURN(-EINVAL);
273                 
274         if (cache_sb->s_op->statfs)
275                 rc = cache_sb->s_op->statfs(cache_sb, buf);
276
277         duplicate_sb(cache_sb, sb);
278         
279         return rc;
280 }
281 static int smfs_remount(struct super_block * sb, int * flags, char * data)
282 {
283         struct super_block *cache_sb;
284         int    rc = 0;
285
286         ENTRY;
287         cache_sb = S2CSB(sb);
288
289         if (!cache_sb)
290                 RETURN(-EINVAL);
291                 
292         if (cache_sb->s_op->remount_fs)
293                 rc = cache_sb->s_op->remount_fs(cache_sb, flags, data);
294
295         duplicate_sb(cache_sb, sb);
296         RETURN(rc);
297 }
298 struct super_operations smfs_super_ops = {
299         read_inode:     smfs_read_inode,
300         clear_inode:    smfs_clear_inode,
301         put_super:      smfs_put_super,
302         delete_inode:   smfs_delete_inode,
303         write_inode:    smfs_write_inode,
304         dirty_inode:    smfs_dirty_inode,       /* BKL not held.  We take it */
305         put_inode:      smfs_put_inode,         /* BKL not held.  Don't need */
306
307         write_super:    smfs_write_super,       /* BKL held */
308         write_super_lockfs: smfs_write_super_lockfs, /* BKL not held. Take it */
309         unlockfs:       smfs_unlockfs,          /* BKL not held.  We take it */
310         statfs:         smfs_statfs,            /* BKL held */
311         remount_fs:     smfs_remount,           /* BKL held */
312
313 };
314
315
316
317
318