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) 2004 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 <libcfs/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 #include <linux/lustre_snap.h>
43 #include <linux/lustre_smfs.h>
44 static void *fsfilt_smfs_start(struct inode *inode, int op,
45 void *desc_private, int logs)
48 struct inode *cache_inode = I2CI(inode);
49 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
51 if (cache_fsfilt == NULL)
54 SMFS_TRANS_OP(inode, op);
56 if (!cache_fsfilt->fs_start)
57 return ERR_PTR(-ENOSYS);
59 handle = cache_fsfilt->fs_start(cache_inode, op, desc_private, logs);
63 static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
64 int niocount, struct niobuf_local *nb,
65 void *desc_private, int logs)
67 struct fsfilt_operations *cache_fsfilt;
68 struct dentry *cache_dentry = NULL;
69 struct inode *cache_inode = NULL;
70 struct fsfilt_objinfo cache_fso;
74 cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
75 if (cache_fsfilt == NULL)
78 cache_inode = I2CI(fso->fso_dentry->d_inode);
79 cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
81 GOTO(exit, rc = ERR_PTR(-ENOMEM));
83 cache_fso.fso_dentry = cache_dentry;
84 cache_fso.fso_bufcnt = fso->fso_bufcnt;
86 if (!cache_fsfilt->fs_brw_start)
87 GOTO(exit, rc = ERR_PTR(-ENOSYS));
89 rc = cache_fsfilt->fs_brw_start(objcount, &cache_fso, niocount, nb,
92 post_smfs_dentry(cache_dentry);
96 /* FIXME-WANGDI: here we can easily have inode == NULL due to
97 mds_open() behavior. It passes NULL inode to mds_finish_transno()
98 sometimes. Probably we should have spare way to get cache fsfilt
100 static int fsfilt_smfs_commit(struct super_block *sb, struct inode *inode,
101 void *h, int force_sync)
103 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
104 struct super_block *csb = S2CSB(sb);
105 struct inode *cache_inode = NULL;
111 cache_inode = I2CI(inode);
113 if (cache_fsfilt == NULL)
116 if (!cache_fsfilt->fs_commit)
119 rc = cache_fsfilt->fs_commit(csb, cache_inode, h, force_sync);
124 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
127 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
128 struct inode *cache_inode = NULL;
131 cache_inode = I2CI(inode);
132 if (cache_fsfilt == NULL)
135 if (!cache_fsfilt->fs_commit_async)
138 rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
143 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
145 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
146 struct inode *cache_inode = NULL;
149 cache_inode = I2CI(inode);
150 if (cache_fsfilt == NULL)
153 if (!cache_fsfilt->fs_commit_wait)
156 rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
161 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
162 struct iattr *iattr, int do_trunc)
164 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
165 struct dentry *cache_dentry = NULL;
166 struct inode *cache_inode = NULL;
172 if (!cache_fsfilt->fs_setattr)
175 cache_inode = I2CI(dentry->d_inode);
177 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
179 GOTO(exit, rc = -ENOMEM);
181 pre_smfs_inode(dentry->d_inode, cache_inode);
183 rc = cache_fsfilt->fs_setattr(cache_dentry, handle, iattr, do_trunc);
185 post_smfs_inode(dentry->d_inode, cache_inode);
188 struct super_block *sb = dentry->d_inode->i_sb;
190 if (SMFS_DO_REC(S2SMI(sb)) &&
191 SMFS_DO_INODE_REC(dentry->d_inode)) {
192 rc = smfs_rec_setattr(dentry->d_inode, dentry, iattr);
196 post_smfs_dentry(cache_dentry);
200 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
201 unsigned int cmd, unsigned long arg)
203 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
204 struct inode *cache_inode = NULL;
205 struct smfs_file_info *sfi = NULL;
212 cache_inode = I2CI(inode);
217 if (!cache_fsfilt->fs_iocontrol)
224 if (sfi->magic != SMFS_FILE_MAGIC)
231 rc = cache_fsfilt->fs_iocontrol(cache_inode, sfi->c_file, cmd,
234 rc = cache_fsfilt->fs_iocontrol(cache_inode, NULL, cmd, arg);
237 /* FIXME-UMKA: Should this be in duplicate_inode()? */
238 if (rc == 0 && cmd == EXT3_IOC_SETFLAGS)
239 inode->i_flags = cache_inode->i_flags;
241 post_smfs_inode(inode, cache_inode);
246 typedef int (*set_ea_func_t) (struct inode *, void *, void *, int);
247 typedef int (*get_ea_func_t) (struct inode *, void *, int);
249 static int fsfilt_smfs_set_ea(struct inode *inode, void *handle,
250 void *ea, int ea_size,
251 set_ea_func_t set_ea_func)
253 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
254 struct inode *cache_inode = NULL;
260 cache_inode = I2CI(inode);
268 pre_smfs_inode(inode, cache_inode);
270 down(&cache_inode->i_sem);
271 rc = set_ea_func(cache_inode, handle, ea, ea_size);
272 up(&cache_inode->i_sem);
274 post_smfs_inode(inode, cache_inode);
279 static int fsfilt_smfs_get_ea(struct inode *inode, void *ea,
280 int ea_size, get_ea_func_t get_ea_func)
282 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
283 struct inode *cache_inode = NULL;
289 cache_inode = I2CI(inode);
297 pre_smfs_inode(inode, cache_inode);
299 down(&cache_inode->i_sem);
300 rc = get_ea_func(cache_inode, ea, ea_size);
301 up(&cache_inode->i_sem);
303 post_smfs_inode(inode, cache_inode);
308 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
309 void *lmm, int lmm_size)
312 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
314 rc = fsfilt_smfs_set_ea(inode, handle, lmm, lmm_size,
315 cache_fsfilt->fs_set_md);
319 smfs_rec_md(inode, lmm, lmm_size);
323 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm, int
326 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
327 return fsfilt_smfs_get_ea(inode, lmm, lmm_size,
328 cache_fsfilt->fs_get_md);
331 static int fsfilt_smfs_set_mid(struct inode *inode, void *handle,
332 void *mid, int mid_size)
334 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
335 return fsfilt_smfs_set_ea(inode, handle, mid, mid_size,
336 cache_fsfilt->fs_set_mid);
339 static int fsfilt_smfs_get_mid(struct inode *inode, void *mid,
342 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
343 return fsfilt_smfs_get_ea(inode, mid, mid_size,
344 cache_fsfilt->fs_get_mid);
347 static int fsfilt_smfs_set_sid(struct inode *inode, void *handle,
348 void *sid, int sid_size)
350 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
351 return fsfilt_smfs_set_ea(inode, handle, sid, sid_size,
352 cache_fsfilt->fs_set_sid);
355 static int fsfilt_smfs_get_sid(struct inode *inode, void *sid,
358 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
359 return fsfilt_smfs_get_ea(inode, sid, sid_size,
360 cache_fsfilt->fs_get_sid);
363 static int fsfilt_smfs_send_bio(int rw, struct inode *inode, void *bio)
365 struct inode *cache_inode;
366 struct fsfilt_operations *cache_fsfilt;
370 cache_fsfilt = I2FOPS(inode);
374 cache_inode = I2CI(inode);
378 if (!cache_fsfilt->fs_send_bio)
381 return cache_fsfilt->fs_send_bio(rw, cache_inode, bio);
385 fsfilt_smfs_getpage(struct inode *inode, long int index)
387 struct fsfilt_operations *cache_fsfilt;
388 struct inode *cache_inode;
390 cache_fsfilt = I2FOPS(inode);
392 RETURN(ERR_PTR(-EINVAL));
394 cache_inode = I2CI(inode);
396 RETURN(ERR_PTR(-EINVAL));
398 if (!cache_fsfilt->fs_getpage)
399 RETURN(ERR_PTR(-ENOSYS));
401 if (SMFS_DO_COW(S2SMI(inode->i_sb))) {
402 struct address_space_operations *aops =
403 cache_inode->i_mapping->a_ops;
404 if (aops->bmap(cache_inode->i_mapping, index)) {
405 struct inode *ind_inode = NULL;
406 struct inode *cache_ind = NULL;
407 struct page *page = NULL;
409 ind_inode = smfs_cow_get_ind(inode, index);
411 RETURN(ERR_PTR(-EIO));
413 cache_ind = I2CI(ind_inode);
414 /*FIXME cow inode should be bottom fs inode */
415 page = cache_fsfilt->fs_getpage(cache_ind, index);
421 return cache_fsfilt->fs_getpage(cache_inode, index);
424 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
425 size_t count, loff_t *off)
427 struct fsfilt_operations *cache_fsfilt;
428 struct smfs_file_info *sfi;
429 struct inode *cache_inode;
436 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
440 cache_inode = I2CI(file->f_dentry->d_inode);
445 if (sfi->magic != SMFS_FILE_MAGIC)
448 if (off != &(file->f_pos))
449 cache_ppos = &tmp_ppos;
451 cache_ppos = &sfi->c_file->f_pos;
454 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
457 if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
458 struct fsfilt_operations *snapops =
459 I2SNAPOPS(file->f_dentry->d_inode);
461 LASSERT(S_ISDIR(file->f_dentry->d_inode->i_mode));
463 rc = snapops->fs_read_dotsnap_dir_page(sfi->c_file, buf, count,
466 if (cache_fsfilt->fs_readpage)
467 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
471 if (cache_fsfilt->fs_readpage)
472 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
477 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
478 duplicate_file(file, sfi->c_file);
484 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
485 struct super_block *sb, __u64 last_rcvd,
486 void *handle, fsfilt_cb_t cb_func,
489 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
490 struct super_block *csb = S2CSB(sb);
497 if (cache_fsfilt->fs_add_journal_cb)
498 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
499 handle, cb_func, cb_data);
503 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
505 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
506 struct super_block *csb = S2CSB(sb);
514 if (!cache_fsfilt->fs_statfs)
517 rc = cache_fsfilt->fs_statfs(csb, osfs);
518 duplicate_sb(csb, sb);
523 static int fsfilt_smfs_sync(struct super_block *sb)
525 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
526 struct super_block *csb = S2CSB(sb);
532 if (!cache_fsfilt->fs_sync)
535 rc = cache_fsfilt->fs_sync(csb);
540 int fsfilt_smfs_map_inode_pages(struct inode *inode, struct page **page,
541 int pages, unsigned long *blocks, int *created,
542 int create, struct semaphore *sem)
544 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
545 struct inode *cache_inode = NULL;
553 cache_inode = I2CI(inode);
558 if (!cache_fsfilt->fs_map_inode_pages)
561 down(&cache_inode->i_sem);
563 rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
564 created, create, sem);
565 up(&cache_inode->i_sem);
570 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
571 int nblocks, loff_t newsize)
573 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
574 struct inode *cache_inode = NULL;
580 cache_inode = I2CI(inode);
585 if (!cache_fsfilt->fs_prep_san_write)
588 down(&cache_inode->i_sem);
589 rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, nblocks,
591 up(&cache_inode->i_sem);
596 static int fsfilt_smfs_read_record(struct file * file, void *buf,
597 int size, loff_t *offs)
599 struct fsfilt_operations *cache_fsfilt;
600 struct inode *cache_inode;
601 struct smfs_file_info *sfi;
607 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
611 cache_inode = I2CI(file->f_dentry->d_inode);
617 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
619 if (offs != &(file->f_pos))
620 cache_ppos = &tmp_ppos;
622 cache_ppos = &sfi->c_file->f_pos;
625 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
627 if (!cache_fsfilt->fs_read_record)
630 rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, size, cache_ppos);
633 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
634 duplicate_file(file, sfi->c_file);
639 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
640 loff_t *offs, int force_sync)
642 struct fsfilt_operations *cache_fsfilt;
643 struct inode *cache_inode;
644 struct smfs_file_info *sfi;
651 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
655 cache_inode = I2CI(file->f_dentry->d_inode);
661 if (sfi->magic != SMFS_FILE_MAGIC)
664 if (offs != &(file->f_pos))
665 cache_ppos = &tmp_ppos;
667 cache_ppos = &sfi->c_file->f_pos;
670 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
672 if (!cache_fsfilt->fs_write_record)
675 rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
676 bufsize, cache_ppos, force_sync);
678 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
679 duplicate_file(file, sfi->c_file);
684 static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
685 struct dentry *root_dentry)
687 struct super_block *sb = NULL;
692 S2SMI(sb)->smsi_exp = obd->obd_self_export;
693 smfs_post_setup(sb, mnt);
694 if (SMFS_DO_REC(S2SMI(sb)))
695 rc = smfs_start_rec(sb, mnt);
699 obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT] =
700 S2SMI(sb)->smsi_rec_log;
704 CERROR("can not do post setup in obd %p rc=%d", obd, rc);
709 static int fsfilt_smfs_post_cleanup(struct obd_device *obd,
710 struct vfsmount *mnt)
712 struct super_block *sb = NULL;
718 if (SMFS_DO_REC(S2SMI(sb)))
719 rc = smfs_stop_rec(sb);
720 smfs_post_cleanup(sb);
725 static int fsfilt_smfs_set_fs_flags(struct inode *inode, int flags)
730 if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
731 SMFS_SET_INODE_REC(inode);
732 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
733 SMFS_SET_INODE_COW(inode);
737 static int fsfilt_smfs_clear_fs_flags(struct inode *inode, int flags)
742 if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
743 SMFS_CLEAN_INODE_REC(inode);
744 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
745 SMFS_CLEAN_INODE_COW(inode);
749 static int fsfilt_smfs_get_fs_flags(struct dentry *de)
751 struct inode *inode = de->d_inode;
757 if (SMFS_DO_REC(S2SMI(inode->i_sb)) && SMFS_DO_INODE_REC(inode))
759 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && SMFS_DO_INODE_COW(inode))
764 static int fsfilt_smfs_set_ost_flags(struct super_block *sb)
767 SET_REC_PACK_TYPE_INDEX(S2SMI(sb)->smsi_flags, PACK_OST);
771 static int fsfilt_smfs_set_mds_flags(struct super_block *sb)
774 SET_REC_PACK_TYPE_INDEX(S2SMI(sb)->smsi_flags, PACK_MDS);
778 static int fsfilt_smfs_get_reint_log_ctxt(struct super_block *sb,
779 struct llog_ctxt **ctxt)
781 struct smfs_super_info *smfs_info = S2SMI(sb);
784 *ctxt = smfs_info->smsi_rec_log;
788 static int fsfilt_smfs_setup(struct obd_device *obd, struct super_block *sb)
790 struct smfs_super_info *smfs_info = S2SMI(sb);
791 struct fsfilt_operations *cache_fsfilt;
792 struct super_block *csb;
795 /* It should be initialized olready by smfs_read_super(). */
796 if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
797 cache_fsfilt = fsfilt_get_ops(smfs_info->smsi_cache_ftype);
803 if (cache_fsfilt->fs_setup)
804 rc = cache_fsfilt->fs_setup(obd, csb);
806 duplicate_sb(sb, csb);
811 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle, char *name,
812 void *buffer, int buffer_size)
814 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
815 struct inode *cache_inode = NULL;
821 cache_inode = I2CI(inode);
825 pre_smfs_inode(inode, cache_inode);
827 if (cache_fsfilt->fs_set_xattr)
828 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
829 buffer, buffer_size);
830 post_smfs_inode(inode, cache_inode);
835 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
836 void *buffer, int buffer_size)
838 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
839 struct inode *cache_inode = NULL;
845 cache_inode = I2CI(inode);
849 pre_smfs_inode(inode, cache_inode);
851 if (cache_fsfilt->fs_get_xattr)
852 rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
853 buffer, buffer_size);
854 post_smfs_inode(inode, cache_inode);
859 static int fsfilt_smfs_insert_extents_ea(struct inode *inode,
860 unsigned long from, unsigned long num)
862 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
863 struct inode *cache_inode = NULL;
869 cache_inode = I2CI(inode);
873 pre_smfs_inode(inode, cache_inode);
875 if (cache_fsfilt->fs_insert_extents_ea)
876 rc = cache_fsfilt->fs_insert_extents_ea(cache_inode, from, num);
878 post_smfs_inode(inode, cache_inode);
882 static int fsfilt_smfs_remove_extents_ea(struct inode *inode,
883 unsigned long from, unsigned long num)
885 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
886 struct inode *cache_inode = NULL;
892 cache_inode = I2CI(inode);
896 pre_smfs_inode(inode, cache_inode);
898 if (cache_fsfilt->fs_remove_extents_ea)
899 rc = cache_fsfilt->fs_remove_extents_ea(cache_inode, from, num);
901 post_smfs_inode(inode, cache_inode);
905 static int fsfilt_smfs_init_extents_ea(struct inode *inode)
907 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
908 struct inode *cache_inode = NULL;
915 cache_inode = I2CI(inode);
919 pre_smfs_inode(inode, cache_inode);
921 if (cache_fsfilt->fs_init_extents_ea)
922 rc = cache_fsfilt->fs_init_extents_ea(cache_inode);
924 post_smfs_inode(inode, cache_inode);
928 static int fsfilt_smfs_free_extents(struct super_block *sb, ino_t ino,
929 char *pbuf, int size)
931 OBD_FREE(pbuf, size * (sizeof(struct ldlm_extent)));
935 static int fsfilt_smfs_write_extents(struct dentry *dentry,
936 unsigned long from, unsigned long num)
940 if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
941 rc = smfs_write_extents(dentry->d_inode, dentry, from, num);
946 static int fsfilt_smfs_precreate_rec(struct dentry *dentry, int *count,
951 if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
952 rc = smfs_rec_precreate(dentry, count, oa);
957 static int fsfilt_smfs_get_ino_write_extents(struct super_block *sb, ino_t ino,
958 char **pbuf, int *size)
960 struct fs_extent *fs_extents;
961 struct ldlm_extent *extents = NULL;
963 struct inode *cache_inode;
964 struct fsfilt_operations *cache_fsfilt = NULL;
965 struct lvfs_run_ctxt saved;
966 int rc = 0, fs_ex_size, ex_num, flags;
967 char *buf = NULL, *ex_buf = NULL;
970 push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
972 inode = iget(sb, ino);
974 if (!inode || is_bad_inode(inode)) {
975 CWARN("Can not get inode %lu ino\n", ino);
978 cache_inode = I2CI(inode);
979 cache_fsfilt = I2FOPS(inode);
981 rc = cache_fsfilt->fs_get_xattr(cache_inode, REINT_EXTENTS_FLAGS,
982 &flags, sizeof(int));
983 if (!(flags & SMFS_OVER_WRITE) && !(flags & SMFS_DIRTY_WRITE)) {
985 } else if (flags & SMFS_OVER_WRITE) {
987 OBD_ALLOC(ex_buf, sizeof(struct ldlm_extent));
989 GOTO(out, rc=-ENOMEM);
990 extents = (struct ldlm_extent*)(ex_buf);
992 extents->end = 0xffffffff;
996 rc = cache_fsfilt->fs_get_write_extents_num(cache_inode, &fs_ex_size);
999 OBD_ALLOC(buf, fs_ex_size);
1001 GOTO(out, rc=-ENOMEM);
1003 rc = cache_fsfilt->fs_get_inode_write_extents(cache_inode, &buf,
1008 ex_num = fs_ex_size / sizeof(struct fs_extent);
1010 OBD_ALLOC(ex_buf, ex_num* sizeof(struct ldlm_extent));
1012 GOTO(out, rc=-ENOMEM);
1014 fs_extents = (struct fs_extent*)(buf);
1015 extents = (struct ldlm_extent*)(ex_buf);
1016 while (ex_num > 0) {
1017 int blk_size = I2CI(inode)->i_blksize;
1019 extents->start = fs_extents->e_block * blk_size;
1020 extents->end = extents->start + fs_extents->e_num * blk_size;
1029 OBD_FREE(buf, fs_ex_size);
1031 OBD_FREE(ex_buf, (*size) * (sizeof(struct ldlm_extent)));
1032 pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
1036 static int fsfilt_smfs_set_snap_item(struct super_block *sb, char *name)
1042 #warning "still not implement for add snap item -wangdi"
1046 static int fsfilt_smfs_do_write_cow(struct dentry *de, void *extents,
1051 struct write_extents *w_ext = (struct write_extents *)extents;
1054 for (i = 0; i < num_extents; i++) {
1055 size_t count = w_ext->w_count;
1056 loff_t off = w_ext->w_pos;
1057 rc = smfs_cow_write_pre(de->d_inode, de, &count, &off);
1065 static struct fsfilt_operations fsfilt_smfs_ops = {
1067 .fs_owner = THIS_MODULE,
1068 .fs_start = fsfilt_smfs_start,
1069 .fs_brw_start = fsfilt_smfs_brw_start,
1070 .fs_commit = fsfilt_smfs_commit,
1071 .fs_commit_async = fsfilt_smfs_commit_async,
1072 .fs_commit_wait = fsfilt_smfs_commit_wait,
1073 .fs_setattr = fsfilt_smfs_setattr,
1074 .fs_iocontrol = fsfilt_smfs_iocontrol,
1075 .fs_set_md = fsfilt_smfs_set_md,
1076 .fs_get_md = fsfilt_smfs_get_md,
1077 .fs_set_mid = fsfilt_smfs_set_mid,
1078 .fs_get_mid = fsfilt_smfs_get_mid,
1079 .fs_set_sid = fsfilt_smfs_set_sid,
1080 .fs_get_sid = fsfilt_smfs_get_sid,
1081 .fs_readpage = fsfilt_smfs_readpage,
1082 .fs_getpage = fsfilt_smfs_getpage,
1083 .fs_add_journal_cb = fsfilt_smfs_add_journal_cb,
1084 .fs_statfs = fsfilt_smfs_statfs,
1085 .fs_sync = fsfilt_smfs_sync,
1086 .fs_map_inode_pages = fsfilt_smfs_map_inode_pages,
1087 .fs_prep_san_write = fsfilt_smfs_prep_san_write,
1088 .fs_write_record = fsfilt_smfs_write_record,
1089 .fs_read_record = fsfilt_smfs_read_record,
1090 .fs_setup = fsfilt_smfs_setup,
1091 .fs_post_setup = fsfilt_smfs_post_setup,
1092 .fs_post_cleanup = fsfilt_smfs_post_cleanup,
1093 .fs_set_fs_flags = fsfilt_smfs_set_fs_flags,
1094 .fs_clear_fs_flags = fsfilt_smfs_clear_fs_flags,
1095 .fs_get_fs_flags = fsfilt_smfs_get_fs_flags,
1096 .fs_set_ost_flags = fsfilt_smfs_set_ost_flags,
1097 .fs_set_mds_flags = fsfilt_smfs_set_mds_flags,
1098 .fs_precreate_rec = fsfilt_smfs_precreate_rec,
1099 .fs_get_reint_log_ctxt = fsfilt_smfs_get_reint_log_ctxt,
1100 .fs_send_bio = fsfilt_smfs_send_bio,
1101 .fs_set_xattr = fsfilt_smfs_set_xattr,
1102 .fs_get_xattr = fsfilt_smfs_get_xattr,
1103 .fs_init_extents_ea = fsfilt_smfs_init_extents_ea,
1104 .fs_insert_extents_ea = fsfilt_smfs_insert_extents_ea,
1105 .fs_remove_extents_ea = fsfilt_smfs_remove_extents_ea,
1106 .fs_get_ino_write_extents = fsfilt_smfs_get_ino_write_extents,
1107 .fs_free_write_extents = fsfilt_smfs_free_extents,
1108 .fs_write_extents = fsfilt_smfs_write_extents,
1109 .fs_set_snap_item = fsfilt_smfs_set_snap_item,
1110 .fs_do_write_cow = fsfilt_smfs_do_write_cow,
1113 static int __init fsfilt_smfs_init(void)
1117 rc = fsfilt_register_ops(&fsfilt_smfs_ops);
1121 static void __exit fsfilt_smfs_exit(void)
1123 fsfilt_unregister_ops(&fsfilt_smfs_ops);
1126 module_init(fsfilt_smfs_init);
1127 module_exit(fsfilt_smfs_exit);
1129 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1130 MODULE_DESCRIPTION("Lustre SMFS Filesystem Helper v0.1");
1131 MODULE_LICENSE("GPL");