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_SM
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/obd.h>
36 #include <linux/obd_class.h>
38 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
40 #include <linux/lustre_snap.h>
42 #include "smfs_internal.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);
53 if (cache_fsfilt == NULL)
56 if (!cache_fsfilt->fs_start)
57 return ERR_PTR(-ENOSYS);
59 //opcode can be changed here.
60 //For example, unlink is rename in nature for undo plugin
61 extra = SMFS_PLG_HELP(inode->i_sb, PLG_TRANS_SIZE, &opcode);
63 handle = cache_fsfilt->fs_start(cache_inode, op, desc_private,
69 static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
70 int niocount, struct niobuf_local *nb,
71 void *desc_private, int logs)
73 struct fsfilt_operations *cache_fsfilt;
74 struct dentry *cache_dentry = NULL;
75 struct inode *cache_inode = NULL;
76 struct fsfilt_objinfo cache_fso;
81 cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
82 if (cache_fsfilt == NULL)
85 cache_inode = I2CI(fso->fso_dentry->d_inode);
86 cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
88 RETURN(ERR_PTR(-ENOMEM));
90 cache_fso.fso_dentry = cache_dentry;
91 cache_fso.fso_bufcnt = fso->fso_bufcnt;
93 if (!cache_fsfilt->fs_brw_start) {
94 rc = ERR_PTR(-ENOSYS);
98 rc = cache_fsfilt->fs_brw_start(objcount, &cache_fso, niocount, nb,
101 post_smfs_dentry(cache_dentry);
105 /* FIXME-WANGDI: here we can easily have inode == NULL due to
106 mds_open() behavior. It passes NULL inode to mds_finish_transno()
107 sometimes. Probably we should have spare way to get cache fsfilt
109 static int fsfilt_smfs_commit(struct super_block *sb, struct inode *inode,
110 void *h, int force_sync)
112 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
113 struct super_block *csb = S2CSB(sb);
114 struct inode *cache_inode = NULL;
120 cache_inode = I2CI(inode);
122 if (cache_fsfilt == NULL)
125 if (!cache_fsfilt->fs_commit)
128 rc = cache_fsfilt->fs_commit(csb, cache_inode, h, force_sync);
133 static int fsfilt_smfs_commit_async(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_async)
147 rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
152 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
154 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
155 struct inode *cache_inode = NULL;
158 cache_inode = I2CI(inode);
159 if (cache_fsfilt == NULL)
162 if (!cache_fsfilt->fs_commit_wait)
165 rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
170 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
171 unsigned int cmd, unsigned long arg)
173 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
174 struct inode *cache_inode = I2CI(inode);
175 struct smfs_file_info *sfi = NULL;
176 struct file * cache_file = NULL;
180 if (!cache_fsfilt || !cache_inode)
183 if (!cache_fsfilt->fs_iocontrol)
189 if (sfi->magic != SMFS_FILE_MAGIC)
191 cache_file = sfi->c_file;
194 pre_smfs_inode(inode, cache_inode);
196 rc = cache_fsfilt->fs_iocontrol(cache_inode, cache_file, cmd, arg);
198 post_smfs_inode(inode, cache_inode);
203 static int fsfilt_smfs_send_bio(int rw, struct inode *inode, void *bio)
205 struct inode *cache_inode;
206 struct fsfilt_operations *cache_fsfilt;
210 cache_fsfilt = I2FOPS(inode);
214 cache_inode = I2CI(inode);
218 if (!cache_fsfilt->fs_send_bio)
221 return cache_fsfilt->fs_send_bio(rw, cache_inode, bio);
224 static struct page * fsfilt_smfs_getpage(struct inode *inode, long int index)
226 struct fsfilt_operations *cache_fsfilt;
227 struct inode *cache_inode;
229 cache_fsfilt = I2FOPS(inode);
231 RETURN(ERR_PTR(-EINVAL));
233 cache_inode = I2CI(inode);
235 RETURN(ERR_PTR(-EINVAL));
237 if (!cache_fsfilt->fs_getpage)
238 RETURN(ERR_PTR(-ENOSYS));
240 if (SMFS_DO_COW(S2SMI(inode->i_sb))) {
241 struct address_space_operations *aops =
242 cache_inode->i_mapping->a_ops;
243 if (aops->bmap(cache_inode->i_mapping, index)) {
244 struct inode *ind_inode = NULL;
245 struct inode *cache_ind = NULL;
246 struct page *page = NULL;
248 ind_inode = smfs_cow_get_ind(inode, index);
250 RETURN(ERR_PTR(-EIO));
252 cache_ind = I2CI(ind_inode);
253 /*FIXME cow inode should be bottom fs inode */
254 page = cache_fsfilt->fs_getpage(cache_ind, index);
260 return cache_fsfilt->fs_getpage(cache_inode, index);
263 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
264 size_t count, loff_t *off)
266 struct fsfilt_operations *cache_fsfilt;
267 struct smfs_file_info *sfi;
268 struct inode *cache_inode;
272 struct hook_msg msg = {
273 .dentry = file->f_dentry,
278 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
282 cache_inode = I2CI(file->f_dentry->d_inode);
287 if (sfi->magic != SMFS_FILE_MAGIC)
290 if (off != &(file->f_pos))
291 cache_ppos = &tmp_ppos;
293 cache_ppos = &sfi->c_file->f_pos;
296 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
297 SMFS_PRE_HOOK(file->f_dentry->d_inode, HOOK_READDIR, &msg);
301 if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
302 struct fsfilt_operations *snapops =
303 I2SNAPOPS(file->f_dentry->d_inode);
305 LASSERT(S_ISDIR(file->f_dentry->d_inode->i_mode));
307 rc = snapops->fs_read_dotsnap_dir_page(sfi->c_file, buf, count,
310 if (cache_fsfilt->fs_readpage)
311 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
315 if (cache_fsfilt->fs_readpage)
316 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
320 SMFS_POST_HOOK(file->f_dentry->d_inode, HOOK_READDIR, &msg, rc);
322 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
323 duplicate_file(file, sfi->c_file);
329 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
330 struct super_block *sb, __u64 last_rcvd,
331 void *handle, fsfilt_cb_t cb_func,
334 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
335 struct super_block *csb = S2CSB(sb);
342 if (cache_fsfilt->fs_add_journal_cb)
343 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
344 handle, cb_func, cb_data);
348 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
350 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
351 struct super_block *csb = S2CSB(sb);
359 if (!cache_fsfilt->fs_statfs)
362 rc = cache_fsfilt->fs_statfs(csb, osfs);
363 duplicate_sb(csb, sb);
368 static int fsfilt_smfs_sync(struct super_block *sb)
370 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
371 struct super_block *csb = S2CSB(sb);
377 if (cache_fsfilt->fs_sync)
378 rc = cache_fsfilt->fs_sync(csb);
383 int fsfilt_smfs_map_inode_pages(struct inode *inode, struct page **page,
384 int pages, unsigned long *blocks, int *created,
385 int create, struct semaphore *sem)
387 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
388 struct inode *cache_inode = NULL;
391 struct hook_rw_msg msg = {
400 cache_inode = I2CI(inode);
405 if (!cache_fsfilt->fs_map_inode_pages)
408 down(&cache_inode->i_sem);
409 //SMFS_PRE_HOOK(inode, HOOK_MAP_PAGES, &msg);
411 rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
412 created, create, sem);
414 up(&cache_inode->i_sem);
419 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
420 int nblocks, loff_t newsize)
422 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
423 struct inode *cache_inode = NULL;
429 cache_inode = I2CI(inode);
434 if (!cache_fsfilt->fs_prep_san_write)
437 down(&cache_inode->i_sem);
438 rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, nblocks,
440 up(&cache_inode->i_sem);
445 static int fsfilt_smfs_read_record(struct file * file, void *buf,
446 int size, loff_t *offs)
448 struct fsfilt_operations *cache_fsfilt;
449 struct inode *cache_inode;
450 struct smfs_file_info *sfi;
456 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
460 cache_inode = I2CI(file->f_dentry->d_inode);
466 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
468 if (offs != &(file->f_pos))
469 cache_ppos = &tmp_ppos;
471 cache_ppos = &sfi->c_file->f_pos;
474 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
476 if (!cache_fsfilt->fs_read_record)
479 rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, size, cache_ppos);
482 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
483 duplicate_file(file, sfi->c_file);
488 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
489 loff_t *offs, int force_sync)
491 struct fsfilt_operations *cache_fsfilt;
492 struct inode *cache_inode;
493 struct smfs_file_info *sfi;
500 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
504 cache_inode = I2CI(file->f_dentry->d_inode);
510 if (sfi->magic != SMFS_FILE_MAGIC)
513 if (offs != &(file->f_pos))
514 cache_ppos = &tmp_ppos;
516 cache_ppos = &sfi->c_file->f_pos;
519 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
521 if (!cache_fsfilt->fs_write_record)
524 rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
525 bufsize, cache_ppos, force_sync);
527 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
528 duplicate_file(file, sfi->c_file);
533 static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
534 struct dentry *root_dentry)//, void *data)
536 struct super_block *sb = NULL;
545 S2SMI(sb)->smsi_exp = obd->obd_self_export;
547 rc = smfs_post_setup(obd, mnt, root_dentry);//, data);
549 CERROR("post_setup fails in obd %p rc=%d", obd, rc);
556 static int fsfilt_smfs_post_cleanup(struct obd_device *obd,
557 struct vfsmount *mnt)
559 struct super_block *sb = NULL;
565 smfs_post_cleanup(sb);
571 static int fsfilt_smfs_set_fs_flags(struct inode *inode, int flags)
576 if (flags & SM_ALL_PLG) /* enable all plugins */
577 SMFS_SET(I2SMI(inode)->smi_flags, SMFS_PLG_ALL);
579 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
580 SMFS_SET_INODE_COW(inode);
585 static int fsfilt_smfs_clear_fs_flags(struct inode *inode, int flags)
590 if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
591 SMFS_CLEAN_INODE_REC(inode);
592 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
593 SMFS_CLEAN_INODE_COW(inode);
595 if(flags & SM_ALL_PLG) /* disable all plugins */
596 SMFS_CLEAR(I2SMI(inode)->smi_flags, SMFS_PLG_ALL);
600 static int fsfilt_smfs_get_fs_flags(struct dentry *de)
602 struct inode *inode = de->d_inode;
608 flags = I2SMI(inode)->smi_flags & S2SMI(inode->i_sb)->plg_flags;
613 static int fsfilt_smfs_set_ost_flags(struct super_block *sb)
618 static int fsfilt_smfs_set_mds_flags(struct super_block *sb)
624 static int fsfilt_smfs_get_reint_log_ctxt(struct super_block *sb,
625 struct llog_ctxt **ctxt)
627 struct smfs_super_info *smfs_info = S2SMI(sb);
630 *ctxt = smfs_info->smsi_kml_log;
635 static int fsfilt_smfs_setup(struct obd_device *obd, struct super_block *sb)
637 struct smfs_super_info *smfs_info = S2SMI(sb);
638 struct fsfilt_operations *cache_fsfilt;
639 struct super_block *csb;
644 /* It should be initialized olready by smfs_read_super(). */
645 if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
646 cache_fsfilt = fsfilt_get_ops(smfs_info->smsi_cache_ftype);
652 if (cache_fsfilt->fs_setup)
653 rc = cache_fsfilt->fs_setup(obd, csb);
655 duplicate_sb(sb, csb);
660 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
661 struct iattr *iattr, int do_trunc)
663 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
664 struct dentry *cache_dentry = NULL;
665 struct inode *cache_inode = I2CI(dentry->d_inode);
666 struct smfs_super_info *sbi = S2SMI(dentry->d_inode->i_sb);
667 struct hook_attr_msg msg = {
676 if (!cache_fsfilt->fs_setattr)
679 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
683 pre_smfs_inode(dentry->d_inode, cache_inode);
685 SMFS_PRE_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg);
687 if (SMFS_DO_HND_IBLOCKS(sbi)) {
688 /* size-on-mds changes i_blocks directly to reflect
689 * aggregated i_blocks from all OSTs -bzzz */
690 cache_inode->i_blocks = dentry->d_inode->i_blocks;
693 rc = cache_fsfilt->fs_setattr(cache_dentry, handle, iattr, do_trunc);
695 SMFS_POST_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg, rc);
696 post_smfs_inode(dentry->d_inode, cache_inode);
698 post_smfs_dentry(cache_dentry);
701 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle, char *name,
702 void *buffer, int buffer_size)
704 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
705 struct inode *cache_inode = NULL;
706 struct hook_xattr_msg msg = {
709 .buffer_size = buffer_size
718 cache_inode = I2CI(inode);
722 pre_smfs_inode(inode, cache_inode);
723 SMFS_PRE_HOOK(inode, HOOK_F_SETXATTR, &msg);
724 if (cache_fsfilt->fs_set_xattr)
725 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
726 buffer, buffer_size);
728 SMFS_POST_HOOK(inode, HOOK_F_SETXATTR, &msg, rc);
729 post_smfs_inode(inode, cache_inode);
734 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
735 void *buffer, int buffer_size)
737 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
738 struct inode *cache_inode = NULL;
744 cache_inode = I2CI(inode);
748 pre_smfs_inode(inode, cache_inode);
749 if (cache_fsfilt->fs_get_xattr)
750 rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
751 buffer, buffer_size);
752 post_smfs_inode(inode, cache_inode);
757 #define XATTR_LUSTRE_MDS_LOV_EA "lov"
758 #define XATTR_LUSTRE_MDS_MEA_EA "mea"
759 #define XATTR_LUSTRE_MDS_MID_EA "mid"
760 #define XATTR_LUSTRE_MDS_SID_EA "sid"
761 #define XATTR_LUSTRE_MDS_PID_EA "pid"
762 #define XATTR_LUSTRE_MDS_KEY_EA "key"
764 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
765 void *lmm, int lmm_size, enum ea_type type)
771 rc = fsfilt_smfs_set_xattr(inode, handle,
772 XATTR_LUSTRE_MDS_LOV_EA,
776 rc = fsfilt_smfs_set_xattr(inode, handle,
777 XATTR_LUSTRE_MDS_MEA_EA,
781 rc = fsfilt_smfs_set_xattr(inode, handle,
782 XATTR_LUSTRE_MDS_SID_EA,
786 rc = fsfilt_smfs_set_xattr(inode, handle,
787 XATTR_LUSTRE_MDS_MID_EA,
791 rc = fsfilt_smfs_set_xattr(inode, handle,
792 XATTR_LUSTRE_MDS_PID_EA,
796 rc = fsfilt_smfs_set_xattr(inode, handle,
797 XATTR_LUSTRE_MDS_KEY_EA,
807 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm,
808 int lmm_size, enum ea_type type)
814 rc = fsfilt_smfs_get_xattr(inode,
815 XATTR_LUSTRE_MDS_LOV_EA,
819 rc = fsfilt_smfs_get_xattr(inode,
820 XATTR_LUSTRE_MDS_MEA_EA,
824 rc = fsfilt_smfs_get_xattr(inode,
825 XATTR_LUSTRE_MDS_SID_EA,
829 rc = fsfilt_smfs_get_xattr(inode,
830 XATTR_LUSTRE_MDS_MID_EA,
834 rc = fsfilt_smfs_get_xattr(inode,
835 XATTR_LUSTRE_MDS_PID_EA,
839 rc = fsfilt_smfs_get_xattr(inode,
840 XATTR_LUSTRE_MDS_KEY_EA,
850 static int fsfilt_smfs_insert_extents_ea(struct inode *inode,
851 unsigned long from, unsigned long num)
853 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
854 struct inode *cache_inode = NULL;
860 cache_inode = I2CI(inode);
864 pre_smfs_inode(inode, cache_inode);
866 if (cache_fsfilt->fs_insert_extents_ea)
867 rc = cache_fsfilt->fs_insert_extents_ea(cache_inode, from, num);
869 post_smfs_inode(inode, cache_inode);
873 static int fsfilt_smfs_remove_extents_ea(struct inode *inode,
874 unsigned long from, unsigned long num)
876 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
877 struct inode *cache_inode = NULL;
883 cache_inode = I2CI(inode);
887 pre_smfs_inode(inode, cache_inode);
889 if (cache_fsfilt->fs_remove_extents_ea)
890 rc = cache_fsfilt->fs_remove_extents_ea(cache_inode, from, num);
892 post_smfs_inode(inode, cache_inode);
896 static int fsfilt_smfs_init_extents_ea(struct inode *inode)
898 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
899 struct inode *cache_inode = NULL;
906 cache_inode = I2CI(inode);
910 pre_smfs_inode(inode, cache_inode);
912 if (cache_fsfilt->fs_init_extents_ea)
913 rc = cache_fsfilt->fs_init_extents_ea(cache_inode);
915 post_smfs_inode(inode, cache_inode);
919 static int fsfilt_smfs_free_extents(struct super_block *sb, ino_t ino,
920 char *pbuf, int size)
922 OBD_FREE(pbuf, size * (sizeof(struct ldlm_extent)));
926 static int fsfilt_smfs_write_extents(struct dentry *dentry,
927 unsigned long from, unsigned long num)
929 /* TODO: fix this later */
932 struct inode * cache_inode = I2CI(dentry->d_inode);
933 struct hook_write_msg msg = {
941 pre_smfs_inode(dentry->d_inode, cache_inode);
943 SMFS_PRE_HOOK(dentry->d_inode, HOOK_WRITE, &msg);
945 rc = smfs_write_extents(dentry->d_inode, dentry, from, num);
946 SMFS_POST_HOOK(dentry->d_inode, HOOK_WRITE, &msg, rc);
947 post_smfs_inode(dentry->d_inode, cache_inode);
955 static int fsfilt_smfs_precreate_rec(struct dentry *dentry, int *count,
959 /* Why to log precreate?? MDS will do this in any case
960 if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
961 rc = smfs_rec_precreate(dentry, count, oa);
966 // should be rewrote when needed
967 static int fsfilt_smfs_get_ino_write_extents(struct super_block *sb, ino_t ino,
968 char **pbuf, int *size)
972 struct fs_extent *fs_extents;
973 struct ldlm_extent *extents = NULL;
975 struct inode *cache_inode;
976 struct fsfilt_operations *cache_fsfilt = NULL;
977 struct lvfs_run_ctxt saved;
978 int fs_ex_size, ex_num, flags;
979 char *buf = NULL, *ex_buf = NULL;
982 push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
984 inode = iget(sb, ino);
986 if (!inode || is_bad_inode(inode)) {
987 CWARN("Can not get inode %lu ino\n", ino);
990 cache_inode = I2CI(inode);
991 cache_fsfilt = I2FOPS(inode);
993 rc = cache_fsfilt->fs_get_xattr(cache_inode, REINT_EXTENTS_FLAGS,
994 &flags, sizeof(int));
995 if (!(flags & SMFS_OVER_WRITE) && !(flags & SMFS_DIRTY_WRITE)) {
997 } else if (flags & SMFS_OVER_WRITE) {
999 OBD_ALLOC(ex_buf, sizeof(struct ldlm_extent));
1001 GOTO(out, rc=-ENOMEM);
1002 extents = (struct ldlm_extent*)(ex_buf);
1004 extents->end = 0xffffffff;
1008 rc = cache_fsfilt->fs_get_write_extents_num(cache_inode, &fs_ex_size);
1011 OBD_ALLOC(buf, fs_ex_size);
1013 GOTO(out, rc=-ENOMEM);
1015 rc = cache_fsfilt->fs_get_inode_write_extents(cache_inode, &buf,
1020 ex_num = fs_ex_size / sizeof(struct fs_extent);
1022 OBD_ALLOC(ex_buf, ex_num* sizeof(struct ldlm_extent));
1024 GOTO(out, rc=-ENOMEM);
1026 fs_extents = (struct fs_extent*)(buf);
1027 extents = (struct ldlm_extent*)(ex_buf);
1028 while (ex_num > 0) {
1029 int blk_size = I2CI(inode)->i_blksize;
1031 extents->start = fs_extents->e_block * blk_size;
1032 extents->end = extents->start + fs_extents->e_num * blk_size;
1041 OBD_FREE(buf, fs_ex_size);
1043 OBD_FREE(ex_buf, (*size) * (sizeof(struct ldlm_extent)));
1044 pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
1049 static int fsfilt_smfs_set_snap_item(struct super_block *sb, char *name)
1055 #warning "still not implement for add snap item -wangdi"
1059 static int fsfilt_smfs_do_write_cow(struct dentry *de, void *extents,
1064 struct write_extents *w_ext = (struct write_extents *)extents;
1067 for (i = 0; i < num_extents; i++) {
1068 size_t count = w_ext->w_count;
1069 loff_t off = w_ext->w_pos;
1070 rc = smfs_cow_write_pre(de->d_inode, de, &count, &off);
1079 static int fsfilt_smfs_add_dir_entry(struct obd_device * obd,
1080 struct dentry * parent, char* name,
1081 int namelen, unsigned long ino,
1082 unsigned long generation,
1086 struct fsfilt_operations *cache_fsfilt = I2FOPS(parent->d_inode);
1087 struct dentry *cache_dentry = NULL, *dentry = NULL;
1088 struct inode *cache_parent = I2CI(parent->d_inode);
1096 if (!cache_fsfilt->fs_add_dir_entry)
1099 dentry = ll_lookup_one_len(name, parent, namelen);
1100 if (IS_ERR(dentry)) {
1101 CERROR("can't lookup %*s in %lu/%lu: %d\n", namelen,
1102 name, parent->d_inode->i_ino,
1103 (unsigned long) parent->d_inode->i_generation,
1104 (int) PTR_ERR(dentry));
1105 RETURN(PTR_ERR(dentry));
1107 if (dentry->d_inode != NULL || dentry->d_flags & DCACHE_CROSS_REF) {
1108 CERROR("dentry %*s(0x%p) found\n", dentry->d_name.len,
1109 dentry->d_name.name, dentry);
1113 /* mds_reint_rename() may use this method to add dir entry
1114 * that points onto local inode. and we don't want to find
1115 * it cross-ref by subsequent lookups */
1118 dentry->d_flags |= DCACHE_CROSS_REF;
1119 dentry->d_inum = ino;
1120 dentry->d_mdsnum = mds;
1121 dentry->d_generation = generation;
1122 dentry->d_fid = fid;
1125 cache_dentry = pre_smfs_dentry(NULL, cache_parent, parent);
1126 if (!cache_dentry) {
1130 pre_smfs_inode(parent->d_inode, cache_parent);
1132 rc = cache_fsfilt->fs_add_dir_entry(obd, cache_dentry, name, namelen,
1133 ino, generation, mds, fid);
1135 post_smfs_inode(parent->d_inode, cache_parent);
1137 post_smfs_dentry(cache_dentry);
1143 static int fsfilt_smfs_del_dir_entry(struct obd_device * obd,
1144 struct dentry * dentry)
1146 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_parent->d_inode);
1147 struct dentry *cache_dentry = NULL, *cache_parent = NULL;
1148 struct inode * cache_dir = I2CI(dentry->d_parent->d_inode);
1149 struct inode * cache_inode = NULL;
1157 if (!cache_fsfilt->fs_del_dir_entry)
1160 if (dentry->d_inode)
1161 cache_inode = I2CI(dentry->d_inode);
1163 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
1164 cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
1165 if (!cache_parent || !cache_dentry) {
1170 pre_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1171 pre_smfs_inode(dentry->d_inode, cache_inode);
1173 rc = cache_fsfilt->fs_del_dir_entry(obd, cache_dentry);
1178 post_smfs_inode(dentry->d_inode, cache_inode);
1179 if (S_ISDIR(dentry->d_inode->i_mode))
1180 dentry->d_parent->d_inode->i_nlink--;
1182 post_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1185 post_smfs_dentry(cache_dentry);
1186 post_smfs_dentry(cache_parent);
1191 static int fsfilt_smfs_set_info (struct super_block *sb, struct inode * inode,
1192 __u32 keylen, void *key,
1193 __u32 valsize, void *val)
1196 struct plg_info_msg msg = {
1202 if (keylen >= 9 && memcmp(key, "file_read", 9) == 0) {
1204 * this key used to inform smfs on OST about incoming r/w
1206 struct lustre_id * id = val;
1207 struct hook_rw_msg msg = {
1212 SMFS_POST_HOOK(inode, HOOK_SI_READ, &msg, rc);
1214 else if (keylen >= 10 && memcmp(key, "file_write", 10) == 0) {
1216 * this key used to inform smfs on OST about incoming r/w
1218 struct lustre_id * id = val;
1219 struct hook_rw_msg msg = {
1224 SMFS_POST_HOOK(inode, HOOK_SI_WRITE, &msg, rc);
1226 else if (keylen >= 10 && memcmp(key, "audit_info", 10) == 0) {
1227 /* this key used to pass audit data on MDS */
1228 struct audit_info * info = val;
1230 SMFS_POST_HOOK(inode, HOOK_SPECIAL, info, info->m.result);
1232 else if (keylen >= 8 && memcmp(key, "auditlog", 8) == 0) {
1234 * this key used to inform smfs on OST about client audit data
1237 audit_client_log(sb, val);
1239 else if (keylen == 5 && memcmp(key, "audit", 5) == 0) {
1240 rc = smfs_set_audit(sb, inode, (__u64 *)val);
1242 else if (keylen == 7 && memcmp(key, "id2name", 7) == 0) {
1243 rc = SMFS_PLG_HELP(sb, PLG_SET_INFO, &msg);
1251 static int fsfilt_smfs_get_info (struct super_block *sb, struct inode * inode,
1252 __u32 keylen, void *key,
1253 __u32 *valsize, void *val)
1259 if (keylen == 5 && strcmp(key, "audit") == 0) {
1261 rc = smfs_get_audit(sb, inode, NULL, mask);
1267 static struct fsfilt_operations fsfilt_smfs_ops = {
1269 .fs_owner = THIS_MODULE,
1270 .fs_start = fsfilt_smfs_start,
1271 .fs_brw_start = fsfilt_smfs_brw_start,
1272 .fs_commit = fsfilt_smfs_commit,
1273 .fs_commit_async = fsfilt_smfs_commit_async,
1274 .fs_commit_wait = fsfilt_smfs_commit_wait,
1275 .fs_setattr = fsfilt_smfs_setattr,
1276 .fs_iocontrol = fsfilt_smfs_iocontrol,
1277 .fs_set_md = fsfilt_smfs_set_md,
1278 .fs_get_md = fsfilt_smfs_get_md,
1279 .fs_readpage = fsfilt_smfs_readpage,
1280 .fs_getpage = fsfilt_smfs_getpage,
1281 .fs_add_journal_cb = fsfilt_smfs_add_journal_cb,
1282 .fs_statfs = fsfilt_smfs_statfs,
1283 .fs_sync = fsfilt_smfs_sync,
1284 .fs_map_inode_pages = fsfilt_smfs_map_inode_pages,
1285 .fs_prep_san_write = fsfilt_smfs_prep_san_write,
1286 .fs_write_record = fsfilt_smfs_write_record,
1287 .fs_read_record = fsfilt_smfs_read_record,
1288 .fs_setup = fsfilt_smfs_setup,
1289 .fs_send_bio = fsfilt_smfs_send_bio,
1290 .fs_set_xattr = fsfilt_smfs_set_xattr,
1291 .fs_get_xattr = fsfilt_smfs_get_xattr,
1292 .fs_get_op_len = NULL,
1293 .fs_del_dir_entry = fsfilt_smfs_del_dir_entry,
1294 .fs_add_dir_entry = fsfilt_smfs_add_dir_entry,
1295 .fs_insert_extents_ea = fsfilt_smfs_insert_extents_ea,
1296 .fs_remove_extents_ea = fsfilt_smfs_remove_extents_ea,
1297 .fs_init_extents_ea = fsfilt_smfs_init_extents_ea,
1298 .fs_get_ino_write_extents = fsfilt_smfs_get_ino_write_extents,
1299 .fs_get_write_extents_num = NULL,
1301 .fs_free_write_extents = fsfilt_smfs_free_extents,
1302 .fs_write_extents = fsfilt_smfs_write_extents,
1303 .fs_post_setup = fsfilt_smfs_post_setup,
1304 .fs_post_cleanup = fsfilt_smfs_post_cleanup,
1305 .fs_set_fs_flags = fsfilt_smfs_set_fs_flags,
1306 .fs_clear_fs_flags = fsfilt_smfs_clear_fs_flags,
1307 .fs_get_fs_flags = fsfilt_smfs_get_fs_flags,
1308 .fs_set_ost_flags = fsfilt_smfs_set_ost_flags,
1309 .fs_set_mds_flags = fsfilt_smfs_set_mds_flags,
1310 .fs_precreate_rec = fsfilt_smfs_precreate_rec,
1311 .fs_set_info = fsfilt_smfs_set_info,
1312 .fs_get_info = fsfilt_smfs_get_info,
1313 .fs_set_snap_item = fsfilt_smfs_set_snap_item,
1314 .fs_do_write_cow = fsfilt_smfs_do_write_cow,
1317 struct fsfilt_operations *get_smfs_fs_ops(void)
1319 return (&fsfilt_smfs_ops);
1321 EXPORT_SYMBOL(get_smfs_fs_ops);