1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Lustre filesystem abstraction routines
6 * Copyright (C) 2004 Cluster File Systems, Inc.
8 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
24 #define DEBUG_SUBSYSTEM S_FILTER
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>
40 #include <linux/lustre_snap.h>
41 #include <linux/lustre_smfs.h>
43 static struct inode* fsfilt_smfs_create_indirect(struct inode *inode,
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;
59 cache_inode = I2CI(inode);
63 cache_parent = I2CI(parent);
67 pre_smfs_inode(inode, cache_inode);
68 pre_smfs_inode(inode, cache_parent);
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);
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);
83 static struct inode* fsfilt_smfs_get_indirect(struct inode *inode,
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;
95 cache_inode = I2CI(inode);
99 pre_smfs_inode(inode, cache_inode);
101 if (snap_fsfilt->fs_get_indirect)
102 cache_ind_inode = snap_fsfilt->fs_get_indirect(cache_inode,
104 post_smfs_inode(inode, cache_inode);
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);
113 static int fsfilt_smfs_set_indirect(struct inode *inode, int index,
114 ino_t ind_ino, ino_t parent_ino)
116 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
117 struct inode *cache_inode = NULL;
121 if (snap_fsfilt == NULL)
124 cache_inode = I2CI(inode);
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);
137 static int fsfilt_smfs_snap_feature(struct super_block *sb, int feature,
140 struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
141 struct super_block *csb = S2CSB(sb);
144 if (snap_fsfilt == NULL)
149 if (snap_fsfilt->fs_snap_feature)
150 rc = snap_fsfilt->fs_snap_feature(csb, feature, op);
155 static int fsfilt_smfs_is_redirector(struct inode *inode)
157 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
158 struct inode *cache_inode = NULL;
162 if (snap_fsfilt == NULL)
165 cache_inode = I2CI(inode);
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);
176 static int fsfilt_smfs_is_indirect(struct inode *inode)
178 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
179 struct inode *cache_inode = NULL;
183 if (snap_fsfilt == NULL)
186 cache_inode = I2CI(inode);
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);
197 static ino_t fsfilt_smfs_get_indirect_ino(struct inode *inode, int index)
199 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
200 struct inode *cache_inode = NULL;
204 if (snap_fsfilt == NULL)
207 cache_inode = I2CI(inode);
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);
218 static int fsfilt_smfs_set_generation(struct inode *inode,
219 unsigned long new_gen)
221 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
222 struct inode *cache_inode = NULL;
226 if (snap_fsfilt == NULL)
229 cache_inode = I2CI(inode);
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);
241 static int fsfilt_smfs_get_generation(struct inode *inode)
243 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
244 struct inode *cache_inode = NULL;
248 if (snap_fsfilt == NULL)
251 cache_inode = I2CI(inode);
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);
263 static int fsfilt_smfs_destroy_indirect(struct inode *inode, int index,
264 struct inode *next_ind)
266 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
267 struct inode *cache_inode = NULL;
268 struct inode *cache_next = NULL;
272 if (snap_fsfilt == NULL)
275 cache_inode = I2CI(inode);
279 cache_next = I2CI(next_ind);
283 pre_smfs_inode(inode, cache_inode);
284 pre_smfs_inode(next_ind, cache_next);
286 if (snap_fsfilt->fs_destroy_indirect)
287 rc = snap_fsfilt->fs_destroy_indirect(cache_inode, index,
289 post_smfs_inode(inode, cache_inode);
290 post_smfs_inode(next_ind, cache_next);
294 static int fsfilt_smfs_restore_indirect(struct inode *inode, int index)
296 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(inode);
297 struct inode *cache_inode = NULL;
301 if (snap_fsfilt == NULL)
304 cache_inode = I2CI(inode);
308 pre_smfs_inode(inode, cache_inode);
310 if (snap_fsfilt->fs_restore_indirect)
311 rc = snap_fsfilt->fs_restore_indirect(cache_inode, index);
313 post_smfs_inode(inode, cache_inode);
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)
321 struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
322 struct super_block *csb = S2CSB(sb);
326 /*FIXME start == NULL, later*/
327 LASSERT(start == NULL);
329 if (snap_fsfilt == NULL)
332 if (snap_fsfilt->fs_iterate)
333 rc = snap_fsfilt->fs_iterate(csb, repeat, start, priv, flag);
338 static int fsfilt_smfs_copy_block(struct inode *dst, struct inode *src, int blk)
340 struct fsfilt_operations *snap_fsfilt = I2SNAPOPS(dst);
341 struct inode *cache_dst = NULL;
342 struct inode *cache_src = NULL;
346 if (snap_fsfilt == NULL)
349 cache_dst = I2CI(dst);
353 cache_src = I2CI(src);
357 pre_smfs_inode(dst, cache_dst);
358 pre_smfs_inode(src, cache_src);
360 if (snap_fsfilt->fs_copy_block)
361 rc = snap_fsfilt->fs_copy_block(cache_dst, cache_src, blk);
363 post_smfs_inode(dst, cache_dst);
364 post_smfs_inode(src, cache_src);
369 static int fsfilt_smfs_set_meta_attr(struct super_block *sb, char *name,
372 struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
373 struct super_block *csb = S2CSB(sb);
376 if (snap_fsfilt == NULL)
381 if (snap_fsfilt->fs_set_meta_attr)
382 rc = snap_fsfilt->fs_set_meta_attr(csb, name, buf, size);
387 static int fsfilt_smfs_get_meta_attr(struct super_block *sb, char *name,
388 char *buf, int *size)
390 struct fsfilt_operations *snap_fsfilt = S2SMI(sb)->sm_snap_fsfilt;
391 struct super_block *csb = S2CSB(sb);
394 if (snap_fsfilt == NULL)
399 if (snap_fsfilt->fs_get_meta_attr)
400 rc = snap_fsfilt->fs_get_meta_attr(csb, name, buf, size);
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,
426 static int __init fsfilt_smfs_snap_init(void)
430 rc = fsfilt_register_ops(&fsfilt_smfs_snap_ops);
434 static void __exit fsfilt_smfs_snap_exit(void)
436 fsfilt_unregister_ops(&fsfilt_smfs_snap_ops);
439 module_init(fsfilt_smfs_snap_init);
440 module_exit(fsfilt_smfs_snap_exit);
442 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
443 MODULE_DESCRIPTION("Lustre SMFS SNAP Filesystem Helper v0.1");
444 MODULE_LICENSE("GPL");