Whamcloud - gitweb
2d74ae48b2aa0420e0e5f1da0a0446137b4d0f92
[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 = I2SNAPOPS(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 = iget4(inode->i_sb, cache_ind_inode->i_ino, NULL, 0);
79         }    
80         RETURN(ind_inode);
81 }
82
83 static struct inode*  fsfilt_smfs_get_indirect(struct inode *inode, 
84                                                int *table, int slot)
85 {
86         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
87         struct inode *cache_inode = NULL;
88         struct inode *cache_ind_inode = NULL;
89         struct inode *ind_inode = NULL;
90         ENTRY;
91
92         if (!snap_fsfilt)
93                 RETURN(NULL);
94
95         cache_inode = I2CI(inode);
96         if (!cache_inode)
97                 RETURN(NULL);
98
99         pre_smfs_inode(inode, cache_inode);
100
101         if (snap_fsfilt->fs_get_indirect)
102                 cache_ind_inode = snap_fsfilt->fs_get_indirect(cache_inode, 
103                                                                table, slot);
104         post_smfs_inode(inode, cache_inode);
105       
106         if (cache_ind_inode && !IS_ERR(cache_ind_inode)){ 
107                 /*FIXME: get indirect inode set_cow flags*/ 
108                 ind_inode = iget4(inode->i_sb, cache_ind_inode->i_ino, NULL, 0);
109         }    
110         RETURN(ind_inode);
111 }
112
113 static int fsfilt_smfs_set_indirect(struct inode *inode, int index,
114                                     ino_t ind_ino, ino_t parent_ino)
115 {
116         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
117         struct inode *cache_inode = NULL;
118         int    rc = -EIO;
119         ENTRY;
120
121         if (snap_fsfilt == NULL)
122                 RETURN(rc);
123
124         cache_inode = I2CI(inode);
125         if (!cache_inode)
126                 RETURN(rc);
127
128         pre_smfs_inode(inode, cache_inode);
129         if (snap_fsfilt->fs_set_indirect)
130                 rc = snap_fsfilt->fs_set_indirect(cache_inode, index,
131                                                   ind_ino, parent_ino);
132         post_smfs_inode(inode, cache_inode);
133         
134         RETURN(rc);
135 }
136
137 static int fsfilt_smfs_snap_feature(struct super_block *sb, int feature, 
138                                     int op)
139 {
140         struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
141         struct super_block       *csb = S2CSB(sb);
142         int                      rc = -EIO;
143         
144         if (snap_fsfilt == NULL)
145                 RETURN(rc);
146         if (!csb)
147                 RETURN(rc);
148         
149         if (snap_fsfilt->fs_snap_feature)
150                 rc = snap_fsfilt->fs_snap_feature(csb, feature, op);  
151         
152         RETURN(rc); 
153 }
154
155 static int fsfilt_smfs_is_redirector(struct inode *inode)
156 {
157         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
158         struct inode *cache_inode = NULL;
159         int    rc = -EIO;
160         ENTRY;
161
162         if (snap_fsfilt == NULL)
163                 RETURN(rc);
164
165         cache_inode = I2CI(inode);
166         if (!cache_inode)
167                 RETURN(rc);
168
169         pre_smfs_inode(inode, cache_inode);
170         if (snap_fsfilt->fs_is_redirector)
171                 rc = snap_fsfilt->fs_is_redirector(cache_inode);
172         post_smfs_inode(inode, cache_inode);
173         
174         RETURN(rc);
175 }
176 static int fsfilt_smfs_is_indirect(struct inode *inode)
177 {
178         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
179         struct inode *cache_inode = NULL;
180         int    rc = -EIO;
181         ENTRY;
182
183         if (snap_fsfilt == NULL)
184                 RETURN(rc);
185
186         cache_inode = I2CI(inode);
187         if (!cache_inode)
188                 RETURN(rc);
189
190         pre_smfs_inode(inode, cache_inode);
191         if (snap_fsfilt->fs_is_indirect)
192                 rc = snap_fsfilt->fs_is_indirect(cache_inode);
193         post_smfs_inode(inode, cache_inode);
194         
195         RETURN(rc);
196 }
197 static ino_t fsfilt_smfs_get_indirect_ino(struct inode *inode, int index)
198 {
199         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
200         struct inode *cache_inode = NULL;
201         int    rc = -EIO;
202         ENTRY;
203
204         if (snap_fsfilt == NULL)
205                 RETURN(rc);
206
207         cache_inode = I2CI(inode);
208         if (!cache_inode)
209                 RETURN(rc);
210
211         pre_smfs_inode(inode, cache_inode);
212         if (snap_fsfilt->fs_get_indirect_ino)
213                 rc = snap_fsfilt->fs_get_indirect_ino(cache_inode, index);
214         post_smfs_inode(inode, cache_inode);
215         
216         RETURN(rc);
217 }
218 static int fsfilt_smfs_set_generation(struct inode *inode, 
219                                       unsigned long new_gen)
220 {
221         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
222         struct inode *cache_inode = NULL;
223         int    rc = -EIO;
224         ENTRY;
225
226         if (snap_fsfilt == NULL)
227                 RETURN(rc);
228
229         cache_inode = I2CI(inode);
230         if (!cache_inode)
231                 RETURN(rc);
232
233         pre_smfs_inode(inode, cache_inode);
234         if (snap_fsfilt->fs_set_generation)
235                 rc = snap_fsfilt->fs_set_generation(cache_inode, new_gen);
236         post_smfs_inode(inode, cache_inode);
237         
238         RETURN(rc);
239 }
240
241 static int fsfilt_smfs_get_generation(struct inode *inode)
242 {
243         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
244         struct inode *cache_inode = NULL;
245         int    rc = -EIO;
246         ENTRY;
247
248         if (snap_fsfilt == NULL)
249                 RETURN(rc);
250
251         cache_inode = I2CI(inode);
252         if (!cache_inode)
253                 RETURN(rc);
254
255         pre_smfs_inode(inode, cache_inode);
256         if (snap_fsfilt->fs_get_generation)
257                 rc = snap_fsfilt->fs_get_generation(cache_inode);
258         post_smfs_inode(inode, cache_inode);
259         
260         RETURN(rc);
261 }
262
263 static int fsfilt_smfs_destroy_indirect(struct inode *inode, int index,
264                                         struct inode *next_ind)
265 {
266         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
267         struct inode *cache_inode = NULL;
268         struct inode *cache_next = NULL;
269         int    rc = -EIO;
270         ENTRY;
271
272         if (snap_fsfilt == NULL)
273                 RETURN(rc);
274
275         cache_inode = I2CI(inode);
276         if (!cache_inode)
277                 RETURN(rc);
278
279         cache_next = I2CI(next_ind);
280         if (!cache_next)
281                 RETURN(rc);
282
283         pre_smfs_inode(inode, cache_inode);
284         pre_smfs_inode(next_ind, cache_next);
285
286         if (snap_fsfilt->fs_destroy_indirect)
287                 rc = snap_fsfilt->fs_destroy_indirect(cache_inode, index, 
288                                                       cache_next);
289         post_smfs_inode(inode, cache_inode);
290         post_smfs_inode(next_ind, cache_next);
291         
292         RETURN(rc);
293 }
294 static int fsfilt_smfs_restore_indirect(struct inode *inode, int index)
295 {
296         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
297         struct inode *cache_inode = NULL;
298         int    rc = -EIO;
299         ENTRY;
300
301         if (snap_fsfilt == NULL)
302                 RETURN(rc);
303
304         cache_inode = I2CI(inode);
305         if (!cache_inode)
306                 RETURN(rc);
307
308         pre_smfs_inode(inode, cache_inode);
309         
310         if (snap_fsfilt->fs_restore_indirect)
311                 rc = snap_fsfilt->fs_restore_indirect(cache_inode, index);
312         
313         post_smfs_inode(inode, cache_inode);
314         
315         RETURN(rc);
316 }
317 static int fsfilt_smfs_iterate(struct super_block *sb,
318                                int (*repeat)(struct inode *inode, void *priv),
319                                struct inode **start, void *priv, int flag)
320 {
321         struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
322         struct super_block       *csb = S2CSB(sb);
323         int                      rc = -EIO;
324         ENTRY;
325
326         /*FIXME start == NULL, later*/
327         LASSERT(start == NULL);
328  
329         if (snap_fsfilt == NULL)
330                 RETURN(rc);
331          
332         if (snap_fsfilt->fs_iterate)
333                 rc = snap_fsfilt->fs_iterate(csb, repeat, start, priv, flag);
334
335         RETURN(rc);
336 }
337
338 static int fsfilt_smfs_copy_block(struct inode *dst, struct inode *src, int blk)
339 {
340         struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(dst);
341         struct inode *cache_dst = NULL;
342         struct inode *cache_src = NULL;
343         int    rc = -EIO;
344         ENTRY;
345
346         if (snap_fsfilt == NULL)
347                 RETURN(rc);
348          
349         cache_dst = I2CI(dst);
350         if (!cache_dst)
351                 RETURN(rc);
352        
353         cache_src = I2CI(src);
354         if (!cache_src)
355                 RETURN(rc);
356
357         pre_smfs_inode(dst, cache_dst);
358         pre_smfs_inode(src, cache_src);
359         
360         if (snap_fsfilt->fs_copy_block)
361                 rc = snap_fsfilt->fs_copy_block(cache_dst, cache_src, blk);
362
363         post_smfs_inode(dst, cache_dst);
364         post_smfs_inode(src, cache_src);
365          
366         RETURN(rc); 
367 }
368
369 static int fsfilt_smfs_set_meta_attr(struct super_block *sb, char *name,
370                                      char *buf, int size)
371 {
372         struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
373         struct super_block       *csb = S2CSB(sb);
374         int                      rc = -EIO;
375         
376         if (snap_fsfilt == NULL)
377                 RETURN(rc);
378         if (!csb)
379                 RETURN(rc);
380         
381         if (snap_fsfilt->fs_set_meta_attr)
382                 rc = snap_fsfilt->fs_set_meta_attr(csb, name, buf, size);
383
384         RETURN(rc);
385 }
386
387 static int fsfilt_smfs_get_meta_attr(struct super_block *sb, char *name,
388                                      char *buf, int *size)
389 {
390         struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
391         struct super_block       *csb = S2CSB(sb);
392         int                      rc = -EIO;
393         
394         if (snap_fsfilt == NULL)
395                 RETURN(rc);
396         if (!csb)
397                 RETURN(rc);
398         
399         if (snap_fsfilt->fs_get_meta_attr)
400                 rc = snap_fsfilt->fs_get_meta_attr(csb, name, buf, size);
401
402         RETURN(rc);
403 }
404
405 struct fsfilt_operations fsfilt_smfs_snap_ops = {
406         .fs_type                = "smfs_snap",
407         .fs_owner               = THIS_MODULE,
408         .fs_create_indirect     = fsfilt_smfs_create_indirect,
409         .fs_get_indirect        = fsfilt_smfs_get_indirect,
410         .fs_set_indirect        = fsfilt_smfs_set_indirect,
411         .fs_snap_feature        = fsfilt_smfs_snap_feature,
412         .fs_is_redirector       = fsfilt_smfs_is_redirector,
413         .fs_is_indirect         = fsfilt_smfs_is_indirect,
414         .fs_get_indirect_ino    = fsfilt_smfs_get_indirect_ino,
415         .fs_set_generation      = fsfilt_smfs_set_generation,
416         .fs_get_generation      = fsfilt_smfs_get_generation,
417         .fs_destroy_indirect    = fsfilt_smfs_destroy_indirect,
418         .fs_restore_indirect    = fsfilt_smfs_restore_indirect,
419         .fs_iterate             = fsfilt_smfs_iterate,
420         .fs_copy_block          = fsfilt_smfs_copy_block,
421         .fs_set_meta_attr       = fsfilt_smfs_set_meta_attr,
422         .fs_get_meta_attr       = fsfilt_smfs_get_meta_attr,
423 };
424
425
426 static int __init fsfilt_smfs_snap_init(void)
427 {
428         int rc;
429
430         rc = fsfilt_register_ops(&fsfilt_smfs_snap_ops);
431         return rc;
432 }
433
434 static void __exit fsfilt_smfs_snap_exit(void)
435 {
436         fsfilt_unregister_ops(&fsfilt_smfs_snap_ops);
437 }
438
439 module_init(fsfilt_smfs_snap_init);
440 module_exit(fsfilt_smfs_snap_exit);
441
442 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
443 MODULE_DESCRIPTION("Lustre SMFS SNAP Filesystem Helper v0.1");
444 MODULE_LICENSE("GPL");