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>
40 #include <linux/init.h>
42 static void *fsfilt_smfs_start(struct inode *inode, int op,
43 void *desc_private, int logs)
46 struct inode *cache_inode = I2CI(inode);
47 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
49 if (cache_fsfilt == NULL)
52 if (!cache_fsfilt->fs_start)
53 return ERR_PTR(-ENOSYS);
55 handle = cache_fsfilt->fs_start(cache_inode, op,
60 static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
61 int niocount, struct niobuf_local *nb,
62 void *desc_private, int logs)
64 struct fsfilt_operations *cache_fsfilt;
65 struct dentry *cache_dentry = NULL;
66 struct inode *cache_inode = NULL;
67 struct fsfilt_objinfo cache_fso;
71 cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
72 if (cache_fsfilt == NULL)
75 cache_inode = I2CI(fso->fso_dentry->d_inode);
76 cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
79 GOTO(exit, rc = ERR_PTR(-ENOMEM));
81 cache_fso.fso_dentry = cache_dentry;
82 cache_fso.fso_bufcnt = fso->fso_bufcnt;
84 if (!cache_fsfilt->fs_brw_start)
85 return ERR_PTR(-ENOSYS);
87 rc = (cache_fsfilt->fs_brw_start(objcount, &cache_fso,
88 niocount, nb, desc_private,
91 post_smfs_dentry(cache_dentry);
95 static int fsfilt_smfs_commit(struct inode *inode, void *h,
98 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
99 struct inode *cache_inode = NULL;
102 cache_inode = I2CI(inode);
104 if (cache_fsfilt == NULL)
107 if (!cache_fsfilt->fs_commit)
110 rc = cache_fsfilt->fs_commit(cache_inode, h, force_sync);
115 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
118 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
119 struct inode *cache_inode = NULL;
122 cache_inode = I2CI(inode);
123 if (cache_fsfilt == NULL)
126 if (!cache_fsfilt->fs_commit_async)
129 rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
134 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
136 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
137 struct inode *cache_inode = NULL;
140 cache_inode = I2CI(inode);
141 if (cache_fsfilt == NULL)
144 if (!cache_fsfilt->fs_commit_wait)
147 rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
152 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
153 struct iattr *iattr, int do_trunc)
155 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
156 struct dentry *cache_dentry = NULL;
157 struct inode *cache_inode = NULL;
163 cache_inode = I2CI(dentry->d_inode);
165 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
167 GOTO(exit, rc = -ENOMEM);
169 pre_smfs_inode(dentry->d_inode, cache_inode);
171 if (!cache_fsfilt->fs_setattr)
174 rc = cache_fsfilt->fs_setattr(cache_dentry, handle,
177 post_smfs_inode(dentry->d_inode, cache_inode);
180 post_smfs_dentry(cache_dentry);
184 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
185 unsigned int cmd, unsigned long arg)
187 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
188 struct inode *cache_inode = NULL;
189 struct smfs_file_info *sfi = NULL;
196 cache_inode = I2CI(inode);
204 if (sfi->magic != SMFS_FILE_MAGIC)
210 if (!cache_fsfilt->fs_iocontrol)
214 rc = cache_fsfilt->fs_iocontrol(cache_inode,
218 rc = cache_fsfilt->fs_iocontrol(cache_inode,
222 /* FIXME-UMKA: Should this be in duplicate_inode()? */
223 if (rc == 0 && cmd == EXT3_IOC_SETFLAGS)
224 inode->i_flags = cache_inode->i_flags;
226 post_smfs_inode(inode, cache_inode);
231 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
232 void *lmm, int lmm_size)
234 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
235 struct inode *cache_inode = NULL;
241 cache_inode = I2CI(inode);
246 pre_smfs_inode(inode, cache_inode);
248 if (!cache_fsfilt->fs_set_md)
251 down(&cache_inode->i_sem);
253 rc = cache_fsfilt->fs_set_md(cache_inode, handle,
256 up(&cache_inode->i_sem);
258 post_smfs_inode(inode, cache_inode);
263 /* Must be called with i_sem held */
264 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm, int lmm_size)
266 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
267 struct inode *cache_inode = NULL;
273 cache_inode = I2CI(inode);
278 pre_smfs_inode(inode, cache_inode);
280 if (!cache_fsfilt->fs_get_md)
283 down(&cache_inode->i_sem);
285 rc = cache_fsfilt->fs_get_md(cache_inode, lmm,
288 up(&cache_inode->i_sem);
290 post_smfs_inode(inode, cache_inode);
295 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
296 static int fsfilt_smfs_send_bio(struct inode *inode,
299 static int fsfilt_smfs_send_bio(struct inode *inode,
303 struct inode *cache_inode;
304 struct fsfilt_operations *cache_fsfilt;
306 cache_fsfilt = I2FOPS(inode);
310 cache_inode = I2CI(inode);
314 if (!cache_fsfilt->fs_send_bio)
317 return cache_fsfilt->fs_send_bio(cache_inode, bio);
321 fsfilt_smfs_getpage(struct inode *inode, long int index)
323 struct fsfilt_operations *cache_fsfilt;
324 struct inode *cache_inode;
326 cache_fsfilt = I2FOPS(inode);
328 RETURN(ERR_PTR(-EINVAL));
330 cache_inode = I2CI(inode);
332 RETURN(ERR_PTR(-EINVAL));
334 if (!cache_fsfilt->fs_getpage)
335 RETURN(ERR_PTR(-ENOSYS));
337 return cache_fsfilt->fs_getpage(cache_inode, index);
340 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
341 size_t count, loff_t *off)
343 struct fsfilt_operations *cache_fsfilt;
344 struct smfs_file_info *sfi;
345 struct inode *cache_inode;
352 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
356 cache_inode = I2CI(file->f_dentry->d_inode);
361 if (sfi->magic != SMFS_FILE_MAGIC)
364 if (off != &(file->f_pos)) {
365 cache_ppos = &tmp_ppos;
367 cache_ppos = &sfi->c_file->f_pos;
371 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
373 if (cache_fsfilt->fs_readpage)
374 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf,
378 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
379 duplicate_file(file, sfi->c_file);
384 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
385 struct super_block *sb,
386 __u64 last_rcvd, void *handle,
390 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
391 struct super_block *csb = S2CSB(sb);
396 if (cache_fsfilt->fs_add_journal_cb)
397 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
398 handle, cb_func, cb_data);
402 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
404 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
405 struct super_block *csb = S2CSB(sb);
411 if (!cache_fsfilt->fs_statfs)
414 rc = cache_fsfilt->fs_statfs(csb, osfs);
415 duplicate_sb(csb, sb);
420 static int fsfilt_smfs_sync(struct super_block *sb)
422 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
423 struct super_block *csb = S2CSB(sb);
429 if (!cache_fsfilt->fs_sync)
432 rc = cache_fsfilt->fs_sync(csb);
437 int fsfilt_smfs_map_inode_pages(struct inode *inode, struct page **page,
438 int pages, unsigned long *blocks,
439 int *created, int create,
440 struct semaphore *sem)
442 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
443 struct inode *cache_inode = NULL;
449 cache_inode = I2CI(inode);
454 if (!cache_fsfilt->fs_map_inode_pages)
457 down(&cache_inode->i_sem);
458 rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
459 created, create, NULL);
460 up(&cache_inode->i_sem);
465 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
466 int nblocks, loff_t newsize)
468 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
469 struct inode *cache_inode = NULL;
475 cache_inode = I2CI(inode);
480 if (!cache_fsfilt->fs_prep_san_write)
483 down(&cache_inode->i_sem);
484 rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks,
486 up(&cache_inode->i_sem);
491 static int fsfilt_smfs_read_record(struct file * file, void *buf,
492 int size, loff_t *offs)
494 struct fsfilt_operations *cache_fsfilt;
495 struct inode *cache_inode;
496 struct smfs_file_info *sfi;
502 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
506 cache_inode = I2CI(file->f_dentry->d_inode);
512 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
514 if (offs != &(file->f_pos)) {
515 cache_ppos = &tmp_ppos;
517 cache_ppos = &sfi->c_file->f_pos;
521 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
523 if (!cache_fsfilt->fs_read_record)
526 rc = cache_fsfilt->fs_read_record(sfi->c_file, buf,
530 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
531 duplicate_file(file, sfi->c_file);
536 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
537 loff_t *offs, int force_sync)
539 struct fsfilt_operations *cache_fsfilt;
540 struct inode *cache_inode;
541 struct smfs_file_info *sfi;
548 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
552 cache_inode = I2CI(file->f_dentry->d_inode);
558 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
560 if (offs != &(file->f_pos)) {
561 cache_ppos = &tmp_ppos;
563 cache_ppos = &sfi->c_file->f_pos;
567 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
569 if (!cache_fsfilt->fs_write_record)
572 rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
573 bufsize, cache_ppos, force_sync);
575 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
576 duplicate_file(file, sfi->c_file);
581 static int fsfilt_smfs_setup(struct super_block *sb)
583 struct smfs_super_info *smfs_info = S2SMI(sb);
584 struct fsfilt_operations *cache_fsfilt;
585 struct super_block *csb;
588 /* It should be initialized olready by smfs_read_super(). */
589 if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
590 cache_fsfilt = fsfilt_get_ops(smfs_info->cache_fs_type);
597 if (cache_fsfilt->fs_setup)
598 rc = cache_fsfilt->fs_setup(csb);
603 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle,
604 char *name, void *buffer,
607 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
608 struct inode *cache_inode = NULL;
614 cache_inode = I2CI(inode);
618 pre_smfs_inode(inode, cache_inode);
620 if (cache_fsfilt->fs_set_xattr)
621 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
622 buffer, buffer_size);
623 post_smfs_inode(inode, cache_inode);
628 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
629 void *buffer, int buffer_size)
631 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
632 struct inode *cache_inode = NULL;
638 cache_inode = I2CI(inode);
642 pre_smfs_inode(inode, cache_inode);
644 if (cache_fsfilt->fs_get_xattr)
645 rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
646 buffer, buffer_size);
647 post_smfs_inode(inode, cache_inode);
652 static struct fsfilt_operations fsfilt_smfs_ops = {
654 .fs_owner = THIS_MODULE,
655 .fs_start = fsfilt_smfs_start,
656 .fs_brw_start = fsfilt_smfs_brw_start,
657 .fs_commit = fsfilt_smfs_commit,
658 .fs_commit_async = fsfilt_smfs_commit_async,
659 .fs_commit_wait = fsfilt_smfs_commit_wait,
660 .fs_setattr = fsfilt_smfs_setattr,
661 .fs_iocontrol = fsfilt_smfs_iocontrol,
662 .fs_set_md = fsfilt_smfs_set_md,
663 .fs_get_md = fsfilt_smfs_get_md,
664 .fs_readpage = fsfilt_smfs_readpage,
665 .fs_getpage = fsfilt_smfs_getpage,
666 .fs_add_journal_cb = fsfilt_smfs_add_journal_cb,
667 .fs_statfs = fsfilt_smfs_statfs,
668 .fs_sync = fsfilt_smfs_sync,
669 .fs_map_inode_pages = fsfilt_smfs_map_inode_pages,
670 .fs_prep_san_write = fsfilt_smfs_prep_san_write,
671 .fs_write_record = fsfilt_smfs_write_record,
672 .fs_read_record = fsfilt_smfs_read_record,
673 .fs_setup = fsfilt_smfs_setup,
674 .fs_send_bio = fsfilt_smfs_send_bio,
675 .fs_set_xattr = fsfilt_smfs_set_xattr,
676 .fs_get_xattr = fsfilt_smfs_get_xattr,
678 /* FIXME-UMKA: probably fsfilt_smfs_get_op_len() should be put here
682 static int __init fsfilt_smfs_init(void)
686 rc = fsfilt_register_ops(&fsfilt_smfs_ops);
690 static void __exit fsfilt_smfs_exit(void)
692 fsfilt_unregister_ops(&fsfilt_smfs_ops);
695 module_init(fsfilt_smfs_init);
696 module_exit(fsfilt_smfs_exit);
698 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
699 MODULE_DESCRIPTION("Lustre SMFS Filesystem Helper v0.1");
700 MODULE_LICENSE("GPL");