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);
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;
75 cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
76 if (cache_fsfilt == NULL)
79 cache_inode = I2CI(fso->fso_dentry->d_inode);
80 cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
82 RETURN(ERR_PTR(-ENOMEM));
84 cache_fso.fso_dentry = cache_dentry;
85 cache_fso.fso_bufcnt = fso->fso_bufcnt;
87 if (!cache_fsfilt->fs_brw_start) {
88 rc = ERR_PTR(-ENOSYS);
92 rc = cache_fsfilt->fs_brw_start(objcount, &cache_fso, niocount, nb,
95 post_smfs_dentry(cache_dentry);
99 /* FIXME-WANGDI: here we can easily have inode == NULL due to
100 mds_open() behavior. It passes NULL inode to mds_finish_transno()
101 sometimes. Probably we should have spare way to get cache fsfilt
103 static int fsfilt_smfs_commit(struct super_block *sb, struct inode *inode,
104 void *h, int force_sync)
106 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
107 struct super_block *csb = S2CSB(sb);
108 struct inode *cache_inode = NULL;
114 cache_inode = I2CI(inode);
116 if (cache_fsfilt == NULL)
119 if (!cache_fsfilt->fs_commit)
122 rc = cache_fsfilt->fs_commit(csb, cache_inode, h, force_sync);
127 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
130 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
131 struct inode *cache_inode = NULL;
134 cache_inode = I2CI(inode);
135 if (cache_fsfilt == NULL)
138 if (!cache_fsfilt->fs_commit_async)
141 rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
146 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
148 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
149 struct inode *cache_inode = NULL;
152 cache_inode = I2CI(inode);
153 if (cache_fsfilt == NULL)
156 if (!cache_fsfilt->fs_commit_wait)
159 rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
164 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
165 struct iattr *iattr, int do_trunc)
167 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
168 struct dentry *cache_dentry = NULL;
169 struct inode *cache_inode = I2CI(dentry->d_inode);
170 struct hook_setattr_msg msg = {
179 if (!cache_fsfilt->fs_setattr)
182 cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
186 pre_smfs_inode(dentry->d_inode, cache_inode);
188 SMFS_PRE_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg);
190 rc = cache_fsfilt->fs_setattr(cache_dentry, handle, iattr, do_trunc);
192 SMFS_POST_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg, rc);
193 post_smfs_inode(dentry->d_inode, cache_inode);
195 post_smfs_dentry(cache_dentry);
199 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
200 unsigned int cmd, unsigned long arg)
202 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
203 struct inode *cache_inode = I2CI(inode);
204 struct smfs_file_info *sfi = NULL;
205 struct file * cache_file = NULL;
209 if (!cache_fsfilt || !cache_inode)
212 if (!cache_fsfilt->fs_iocontrol)
218 if (sfi->magic != SMFS_FILE_MAGIC)
220 cache_file = sfi->c_file;
223 pre_smfs_inode(inode, cache_inode);
225 rc = cache_fsfilt->fs_iocontrol(cache_inode, cache_file, cmd, arg);
228 /* FIXME-UMKA: Should this be in duplicate_inode()? */
229 if (rc == 0 && cmd == EXT3_IOC_SETFLAGS)
230 inode->i_flags = cache_inode->i_flags;
232 post_smfs_inode(inode, cache_inode);
237 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
238 void *lmm, int lmm_size, enum ea_type type)
240 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
241 struct inode *cache_inode = I2CI(inode);
249 /*TODO: HOOK is needed here */
250 pre_smfs_inode(inode, cache_inode);
252 down(&cache_inode->i_sem);
253 rc = cache_fsfilt->fs_set_md(cache_inode, handle, lmm,
255 up(&cache_inode->i_sem);
257 post_smfs_inode(inode, cache_inode);
262 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm,
263 int lmm_size, enum ea_type type)
265 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
266 struct inode *cache_inode = I2CI(inode);
275 pre_smfs_inode(inode, cache_inode);
277 down(&cache_inode->i_sem);
278 rc = cache_fsfilt->fs_get_md(cache_inode, lmm, lmm_size, type);
279 up(&cache_inode->i_sem);
281 post_smfs_inode(inode, cache_inode);
286 static int fsfilt_smfs_send_bio(int rw, struct inode *inode, void *bio)
288 struct inode *cache_inode;
289 struct fsfilt_operations *cache_fsfilt;
293 cache_fsfilt = I2FOPS(inode);
297 cache_inode = I2CI(inode);
301 if (!cache_fsfilt->fs_send_bio)
304 return cache_fsfilt->fs_send_bio(rw, cache_inode, bio);
307 static struct page * fsfilt_smfs_getpage(struct inode *inode, long int index)
309 struct fsfilt_operations *cache_fsfilt;
310 struct inode *cache_inode;
312 cache_fsfilt = I2FOPS(inode);
314 RETURN(ERR_PTR(-EINVAL));
316 cache_inode = I2CI(inode);
318 RETURN(ERR_PTR(-EINVAL));
320 if (!cache_fsfilt->fs_getpage)
321 RETURN(ERR_PTR(-ENOSYS));
323 if (SMFS_DO_COW(S2SMI(inode->i_sb))) {
324 struct address_space_operations *aops =
325 cache_inode->i_mapping->a_ops;
326 if (aops->bmap(cache_inode->i_mapping, index)) {
327 struct inode *ind_inode = NULL;
328 struct inode *cache_ind = NULL;
329 struct page *page = NULL;
331 ind_inode = smfs_cow_get_ind(inode, index);
333 RETURN(ERR_PTR(-EIO));
335 cache_ind = I2CI(ind_inode);
336 /*FIXME cow inode should be bottom fs inode */
337 page = cache_fsfilt->fs_getpage(cache_ind, index);
343 return cache_fsfilt->fs_getpage(cache_inode, index);
346 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
347 size_t count, loff_t *off)
349 struct fsfilt_operations *cache_fsfilt;
350 struct smfs_file_info *sfi;
351 struct inode *cache_inode;
358 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
362 cache_inode = I2CI(file->f_dentry->d_inode);
367 if (sfi->magic != SMFS_FILE_MAGIC)
370 if (off != &(file->f_pos))
371 cache_ppos = &tmp_ppos;
373 cache_ppos = &sfi->c_file->f_pos;
376 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
379 if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
380 struct fsfilt_operations *snapops =
381 I2SNAPOPS(file->f_dentry->d_inode);
383 LASSERT(S_ISDIR(file->f_dentry->d_inode->i_mode));
385 rc = snapops->fs_read_dotsnap_dir_page(sfi->c_file, buf, count,
388 if (cache_fsfilt->fs_readpage)
389 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
393 if (cache_fsfilt->fs_readpage)
394 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
399 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
400 duplicate_file(file, sfi->c_file);
406 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
407 struct super_block *sb, __u64 last_rcvd,
408 void *handle, fsfilt_cb_t cb_func,
411 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
412 struct super_block *csb = S2CSB(sb);
419 if (cache_fsfilt->fs_add_journal_cb)
420 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
421 handle, cb_func, cb_data);
425 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
427 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
428 struct super_block *csb = S2CSB(sb);
436 if (!cache_fsfilt->fs_statfs)
439 rc = cache_fsfilt->fs_statfs(csb, osfs);
440 duplicate_sb(csb, sb);
445 static int fsfilt_smfs_sync(struct super_block *sb)
447 struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
448 struct super_block *csb = S2CSB(sb);
454 if (cache_fsfilt->fs_sync)
455 rc = cache_fsfilt->fs_sync(csb);
460 int fsfilt_smfs_map_inode_pages(struct inode *inode, struct page **page,
461 int pages, unsigned long *blocks, int *created,
462 int create, struct semaphore *sem)
464 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
465 struct inode *cache_inode = NULL;
473 cache_inode = I2CI(inode);
478 if (!cache_fsfilt->fs_map_inode_pages)
481 down(&cache_inode->i_sem);
483 rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
484 created, create, sem);
485 up(&cache_inode->i_sem);
490 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
491 int nblocks, loff_t newsize)
493 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
494 struct inode *cache_inode = NULL;
500 cache_inode = I2CI(inode);
505 if (!cache_fsfilt->fs_prep_san_write)
508 down(&cache_inode->i_sem);
509 rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, nblocks,
511 up(&cache_inode->i_sem);
516 static int fsfilt_smfs_read_record(struct file * file, void *buf,
517 int size, loff_t *offs)
519 struct fsfilt_operations *cache_fsfilt;
520 struct inode *cache_inode;
521 struct smfs_file_info *sfi;
527 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
531 cache_inode = I2CI(file->f_dentry->d_inode);
537 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
539 if (offs != &(file->f_pos))
540 cache_ppos = &tmp_ppos;
542 cache_ppos = &sfi->c_file->f_pos;
545 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
547 if (!cache_fsfilt->fs_read_record)
550 rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, size, cache_ppos);
553 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
554 duplicate_file(file, sfi->c_file);
559 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
560 loff_t *offs, int force_sync)
562 struct fsfilt_operations *cache_fsfilt;
563 struct inode *cache_inode;
564 struct smfs_file_info *sfi;
571 cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
575 cache_inode = I2CI(file->f_dentry->d_inode);
581 if (sfi->magic != SMFS_FILE_MAGIC)
584 if (offs != &(file->f_pos))
585 cache_ppos = &tmp_ppos;
587 cache_ppos = &sfi->c_file->f_pos;
590 pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
592 if (!cache_fsfilt->fs_write_record)
595 rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
596 bufsize, cache_ppos, force_sync);
598 post_smfs_inode(file->f_dentry->d_inode, cache_inode);
599 duplicate_file(file, sfi->c_file);
604 static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
605 struct dentry *root_dentry)
607 struct super_block *sb = NULL;
616 S2SMI(sb)->smsi_exp = obd->obd_self_export;
618 rc = smfs_post_setup(sb, mnt);
621 obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT] =
622 S2SMI(sb)->smsi_kml_log;
625 CERROR("can not do post setup in obd %p rc=%d",
633 static int fsfilt_smfs_post_cleanup(struct obd_device *obd,
634 struct vfsmount *mnt)
636 struct super_block *sb = NULL;
642 smfs_post_cleanup(sb);
648 static int fsfilt_smfs_set_fs_flags(struct inode *inode, int flags)
653 if (flags & SM_DO_REC)
654 SMFS_SET(I2SMI(inode)->smi_flags, SMFS_PLG_KML);
656 //if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
657 // SMFS_SET_INODE_REC(inode);
658 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
659 SMFS_SET_INODE_COW(inode);
663 static int fsfilt_smfs_clear_fs_flags(struct inode *inode, int flags)
668 if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
669 SMFS_CLEAN_INODE_REC(inode);
670 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
671 SMFS_CLEAN_INODE_COW(inode);
675 static int fsfilt_smfs_get_fs_flags(struct dentry *de)
677 struct inode *inode = de->d_inode;
683 if (SMFS_DO_REC(S2SMI(inode->i_sb)) && SMFS_DO_INODE_REC(inode))
685 if (SMFS_DO_COW(S2SMI(inode->i_sb)) && SMFS_DO_INODE_COW(inode))
690 static int fsfilt_smfs_set_ost_flags(struct super_block *sb)
693 SET_REC_PACK_TYPE_INDEX(S2SMI(sb)->smsi_flags, PACK_OST);
697 static int fsfilt_smfs_set_mds_flags(struct super_block *sb)
700 SET_REC_PACK_TYPE_INDEX(S2SMI(sb)->smsi_flags, PACK_MDS);
704 static int fsfilt_smfs_get_reint_log_ctxt(struct super_block *sb,
705 struct llog_ctxt **ctxt)
707 struct smfs_super_info *smfs_info = S2SMI(sb);
710 *ctxt = smfs_info->smsi_kml_log;
714 static int fsfilt_smfs_setup(struct obd_device *obd, struct super_block *sb)
716 struct smfs_super_info *smfs_info = S2SMI(sb);
717 struct fsfilt_operations *cache_fsfilt;
718 struct super_block *csb;
723 /* It should be initialized olready by smfs_read_super(). */
724 if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
725 cache_fsfilt = fsfilt_get_ops(smfs_info->smsi_cache_ftype);
731 if (cache_fsfilt->fs_setup)
732 rc = cache_fsfilt->fs_setup(obd, csb);
734 duplicate_sb(sb, csb);
739 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle, char *name,
740 void *buffer, int buffer_size)
742 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
743 struct inode *cache_inode = NULL;
751 cache_inode = I2CI(inode);
755 pre_smfs_inode(inode, cache_inode);
757 if (cache_fsfilt->fs_set_xattr)
758 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
759 buffer, buffer_size);
760 post_smfs_inode(inode, cache_inode);
765 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
766 void *buffer, int buffer_size)
768 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
769 struct inode *cache_inode = NULL;
775 cache_inode = I2CI(inode);
779 pre_smfs_inode(inode, cache_inode);
781 if (cache_fsfilt->fs_get_xattr)
782 rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
783 buffer, buffer_size);
784 post_smfs_inode(inode, cache_inode);
789 static int fsfilt_smfs_insert_extents_ea(struct inode *inode,
790 unsigned long from, unsigned long num)
792 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
793 struct inode *cache_inode = NULL;
799 cache_inode = I2CI(inode);
803 pre_smfs_inode(inode, cache_inode);
805 if (cache_fsfilt->fs_insert_extents_ea)
806 rc = cache_fsfilt->fs_insert_extents_ea(cache_inode, from, num);
808 post_smfs_inode(inode, cache_inode);
812 static int fsfilt_smfs_remove_extents_ea(struct inode *inode,
813 unsigned long from, unsigned long num)
815 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
816 struct inode *cache_inode = NULL;
822 cache_inode = I2CI(inode);
826 pre_smfs_inode(inode, cache_inode);
828 if (cache_fsfilt->fs_remove_extents_ea)
829 rc = cache_fsfilt->fs_remove_extents_ea(cache_inode, from, num);
831 post_smfs_inode(inode, cache_inode);
835 static int fsfilt_smfs_init_extents_ea(struct inode *inode)
837 struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
838 struct inode *cache_inode = NULL;
845 cache_inode = I2CI(inode);
849 pre_smfs_inode(inode, cache_inode);
851 if (cache_fsfilt->fs_init_extents_ea)
852 rc = cache_fsfilt->fs_init_extents_ea(cache_inode);
854 post_smfs_inode(inode, cache_inode);
858 static int fsfilt_smfs_free_extents(struct super_block *sb, ino_t ino,
859 char *pbuf, int size)
861 OBD_FREE(pbuf, size * (sizeof(struct ldlm_extent)));
865 static int fsfilt_smfs_write_extents(struct dentry *dentry,
866 unsigned long from, unsigned long num)
870 if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
871 rc = smfs_write_extents(dentry->d_inode, dentry, from, num);
876 static int fsfilt_smfs_precreate_rec(struct dentry *dentry, int *count,
881 if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
882 rc = smfs_rec_precreate(dentry, count, oa);
887 static int fsfilt_smfs_get_ino_write_extents(struct super_block *sb, ino_t ino,
888 char **pbuf, int *size)
890 struct fs_extent *fs_extents;
891 struct ldlm_extent *extents = NULL;
893 struct inode *cache_inode;
894 struct fsfilt_operations *cache_fsfilt = NULL;
895 struct lvfs_run_ctxt saved;
896 int rc = 0, fs_ex_size, ex_num, flags;
897 char *buf = NULL, *ex_buf = NULL;
900 push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
902 inode = iget(sb, ino);
904 if (!inode || is_bad_inode(inode)) {
905 CWARN("Can not get inode %lu ino\n", ino);
908 cache_inode = I2CI(inode);
909 cache_fsfilt = I2FOPS(inode);
911 rc = cache_fsfilt->fs_get_xattr(cache_inode, REINT_EXTENTS_FLAGS,
912 &flags, sizeof(int));
913 if (!(flags & SMFS_OVER_WRITE) && !(flags & SMFS_DIRTY_WRITE)) {
915 } else if (flags & SMFS_OVER_WRITE) {
917 OBD_ALLOC(ex_buf, sizeof(struct ldlm_extent));
919 GOTO(out, rc=-ENOMEM);
920 extents = (struct ldlm_extent*)(ex_buf);
922 extents->end = 0xffffffff;
926 rc = cache_fsfilt->fs_get_write_extents_num(cache_inode, &fs_ex_size);
929 OBD_ALLOC(buf, fs_ex_size);
931 GOTO(out, rc=-ENOMEM);
933 rc = cache_fsfilt->fs_get_inode_write_extents(cache_inode, &buf,
938 ex_num = fs_ex_size / sizeof(struct fs_extent);
940 OBD_ALLOC(ex_buf, ex_num* sizeof(struct ldlm_extent));
942 GOTO(out, rc=-ENOMEM);
944 fs_extents = (struct fs_extent*)(buf);
945 extents = (struct ldlm_extent*)(ex_buf);
947 int blk_size = I2CI(inode)->i_blksize;
949 extents->start = fs_extents->e_block * blk_size;
950 extents->end = extents->start + fs_extents->e_num * blk_size;
959 OBD_FREE(buf, fs_ex_size);
961 OBD_FREE(ex_buf, (*size) * (sizeof(struct ldlm_extent)));
962 pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
966 static int fsfilt_smfs_set_snap_item(struct super_block *sb, char *name)
972 #warning "still not implement for add snap item -wangdi"
976 static int fsfilt_smfs_do_write_cow(struct dentry *de, void *extents,
981 struct write_extents *w_ext = (struct write_extents *)extents;
984 for (i = 0; i < num_extents; i++) {
985 size_t count = w_ext->w_count;
986 loff_t off = w_ext->w_pos;
987 rc = smfs_cow_write_pre(de->d_inode, de, &count, &off);
996 static int fsfilt_smfs_add_dir_entry(struct obd_device * obd,
997 struct dentry * parent, char* name,
998 int namelen, unsigned long ino,
999 unsigned long generation,
1003 struct fsfilt_operations *cache_fsfilt = I2FOPS(parent->d_inode);
1004 struct dentry *cache_dentry = NULL, *dentry = NULL;
1005 struct inode *cache_parent = I2CI(parent->d_inode);
1013 if (!cache_fsfilt->fs_add_dir_entry)
1016 dentry = ll_lookup_one_len(name, parent, namelen);
1017 if (IS_ERR(dentry)) {
1018 CERROR("can't lookup %*s in %lu/%lu: %d\n", namelen,
1019 name, parent->d_inode->i_ino,
1020 (unsigned long) parent->d_inode->i_generation,
1021 (int) PTR_ERR(dentry));
1022 RETURN(PTR_ERR(dentry));
1024 if (dentry->d_inode != NULL || dentry->d_flags & DCACHE_CROSS_REF) {
1025 CERROR("dentry %*s(0x%p) found\n", dentry->d_name.len,
1026 dentry->d_name.name, dentry);
1030 /* mds_reint_rename() may use this method to add dir entry
1031 * that points onto local inode. and we don't want to find
1032 * it cross-ref by subsequent lookups */
1035 dentry->d_flags |= DCACHE_CROSS_REF;
1036 dentry->d_inum = ino;
1037 dentry->d_mdsnum = mds;
1038 dentry->d_generation = generation;
1039 dentry->d_fid = fid;
1042 cache_dentry = pre_smfs_dentry(NULL, cache_parent, parent);
1043 if (!cache_dentry) {
1047 pre_smfs_inode(parent->d_inode, cache_parent);
1049 rc = cache_fsfilt->fs_add_dir_entry(obd, cache_dentry, name, namelen,
1050 ino, generation, mds, fid);
1052 post_smfs_inode(parent->d_inode, cache_parent);
1054 post_smfs_dentry(cache_dentry);
1060 static int fsfilt_smfs_del_dir_entry(struct obd_device * obd,
1061 struct dentry * dentry)
1063 struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_parent->d_inode);
1064 struct dentry *cache_dentry = NULL, *cache_parent = NULL;
1065 struct inode * cache_dir = I2CI(dentry->d_parent->d_inode);
1066 struct inode * cache_inode = NULL;
1074 if (!cache_fsfilt->fs_del_dir_entry)
1077 if (dentry->d_inode)
1078 cache_inode = I2CI(dentry->d_inode);
1080 cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
1081 cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
1082 if (!cache_parent || !cache_dentry) {
1087 pre_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1088 pre_smfs_inode(dentry->d_inode, cache_inode);
1090 rc = cache_fsfilt->fs_del_dir_entry(obd, cache_dentry);
1095 post_smfs_inode(dentry->d_inode, cache_inode);
1096 post_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1098 post_smfs_dentry(cache_dentry);
1099 post_smfs_dentry(cache_parent);
1105 static struct fsfilt_operations fsfilt_smfs_ops = {
1107 .fs_owner = THIS_MODULE,
1108 .fs_start = fsfilt_smfs_start,
1109 .fs_brw_start = fsfilt_smfs_brw_start,
1110 .fs_commit = fsfilt_smfs_commit,
1111 .fs_commit_async = fsfilt_smfs_commit_async,
1112 .fs_commit_wait = fsfilt_smfs_commit_wait,
1113 .fs_setattr = fsfilt_smfs_setattr,
1114 .fs_iocontrol = fsfilt_smfs_iocontrol,
1115 .fs_set_md = fsfilt_smfs_set_md,
1116 .fs_get_md = fsfilt_smfs_get_md,
1117 .fs_readpage = fsfilt_smfs_readpage,
1118 .fs_getpage = fsfilt_smfs_getpage,
1119 .fs_add_journal_cb = fsfilt_smfs_add_journal_cb,
1120 .fs_statfs = fsfilt_smfs_statfs,
1121 .fs_sync = fsfilt_smfs_sync,
1122 .fs_map_inode_pages = fsfilt_smfs_map_inode_pages,
1123 .fs_prep_san_write = fsfilt_smfs_prep_san_write,
1124 .fs_write_record = fsfilt_smfs_write_record,
1125 .fs_read_record = fsfilt_smfs_read_record,
1126 .fs_setup = fsfilt_smfs_setup,
1127 .fs_send_bio = fsfilt_smfs_send_bio,
1128 .fs_set_xattr = fsfilt_smfs_set_xattr,
1129 .fs_get_xattr = fsfilt_smfs_get_xattr,
1130 .fs_get_op_len = NULL,
1131 .fs_del_dir_entry = fsfilt_smfs_del_dir_entry,
1132 .fs_add_dir_entry = fsfilt_smfs_add_dir_entry,
1133 .fs_insert_extents_ea = fsfilt_smfs_insert_extents_ea,
1134 .fs_remove_extents_ea = fsfilt_smfs_remove_extents_ea,
1135 .fs_init_extents_ea = fsfilt_smfs_init_extents_ea,
1136 .fs_get_ino_write_extents = fsfilt_smfs_get_ino_write_extents,
1137 .fs_get_write_extents_num = NULL,
1139 .fs_free_write_extents = fsfilt_smfs_free_extents,
1140 .fs_write_extents = fsfilt_smfs_write_extents,
1141 .fs_post_setup = fsfilt_smfs_post_setup,
1142 .fs_post_cleanup = fsfilt_smfs_post_cleanup,
1143 .fs_set_fs_flags = fsfilt_smfs_set_fs_flags,
1144 .fs_clear_fs_flags = fsfilt_smfs_clear_fs_flags,
1145 .fs_get_fs_flags = fsfilt_smfs_get_fs_flags,
1146 .fs_set_ost_flags = fsfilt_smfs_set_ost_flags,
1147 .fs_set_mds_flags = fsfilt_smfs_set_mds_flags,
1148 .fs_precreate_rec = fsfilt_smfs_precreate_rec,
1149 .fs_get_reint_log_ctxt = fsfilt_smfs_get_reint_log_ctxt,
1150 .fs_set_snap_item = fsfilt_smfs_set_snap_item,
1151 .fs_do_write_cow = fsfilt_smfs_do_write_cow,
1154 struct fsfilt_operations *get_smfs_fs_ops(void)
1156 return (&fsfilt_smfs_ops);
1158 EXPORT_SYMBOL(get_smfs_fs_ops);