1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/lib/fsfilt_smfs.c
5 * Lustre filesystem abstraction routines
7 * Copyright (C) 2002, 2003 Cluster File Systems, Inc.
8 * Author: Wang Di <wangdi@clusterfs.com>
10 * This file is part of Lustre, http://www.lustre.org.
12 * Lustre is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Lustre is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with Lustre; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define DEBUG_SUBSYSTEM S_FILTER
29 #include <linux/jbd.h>
30 #include <linux/slab.h>
31 #include <linux/pagemap.h>
32 #include <linux/quotaops.h>
33 #include <linux/version.h>
34 #include <linux/kp30.h>
35 #include <linux/lustre_fsfilt.h>
36 #include <linux/lustre_smfs.h>
37 #include <linux/obd.h>
38 #include <linux/obd_class.h>
39 #include <linux/module.h>
41 static void *fsfilt_smfs_start(struct inode *inode, int op,
42 void *desc_private, int logs)
45 struct inode *cache_inode = I2CI(inode);
46 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
48 if (cache_fsfilt == NULL)
51 if (!cache_fsfilt->fs_start)
52 return ERR_PTR(-ENOSYS);
54 handle = cache_fsfilt->fs_start(cache_inode, op,
59 static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
60 int niocount, struct niobuf_local *nb,
61 void *desc_private, int logs)
63 struct fsfilt_operations *cache_fsfilt;
64 struct dentry *cache_dentry = NULL;
65 struct inode *cache_inode = NULL;
66 struct fsfilt_objinfo cache_fso;
70 cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
71 if (cache_fsfilt == NULL)
74 cache_inode = I2CI(fso->fso_dentry->d_inode);
75 cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
78 GOTO(exit, rc = ERR_PTR(-ENOMEM));
80 cache_fso.fso_dentry = cache_dentry;
81 cache_fso.fso_bufcnt = fso->fso_bufcnt;
83 if (!cache_fsfilt->fs_brw_start)
84 return ERR_PTR(-ENOSYS);
86 rc = (cache_fsfilt->fs_brw_start(objcount, &cache_fso,
87 niocount, nb, desc_private,
90 post_smfs_dentry(cache_dentry);
94 static int fsfilt_smfs_commit(struct inode *inode, void *h,
97 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
98 struct inode *cache_inode = NULL;
101 cache_inode = I2CI(inode);
103 if (cache_fsfilt == NULL)
106 if (!cache_fsfilt->fs_commit)
109 rc = cache_fsfilt->fs_commit(cache_inode, h, force_sync);
114 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
117 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
118 struct inode *cache_inode = NULL;
121 cache_inode = I2CI(inode);
122 if (cache_fsfilt == NULL)
125 if (!cache_fsfilt->fs_commit_async)
128 rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
133 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
135 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
136 struct inode *cache_inode = NULL;
139 cache_inode = I2CI(inode);
140 if (cache_fsfilt == NULL)
143 if (!cache_fsfilt->fs_commit_wait)
146 rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
151 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
152 struct iattr *iattr, int do_trunc)
154 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
155 struct dentry *cache_dentry = NULL;
156 struct inode *cache_inode = NULL;
162 cache_inode = I2CI(dentry->d_inode);
164 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
166 GOTO(exit, rc = -ENOMEM);
168 pre_smfs_inode(dentry->d_inode, cache_inode);
170 if (!cache_fsfilt->fs_setattr)
173 rc = cache_fsfilt->fs_setattr(cache_dentry, handle,
176 post_smfs_inode(dentry->d_inode, cache_inode);
179 post_smfs_dentry(cache_dentry);
183 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
184 unsigned int cmd, unsigned long arg)
186 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
187 struct inode *cache_inode = NULL;
188 struct smfs_file_info *sfi = NULL;
195 cache_inode = I2CI(inode);
203 if (sfi->magic != SMFS_FILE_MAGIC)
209 if (!cache_fsfilt->fs_iocontrol)
213 rc = cache_fsfilt->fs_iocontrol(cache_inode,
217 rc = cache_fsfilt->fs_iocontrol(cache_inode,
221 /* FIXME-UMKA: Should this be in duplicate_inode()? */
222 if (rc == 0 && cmd == EXT3_IOC_SETFLAGS)
223 inode->i_flags = cache_inode->i_flags;
225 post_smfs_inode(inode, cache_inode);
230 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
231 void *lmm, int lmm_size)
233 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
234 struct inode *cache_inode = NULL;
240 cache_inode = I2CI(inode);
245 pre_smfs_inode(inode, cache_inode);
247 if (!cache_fsfilt->fs_set_md)
250 down(&cache_inode->i_sem);
252 rc = cache_fsfilt->fs_set_md(cache_inode, handle,
255 up(&cache_inode->i_sem);
257 post_smfs_inode(inode, cache_inode);
262 /* Must be called with i_sem held */
263 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm, int lmm_size)
265 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
266 struct inode *cache_inode = NULL;
272 cache_inode = I2CI(inode);
277 pre_smfs_inode(inode, cache_inode);
279 if (!cache_fsfilt->fs_get_md)
282 down(&cache_inode->i_sem);
284 rc = cache_fsfilt->fs_get_md(cache_inode, lmm,
287 up(&cache_inode->i_sem);
289 post_smfs_inode(inode, cache_inode);
294 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
295 static int fsfilt_smfs_send_bio(struct inode *inode,
298 static int fsfilt_smfs_send_bio(struct inode *inode,
302 struct inode *cache_inode;
303 struct fsfilt_operations *cache_fsfilt;
305 cache_fsfilt = I2FOPS(inode);
309 cache_inode = I2CI(inode);
313 if (!cache_fsfilt->fs_send_bio)
316 return cache_fsfilt->fs_send_bio(cache_inode, bio);
320 fsfilt_smfs_getpage(struct inode *inode, long int index)
322 struct fsfilt_operations *cache_fsfilt;
323 struct inode *cache_inode;
325 cache_fsfilt = I2FOPS(inode);
327 RETURN(ERR_PTR(-EINVAL));
329 cache_inode = I2CI(inode);
331 RETURN(ERR_PTR(-EINVAL));
333 if (!cache_fsfilt->fs_getpage)
334 RETURN(ERR_PTR(-ENOSYS));
336 return cache_fsfilt->fs_getpage(cache_inode, index);
339 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
340 size_t count, loff_t *off)
342 struct fsfilt_operations *cache_fsfilt;
343 struct smfs_file_info *sfi;
344 struct inode *cache_inode;
351 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
355 cache_inode = I2CI(file->f_dentry->d_inode);
360 if (sfi->magic != SMFS_FILE_MAGIC)
363 if (off != &(file->f_pos)) {
364 cache_ppos = &tmp_ppos;
366 cache_ppos = &sfi->c_file->f_pos;
370 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
372 if (cache_fsfilt->fs_readpage)
373 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf,
377 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
378 duplicate_file(file, sfi->c_file);
383 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
384 struct super_block *sb,
385 __u64 last_rcvd, void *handle,
389 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
390 struct super_block *csb = S2CSB(sb);
395 if (cache_fsfilt->fs_add_journal_cb)
396 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
397 handle, cb_func, cb_data);
401 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
403 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
404 struct super_block *csb = S2CSB(sb);
410 if (!cache_fsfilt->fs_statfs)
413 rc = cache_fsfilt->fs_statfs(csb, osfs);
414 duplicate_sb(csb, sb);
419 static int fsfilt_smfs_sync(struct super_block *sb)
421 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
422 struct super_block *csb = S2CSB(sb);
428 if (!cache_fsfilt->fs_sync)
431 rc = cache_fsfilt->fs_sync(csb);
436 int fsfilt_smfs_map_inode_page(struct inode *inode, struct page *page,
437 unsigned long *blocks, int *created, int create)
439 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
440 struct inode *cache_inode = NULL;
446 cache_inode = I2CI(inode);
451 if (!cache_fsfilt->fs_map_inode_page)
454 down(&cache_inode->i_sem);
455 rc = cache_fsfilt->fs_map_inode_page(cache_inode, page,
456 blocks, created, create);
457 up(&cache_inode->i_sem);
462 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
463 int nblocks, loff_t newsize)
465 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
466 struct inode *cache_inode = NULL;
472 cache_inode = I2CI(inode);
477 if (!cache_fsfilt->fs_prep_san_write)
480 down(&cache_inode->i_sem);
481 rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks,
483 up(&cache_inode->i_sem);
488 static int fsfilt_smfs_read_record(struct file * file, void *buf,
489 int size, loff_t *offs)
491 struct fsfilt_operations *cache_fsfilt;
492 struct inode *cache_inode;
493 struct smfs_file_info *sfi;
499 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
503 cache_inode = I2CI(file->f_dentry->d_inode);
509 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
511 if (offs != &(file->f_pos)) {
512 cache_ppos = &tmp_ppos;
514 cache_ppos = &sfi->c_file->f_pos;
518 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
520 if (!cache_fsfilt->fs_read_record)
523 rc = cache_fsfilt->fs_read_record(sfi->c_file, buf,
527 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
528 duplicate_file(file, sfi->c_file);
533 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
534 loff_t *offs, int force_sync)
536 struct fsfilt_operations *cache_fsfilt;
537 struct inode *cache_inode;
538 struct smfs_file_info *sfi;
545 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
549 cache_inode = I2CI(file->f_dentry->d_inode);
555 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
557 if (offs != &(file->f_pos)) {
558 cache_ppos = &tmp_ppos;
560 cache_ppos = &sfi->c_file->f_pos;
564 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
566 if (!cache_fsfilt->fs_write_record)
569 rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
570 bufsize, cache_ppos, force_sync);
572 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
573 duplicate_file(file, sfi->c_file);
578 static int fsfilt_smfs_setup(struct super_block *sb)
580 struct smfs_super_info *smfs_info = S2SMI(sb);
581 struct fsfilt_operations *cache_fsfilt;
582 struct super_block *csb;
585 /* It should be initialized olready by smfs_read_super(). */
586 if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
587 cache_fsfilt = fsfilt_get_ops(smfs_info->cache_fs_type);
594 if (cache_fsfilt->fs_setup)
595 rc = cache_fsfilt->fs_setup(csb);
600 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle,
601 char *name, void *buffer,
604 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
605 struct inode *cache_inode = NULL;
611 cache_inode = I2CI(inode);
615 pre_smfs_inode(inode, cache_inode);
617 if (cache_fsfilt->fs_set_xattr)
618 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
619 buffer, buffer_size);
620 post_smfs_inode(inode, cache_inode);
625 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
626 void *buffer, int buffer_size)
628 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
629 struct inode *cache_inode = NULL;
635 cache_inode = I2CI(inode);
639 pre_smfs_inode(inode, cache_inode);
641 if (cache_fsfilt->fs_get_xattr)
642 rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
643 buffer, buffer_size);
644 post_smfs_inode(inode, cache_inode);
649 static struct fsfilt_operations fsfilt_smfs_ops = {
651 .fs_owner = THIS_MODULE,
652 .fs_start = fsfilt_smfs_start,
653 .fs_brw_start = fsfilt_smfs_brw_start,
654 .fs_commit = fsfilt_smfs_commit,
655 .fs_commit_async = fsfilt_smfs_commit_async,
656 .fs_commit_wait = fsfilt_smfs_commit_wait,
657 .fs_setattr = fsfilt_smfs_setattr,
658 .fs_iocontrol = fsfilt_smfs_iocontrol,
659 .fs_set_md = fsfilt_smfs_set_md,
660 .fs_get_md = fsfilt_smfs_get_md,
661 .fs_readpage = fsfilt_smfs_readpage,
662 .fs_getpage = fsfilt_smfs_getpage,
663 .fs_add_journal_cb = fsfilt_smfs_add_journal_cb,
664 .fs_statfs = fsfilt_smfs_statfs,
665 .fs_sync = fsfilt_smfs_sync,
666 .fs_map_inode_page = fsfilt_smfs_map_inode_page,
667 .fs_prep_san_write = fsfilt_smfs_prep_san_write,
668 .fs_write_record = fsfilt_smfs_write_record,
669 .fs_read_record = fsfilt_smfs_read_record,
670 .fs_setup = fsfilt_smfs_setup,
671 .fs_send_bio = fsfilt_smfs_send_bio,
672 .fs_set_xattr = fsfilt_smfs_set_xattr,
673 .fs_get_xattr = fsfilt_smfs_get_xattr,
675 /* FIXME-UMKA: probably fsfilt_smfs_get_op_len() should be put here
679 static int __init fsfilt_smfs_init(void)
683 rc = fsfilt_register_ops(&fsfilt_smfs_ops);
687 static void __exit fsfilt_smfs_exit(void)
689 fsfilt_unregister_ops(&fsfilt_smfs_ops);
692 module_init(fsfilt_smfs_init);
693 module_exit(fsfilt_smfs_exit);
695 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
696 MODULE_DESCRIPTION("Lustre SMFS Filesystem Helper v0.1");
697 MODULE_LICENSE("GPL");