Whamcloud - gitweb
1)cleanup smfs for build in 2.6
[fs/lustre-release.git] / lustre / lvfs / fsfilt_snap_smfs.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Lustre filesystem abstraction routines
5  *
6  *  Copyright (C) 2004 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define DEBUG_SUBSYSTEM S_FILTER
25
26 #include <linux/fs.h>
27 #include <linux/jbd.h>
28 #include <linux/slab.h>
29 #include <linux/pagemap.h>
30 #include <linux/quotaops.h>
31 #include <linux/version.h>
32 #include <linux/kp30.h>
33 #include <linux/lustre_fsfilt.h>
34 #include <linux/lustre_smfs.h>
35 #include <linux/obd.h>
36 #include <linux/obd_class.h>
37 #include <linux/module.h>
38 #include <linux/init.h>
39
40 #include <linux/lustre_snap.h>
41 #include <linux/lustre_smfs.h>
42
43 static struct inode* fsfilt_smfs_create_indirect(struct inode *inode,
44                                                  int index,
45                                                  unsigned int gen,
46                                                  struct inode *parent,
47                                                  int del)
48 {
49         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
50         struct inode *cache_inode = NULL;
51         struct inode *cache_parent = NULL;
52         struct inode *cache_ind_inode = NULL;
53         struct inode *ind_inode = NULL;
54         ENTRY;
55
56         if (!snap_fsfilt)
57                 RETURN(NULL);
58
59         cache_inode = I2CI(inode);
60         if (!cache_inode)
61                 RETURN(NULL);
62
63         cache_parent = I2CI(parent);
64         if (!cache_parent)
65                 RETURN(NULL);
66
67         pre_smfs_inode(inode, cache_inode);
68         pre_smfs_inode(inode, cache_parent);
69
70         if (snap_fsfilt->fs_create_indirect)
71                 cache_ind_inode = snap_fsfilt->fs_create_indirect(cache_inode, 
72                                                index, gen, cache_parent, del);
73         post_smfs_inode(inode, cache_inode);
74         post_smfs_inode(inode, cache_parent);
75         
76         if (cache_ind_inode && !IS_ERR(cache_ind_inode)){ 
77                 /*FIXME: get indirect inode set_cow flags*/ 
78                 ind_inode = smfs_get_inode(inode->i_sb, cache_ind_inode->i_ino, 
79                                            inode, 0);
80         }    
81         RETURN(ind_inode);
82 }
83
84 static struct inode*  fsfilt_smfs_get_indirect(struct inode *inode, 
85                                                int *table, int slot)
86 {
87         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
88         struct inode *cache_inode = NULL;
89         struct inode *cache_ind_inode = NULL;
90         struct inode *ind_inode = NULL;
91         ENTRY;
92
93         if (!snap_fsfilt)
94                 RETURN(NULL);
95
96         cache_inode = I2CI(inode);
97         if (!cache_inode)
98                 RETURN(NULL);
99
100         pre_smfs_inode(inode, cache_inode);
101
102         if (snap_fsfilt->fs_get_indirect)
103                 cache_ind_inode = snap_fsfilt->fs_get_indirect(cache_inode, 
104                                                                table, slot);
105         post_smfs_inode(inode, cache_inode);
106       
107         if (cache_ind_inode && !IS_ERR(cache_ind_inode)){ 
108                 /*FIXME: get indirect inode set_cow flags*/ 
109                 ind_inode = smfs_get_inode(inode->i_sb, cache_ind_inode->i_ino,
110                                            inode, slot);
111         }    
112         RETURN(ind_inode);
113 }
114
115 static int fsfilt_smfs_set_indirect(struct inode *inode, int index,
116                                     ino_t ind_ino, ino_t parent_ino)
117 {
118         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
119         struct inode *cache_inode = NULL;
120         int    rc = -EIO;
121         ENTRY;
122
123         if (snap_fsfilt == NULL)
124                 RETURN(rc);
125
126         cache_inode = I2CI(inode);
127         if (!cache_inode)
128                 RETURN(rc);
129
130         pre_smfs_inode(inode, cache_inode);
131         if (snap_fsfilt->fs_set_indirect)
132                 rc = snap_fsfilt->fs_set_indirect(cache_inode, index,
133                                                   ind_ino, parent_ino);
134         post_smfs_inode(inode, cache_inode);
135         
136         RETURN(rc);
137 }
138
139 static int fsfilt_smfs_snap_feature(struct super_block *sb, int feature, 
140                                     int op)
141 {
142         struct fsfilt_operations *snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt;
143         struct super_block       *csb = S2CSB(sb);
144         int                      rc = -EIO;
145         
146         if (snap_fsfilt == NULL)
147                 RETURN(rc);
148         if (!csb)
149                 RETURN(rc);
150         
151         if (snap_fsfilt->fs_snap_feature)
152                 rc = snap_fsfilt->fs_snap_feature(csb, feature, op);  
153         
154         RETURN(rc); 
155 }
156
157 static int fsfilt_smfs_is_redirector(struct inode *inode)
158 {
159         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
160         struct inode *cache_inode = NULL;
161         int    rc = -EIO;
162         ENTRY;
163
164         if (snap_fsfilt == NULL)
165                 RETURN(rc);
166
167         cache_inode = I2CI(inode);
168         if (!cache_inode)
169                 RETURN(rc);
170
171         pre_smfs_inode(inode, cache_inode);
172         if (snap_fsfilt->fs_is_redirector)
173                 rc = snap_fsfilt->fs_is_redirector(cache_inode);
174         post_smfs_inode(inode, cache_inode);
175         
176         RETURN(rc);
177 }
178 static int fsfilt_smfs_is_indirect(struct inode *inode)
179 {
180         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
181         struct inode *cache_inode = NULL;
182         int    rc = -EIO;
183         ENTRY;
184
185         if (snap_fsfilt == NULL)
186                 RETURN(rc);
187
188         cache_inode = I2CI(inode);
189         if (!cache_inode)
190                 RETURN(rc);
191
192         pre_smfs_inode(inode, cache_inode);
193         if (snap_fsfilt->fs_is_indirect)
194                 rc = snap_fsfilt->fs_is_indirect(cache_inode);
195         post_smfs_inode(inode, cache_inode);
196         
197         RETURN(rc);
198 }
199 static ino_t fsfilt_smfs_get_indirect_ino(struct super_block *sb, ino_t ino, 
200                                           int index)
201 {
202         struct fsfilt_operations *snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt;
203         struct super_block       *csb = S2CSB(sb);
204         int    rc = -EIO;
205         ENTRY;
206
207         if (snap_fsfilt == NULL)
208                 RETURN(rc);
209
210         if (snap_fsfilt->fs_get_indirect_ino)
211                 rc = snap_fsfilt->fs_get_indirect_ino(csb, ino, index);
212          
213         RETURN(rc);
214 }
215
216 static int fsfilt_smfs_destroy_indirect(struct inode *inode, int index,
217                                         struct inode *next_ind)
218 {
219         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
220         struct inode *cache_inode = NULL;
221         struct inode *cache_next = NULL;
222         int    rc = -EIO;
223         ENTRY;
224
225         if (snap_fsfilt == NULL)
226                 RETURN(rc);
227
228         cache_inode = I2CI(inode);
229         if (!cache_inode)
230                 RETURN(rc);
231
232         cache_next = I2CI(next_ind);
233         if (!cache_next)
234                 RETURN(rc);
235
236         pre_smfs_inode(inode, cache_inode);
237         pre_smfs_inode(next_ind, cache_next);
238
239         if (snap_fsfilt->fs_destroy_indirect)
240                 rc = snap_fsfilt->fs_destroy_indirect(cache_inode, index, 
241                                                       cache_next);
242         post_smfs_inode(inode, cache_inode);
243         post_smfs_inode(next_ind, cache_next);
244         
245         RETURN(rc);
246 }
247 static int fsfilt_smfs_restore_indirect(struct inode *inode, int index)
248 {
249         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
250         struct inode *cache_inode = NULL;
251         int    rc = -EIO;
252         ENTRY;
253
254         if (snap_fsfilt == NULL)
255                 RETURN(rc);
256
257         cache_inode = I2CI(inode);
258         if (!cache_inode)
259                 RETURN(rc);
260
261         pre_smfs_inode(inode, cache_inode);
262         
263         if (snap_fsfilt->fs_restore_indirect)
264                 rc = snap_fsfilt->fs_restore_indirect(cache_inode, index);
265         
266         post_smfs_inode(inode, cache_inode);
267         
268         RETURN(rc);
269 }
270 static int fsfilt_smfs_iterate(struct super_block *sb,
271                                int (*repeat)(struct inode *inode, void *priv),
272                                struct inode **start, void *priv, int flag)
273 {
274         struct fsfilt_operations *snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt;
275         struct super_block       *csb = S2CSB(sb);
276         int                      rc = -EIO;
277         ENTRY;
278
279         /*FIXME start == NULL, later*/
280         LASSERT(start == NULL);
281  
282         if (snap_fsfilt == NULL)
283                 RETURN(rc);
284          
285         if (snap_fsfilt->fs_iterate)
286                 rc = snap_fsfilt->fs_iterate(csb, repeat, start, priv, flag);
287
288         RETURN(rc);
289 }
290
291 static int fsfilt_smfs_copy_block(struct inode *dst, struct inode *src, int blk)
292 {
293         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(dst);
294         struct inode *cache_dst = NULL;
295         struct inode *cache_src = NULL;
296         int    rc = -EIO;
297         ENTRY;
298
299         if (snap_fsfilt == NULL)
300                 RETURN(rc);
301          
302         cache_dst = I2CI(dst);
303         if (!cache_dst)
304                 RETURN(rc);
305        
306         cache_src = I2CI(src);
307         if (!cache_src)
308                 RETURN(rc);
309
310         pre_smfs_inode(dst, cache_dst);
311         pre_smfs_inode(src, cache_src);
312         
313         if (snap_fsfilt->fs_copy_block)
314                 rc = snap_fsfilt->fs_copy_block(cache_dst, cache_src, blk);
315
316         post_smfs_inode(dst, cache_dst);
317         post_smfs_inode(src, cache_src);
318          
319         RETURN(rc); 
320 }
321
322 static int fsfilt_smfs_set_snap_info(struct inode *inode, 
323                                      void* key, __u32 keylen, void *val, 
324                                      __u32 *vallen)
325 {
326
327         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
328         struct inode *cache_inode = NULL;
329         int                      rc = -EIO;
330                 
331         if (snap_fsfilt == NULL)
332                 RETURN(rc);
333         
334         cache_inode = I2CI(inode);
335         if (!cache_inode)
336                 RETURN(rc);
337
338         pre_smfs_inode(inode, cache_inode);
339         
340         if (snap_fsfilt->fs_set_snap_info)
341                 rc = snap_fsfilt->fs_set_snap_info(cache_inode, key, 
342                                                    keylen, val, vallen);
343         post_smfs_inode(inode, cache_inode);
344         
345         RETURN(rc);
346 }
347
348 static int fsfilt_smfs_get_snap_info(struct inode *inode, void *key, 
349                                      __u32 keylen, void *val, __u32 *vallen)
350 {
351         struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
352         struct inode *cache_inode = NULL;
353         int                      rc = -EIO;
354         
355         if (snap_fsfilt == NULL)
356                 RETURN(rc);
357         
358         cache_inode = I2CI(inode);
359         if (!cache_inode)
360                 RETURN(rc);
361         
362         if (snap_fsfilt->fs_get_snap_info)
363                 rc = snap_fsfilt->fs_get_snap_info(cache_inode, key, 
364                                                    keylen, val, vallen);
365         
366         RETURN(rc);
367 }
368
369 static int fsfilt_smfs_read_dotsnap_dir_page(struct file *file, char *buf,
370                                              size_t count, loff_t *off)
371 {
372         struct inode *inode = file->f_dentry->d_inode;
373         struct fsfilt_operations *snap_cops = I2SNAPCOPS(inode);
374         struct snap_table *stbl = S2SNAPI(inode->i_sb)->sntbl;
375         int    i = 0, size = 0, off_count = 0, buf_off = 0, rc = 0;
376         ENTRY;
377
378         /*Get the offset of dir ent*/
379         while (size < *off && off_count < stbl->sntbl_count) {
380                 char *name = stbl->sntbl_items[i].sn_name;
381                 size +=snap_cops->fs_dir_ent_size(name);
382                 off_count ++;
383         }
384         for (i = off_count; i < stbl->sntbl_count; i++) {
385                 char *name = stbl->sntbl_items[i].sn_name;
386                 rc = snap_cops->fs_set_dir_ent(inode->i_sb, name, buf, buf_off, 
387                                                rc, count);
388                 if (rc < 0)
389                         break;
390
391                 buf_off += rc;
392
393                 if (buf_off >= count) 
394                         break;
395         }
396         if (rc > 0) 
397                 rc = 0; 
398
399         RETURN(rc); 
400 }
401
402 struct fsfilt_operations fsfilt_smfs_snap_ops = {
403         .fs_type                = "smfs_snap",
404         .fs_owner               = THIS_MODULE,
405         .fs_create_indirect     = fsfilt_smfs_create_indirect,
406         .fs_get_indirect        = fsfilt_smfs_get_indirect,
407         .fs_set_indirect        = fsfilt_smfs_set_indirect,
408         .fs_snap_feature        = fsfilt_smfs_snap_feature,
409         .fs_is_redirector       = fsfilt_smfs_is_redirector,
410         .fs_is_indirect         = fsfilt_smfs_is_indirect,
411         .fs_get_indirect_ino    = fsfilt_smfs_get_indirect_ino,
412         .fs_destroy_indirect    = fsfilt_smfs_destroy_indirect,
413         .fs_restore_indirect    = fsfilt_smfs_restore_indirect,
414         .fs_iterate             = fsfilt_smfs_iterate,
415         .fs_copy_block          = fsfilt_smfs_copy_block,
416         .fs_set_snap_info       = fsfilt_smfs_set_snap_info,
417         .fs_get_snap_info       = fsfilt_smfs_get_snap_info,
418         .fs_read_dotsnap_dir_page = fsfilt_smfs_read_dotsnap_dir_page,
419 };
420
421
422 static int __init fsfilt_smfs_snap_init(void)
423 {
424         int rc;
425
426         rc = fsfilt_register_ops(&fsfilt_smfs_snap_ops);
427         return rc;
428 }
429
430 static void __exit fsfilt_smfs_snap_exit(void)
431 {
432         fsfilt_unregister_ops(&fsfilt_smfs_snap_ops);
433 }
434
435 module_init(fsfilt_smfs_snap_init);
436 module_exit(fsfilt_smfs_snap_exit);
437
438 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
439 MODULE_DESCRIPTION("Lustre SMFS SNAP Filesystem Helper v0.1");
440 MODULE_LICENSE("GPL");