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