Whamcloud - gitweb
64bfcaf68e3063a9f01ff15a28237fbb9425c13a
[fs/lustre-release.git] / lustre / smfs / fsfilt.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/lib/fsfilt_smfs.c
5  *  Lustre filesystem abstraction routines
6  *
7  *  Copyright (C) 2004 Cluster File Systems, Inc.
8  *   Author: Wang Di <wangdi@clusterfs.com>
9  *
10  *   This file is part of Lustre, http://www.lustre.org.
11  *
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.
15  *
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.
20  *
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.
24  */
25
26 #define DEBUG_SUBSYSTEM S_SM
27
28 #include <linux/fs.h>
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>
37
38 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
40 #include <linux/lustre_snap.h>
41
42 #include "smfs_internal.h"
43
44 static void *fsfilt_smfs_start(struct inode *inode, int op,
45                                void *desc_private, int logs)
46 {
47         void *handle;
48         struct inode *cache_inode = I2CI(inode);
49         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
50
51         if (cache_fsfilt == NULL)
52                 return NULL;
53
54         //SMFS_TRANS_OP(inode, op);
55
56         if (!cache_fsfilt->fs_start)
57                 return ERR_PTR(-ENOSYS);
58
59         handle = cache_fsfilt->fs_start(cache_inode, op, desc_private, logs);
60         return handle;
61 }
62
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)
66 {
67         struct fsfilt_operations *cache_fsfilt;
68         struct dentry *cache_dentry = NULL;
69         struct inode *cache_inode = NULL;
70         struct fsfilt_objinfo cache_fso;
71         void   *rc = NULL;
72
73         ENTRY;
74         
75         cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
76         if (cache_fsfilt == NULL)
77                 RETURN(NULL);
78
79         cache_inode = I2CI(fso->fso_dentry->d_inode);
80         cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
81         if (!cache_dentry)
82                 RETURN(ERR_PTR(-ENOMEM));
83         
84         cache_fso.fso_dentry = cache_dentry;
85         cache_fso.fso_bufcnt = fso->fso_bufcnt;
86
87         if (!cache_fsfilt->fs_brw_start) {
88                 rc =  ERR_PTR(-ENOSYS);
89                 goto exit;
90         }
91         
92         rc = cache_fsfilt->fs_brw_start(objcount, &cache_fso, niocount, nb,
93                                         desc_private, logs);
94 exit:
95         post_smfs_dentry(cache_dentry);
96         RETURN(rc);
97 }
98
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
102    operations. */
103 static int fsfilt_smfs_commit(struct super_block *sb, struct inode *inode, 
104                               void *h, int force_sync)
105 {
106         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
107         struct super_block *csb = S2CSB(sb); 
108         struct inode *cache_inode = NULL;
109         int    rc = -EIO;
110         
111         ENTRY;
112         
113         if (inode)
114                 cache_inode = I2CI(inode);
115
116         if (cache_fsfilt == NULL)
117                 RETURN(rc);
118
119         if (!cache_fsfilt->fs_commit)
120                 RETURN(-ENOSYS);
121
122         rc = cache_fsfilt->fs_commit(csb, cache_inode, h, force_sync);
123
124         RETURN(rc);
125 }
126
127 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
128                                     void **wait_handle)
129 {
130         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
131         struct inode *cache_inode = NULL;
132         int    rc = -EIO;
133
134         cache_inode = I2CI(inode);
135         if (cache_fsfilt == NULL)
136                 RETURN(-EINVAL);
137
138         if (!cache_fsfilt->fs_commit_async)
139                 RETURN(-ENOSYS);
140
141         rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
142
143         RETURN(rc);
144 }
145
146 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
147 {
148         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
149         struct inode *cache_inode = NULL;
150         int    rc = -EIO;
151
152         cache_inode = I2CI(inode);
153         if (cache_fsfilt == NULL)
154                 RETURN(-EINVAL);
155
156         if (!cache_fsfilt->fs_commit_wait)
157                 RETURN(-ENOSYS);
158
159         rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
160
161         RETURN(rc);
162 }
163
164 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
165                                struct iattr *iattr, int do_trunc)
166 {
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 = {
171                 .dentry = dentry,
172                 .attr = iattr
173         };
174         int    rc = -EIO;
175
176         if (!cache_fsfilt)
177                 RETURN(rc);
178
179         if (!cache_fsfilt->fs_setattr)
180                 RETURN(-ENOSYS);
181
182         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
183         if (!cache_dentry)
184                 RETURN(-ENOMEM);
185
186         pre_smfs_inode(dentry->d_inode, cache_inode);
187
188         SMFS_PRE_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg);
189         
190         rc = cache_fsfilt->fs_setattr(cache_dentry, handle, iattr, do_trunc);
191
192         SMFS_POST_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg, rc);
193         post_smfs_inode(dentry->d_inode, cache_inode);
194
195         post_smfs_dentry(cache_dentry);
196         RETURN(rc);
197 }
198
199 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
200                                  unsigned int cmd, unsigned long arg)
201 {
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;
206         int    rc = -EIO;
207         ENTRY;
208
209         if (!cache_fsfilt || !cache_inode)
210                 RETURN(rc);
211
212         if (!cache_fsfilt->fs_iocontrol)
213                 RETURN(-ENOSYS);
214
215
216         if (file != NULL) {
217                 sfi = F2SMFI(file);
218                 if (sfi->magic != SMFS_FILE_MAGIC)
219                         BUG();
220                 cache_file = sfi->c_file;
221         }
222         
223         pre_smfs_inode(inode, cache_inode);
224         
225         rc = cache_fsfilt->fs_iocontrol(cache_inode, cache_file, cmd, arg);
226
227 #if 0
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;
231 #endif
232         post_smfs_inode(inode, cache_inode);
233
234         RETURN(rc);
235 }
236
237 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
238                               void *lmm, int lmm_size, enum ea_type type)
239 {
240         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
241         struct inode *cache_inode = I2CI(inode);
242         int    rc = -EIO;
243       
244         if (!cache_fsfilt)
245                 RETURN(-EINVAL);
246
247         if (!cache_inode)
248                 RETURN(-ENOENT);
249         /*TODO: HOOK is needed here */
250         pre_smfs_inode(inode, cache_inode);
251
252         down(&cache_inode->i_sem);
253         rc = cache_fsfilt->fs_set_md(cache_inode, handle, lmm,
254                                      lmm_size, type);
255         up(&cache_inode->i_sem);
256
257         post_smfs_inode(inode, cache_inode);
258                
259         RETURN(rc);
260 }
261
262 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm,
263                               int lmm_size, enum ea_type type)
264 {
265         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
266         struct inode *cache_inode = I2CI(inode);
267         int    rc = -EIO;
268
269         if (!cache_fsfilt)
270                 RETURN(-EINVAL);
271
272         if (!cache_inode)
273                 RETURN(-ENOENT);
274
275         pre_smfs_inode(inode, cache_inode);
276
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);
280
281         post_smfs_inode(inode, cache_inode);
282
283         RETURN(rc);
284 }
285
286 static int fsfilt_smfs_send_bio(int rw, struct inode *inode, void *bio)
287 {
288         struct inode *cache_inode;
289         struct fsfilt_operations *cache_fsfilt;
290         
291         ENTRY;
292         
293         cache_fsfilt = I2FOPS(inode);
294         if (!cache_fsfilt)
295                 RETURN(-EINVAL);
296
297         cache_inode = I2CI(inode);
298         if (!cache_inode)
299                 RETURN(-EINVAL);
300
301         if (!cache_fsfilt->fs_send_bio)
302                 RETURN(-ENOSYS);
303
304         return cache_fsfilt->fs_send_bio(rw, cache_inode, bio);
305 }
306
307 static struct page * fsfilt_smfs_getpage(struct inode *inode, long int index)
308 {
309         struct  fsfilt_operations *cache_fsfilt;
310         struct  inode *cache_inode;
311         ENTRY;
312         cache_fsfilt = I2FOPS(inode);
313         if (!cache_fsfilt)
314                 RETURN(ERR_PTR(-EINVAL));
315
316         cache_inode = I2CI(inode);
317         if (!cache_inode)
318                 RETURN(ERR_PTR(-EINVAL));
319
320         if (!cache_fsfilt->fs_getpage)
321                 RETURN(ERR_PTR(-ENOSYS));
322 #if CONFIG_SNAPFS
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;
330                         
331                         ind_inode = smfs_cow_get_ind(inode, index);
332                         if (!ind_inode) {
333                                 RETURN(ERR_PTR(-EIO));
334                         }
335                         cache_ind = I2CI(ind_inode);
336                         /*FIXME cow inode should be bottom fs inode */         
337                         page = cache_fsfilt->fs_getpage(cache_ind, index);
338                         iput(ind_inode); 
339                         RETURN(page);
340                 } 
341         }
342 #endif
343         return cache_fsfilt->fs_getpage(cache_inode, index);
344 }
345
346 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
347                                     size_t count, loff_t *off)
348 {
349         struct fsfilt_operations *cache_fsfilt;
350         struct smfs_file_info *sfi;
351         struct inode *cache_inode;
352         loff_t tmp_ppos;
353         loff_t *cache_ppos;
354         ssize_t rc = -EIO;
355
356         ENTRY;
357
358         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
359         if (!cache_fsfilt)
360                 RETURN(rc);
361
362         cache_inode = I2CI(file->f_dentry->d_inode);
363         if (!cache_inode)
364                 RETURN(rc);
365
366         sfi = F2SMFI(file);
367         if (sfi->magic != SMFS_FILE_MAGIC)
368                 BUG();
369
370         if (off != &(file->f_pos))
371                 cache_ppos = &tmp_ppos;
372         else
373                 cache_ppos = &sfi->c_file->f_pos;
374         *cache_ppos = *off;
375
376         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
377 #if CONFIG_SNAPFS
378         /*readdir page*/
379         if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
380                 struct fsfilt_operations *snapops = 
381                                         I2SNAPOPS(file->f_dentry->d_inode);
382                 
383                 LASSERT(S_ISDIR(file->f_dentry->d_inode->i_mode));
384                 
385                 rc = snapops->fs_read_dotsnap_dir_page(sfi->c_file, buf, count, 
386                                                        cache_ppos); 
387         } else {
388                 if (cache_fsfilt->fs_readpage)
389                         rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
390                                                        cache_ppos);
391         }
392 #else
393         if (cache_fsfilt->fs_readpage)
394                 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
395                                                cache_ppos);
396
397 #endif
398         *off = *cache_ppos;
399         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
400         duplicate_file(file, sfi->c_file);
401
402         RETURN(rc);
403 }
404
405
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,
409                                       void *cb_data)
410 {
411         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
412         struct super_block *csb = S2CSB(sb);
413         int rc = -EIO;
414         
415         ENTRY;
416         
417         if (!cache_fsfilt)
418                  RETURN(rc);
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);
422         RETURN(rc);
423 }
424
425 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
426 {
427         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
428         struct super_block *csb = S2CSB(sb);
429         int rc = -EIO;
430
431         ENTRY;
432         
433         if (!cache_fsfilt)
434                 RETURN(rc);
435
436         if (!cache_fsfilt->fs_statfs)
437                 RETURN(-ENOSYS);
438
439         rc = cache_fsfilt->fs_statfs(csb, osfs);
440         duplicate_sb(csb, sb);
441
442         RETURN(rc);
443 }
444
445 static int fsfilt_smfs_sync(struct super_block *sb)
446 {
447         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
448         struct super_block *csb = S2CSB(sb);
449         int    rc = -ENOSYS;
450
451         if (!cache_fsfilt)
452                 RETURN(-EINVAL);
453
454         if (cache_fsfilt->fs_sync)
455                 rc = cache_fsfilt->fs_sync(csb);
456
457         RETURN(rc);
458 }
459
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)
463 {
464         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
465         struct  inode *cache_inode = NULL;
466         int     rc = -EIO;
467         
468         ENTRY;
469         
470         if (!cache_fsfilt)
471                 RETURN(-EINVAL);
472
473         cache_inode = I2CI(inode);
474
475         if (!cache_inode)
476                 RETURN(rc);
477
478         if (!cache_fsfilt->fs_map_inode_pages)
479                 RETURN(-ENOSYS);
480
481         down(&cache_inode->i_sem);
482
483         rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
484                                               created, create, sem);
485         up(&cache_inode->i_sem);
486
487         RETURN(rc);
488 }
489
490 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
491                                       int nblocks, loff_t newsize)
492 {
493         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
494         struct  inode *cache_inode = NULL;
495         int     rc = -EIO;
496
497         if (!cache_fsfilt)
498                 RETURN(-EINVAL);
499
500         cache_inode = I2CI(inode);
501
502         if (!cache_inode)
503                 RETURN(-EINVAL);
504
505         if (!cache_fsfilt->fs_prep_san_write)
506                 RETURN(-ENOSYS);
507
508         down(&cache_inode->i_sem);
509         rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, nblocks,
510                                              newsize);
511         up(&cache_inode->i_sem);
512
513         RETURN(rc);
514 }
515
516 static int fsfilt_smfs_read_record(struct file * file, void *buf,
517                                    int size, loff_t *offs)
518 {
519         struct  fsfilt_operations *cache_fsfilt;
520         struct  inode *cache_inode;
521         struct  smfs_file_info *sfi;
522         loff_t  tmp_ppos;
523         loff_t  *cache_ppos;
524         ssize_t rc;
525
526         ENTRY;
527         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
528         if (!cache_fsfilt)
529                 RETURN(-EINVAL);
530
531         cache_inode = I2CI(file->f_dentry->d_inode);
532
533         if (!cache_inode)
534                 RETURN(-EINVAL);
535
536         sfi = F2SMFI(file);
537         if (sfi->magic != SMFS_FILE_MAGIC) BUG();
538
539         if (offs != &(file->f_pos))
540                 cache_ppos = &tmp_ppos;
541         else
542                 cache_ppos = &sfi->c_file->f_pos;
543         *cache_ppos = *offs;
544
545         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
546
547         if (!cache_fsfilt->fs_read_record)
548                 RETURN(-ENOSYS);
549
550         rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, size, cache_ppos);
551
552         *offs = *cache_ppos;
553         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
554         duplicate_file(file, sfi->c_file);
555
556         RETURN(rc);
557 }
558
559 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
560                                     loff_t *offs, int force_sync)
561 {
562         struct  fsfilt_operations *cache_fsfilt;
563         struct  inode *cache_inode;
564         struct  smfs_file_info *sfi;
565         loff_t  tmp_ppos;
566         loff_t  *cache_ppos;
567         ssize_t rc = -EIO;
568
569         ENTRY;
570
571         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
572         if (!cache_fsfilt)
573                 RETURN(-EINVAL);
574
575         cache_inode = I2CI(file->f_dentry->d_inode);
576
577         if (!cache_inode)
578                 RETURN(-EINVAL);
579
580         sfi = F2SMFI(file);
581         if (sfi->magic != SMFS_FILE_MAGIC)
582                 BUG();
583
584         if (offs != &(file->f_pos))
585                 cache_ppos = &tmp_ppos;
586         else
587                 cache_ppos = &sfi->c_file->f_pos;
588         *cache_ppos = *offs;
589
590         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
591
592         if (!cache_fsfilt->fs_write_record)
593                 RETURN(-ENOSYS);
594
595         rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
596                                            bufsize, cache_ppos, force_sync);
597         *offs = *cache_ppos;
598         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
599         duplicate_file(file, sfi->c_file);
600
601         RETURN(rc);
602 }
603
604 static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
605                                   struct dentry *root_dentry)
606 {
607         struct super_block *sb = NULL;
608         int rc = 0;
609
610         ENTRY;
611         
612         if (mnt) {
613                 sb = mnt->mnt_sb;
614                 
615                 if (obd)
616                         S2SMI(sb)->smsi_exp = obd->obd_self_export;
617                 
618                 rc = smfs_post_setup(sb, mnt);
619                 if (!rc) {
620                         if (obd)
621                                 obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT] =
622                                                 S2SMI(sb)->smsi_kml_log;
623                 }
624                 else {
625                         CERROR("can not do post setup in obd %p rc=%d",
626                                obd, rc);
627                 }
628         }
629         
630         RETURN(rc);
631 }
632
633 static int fsfilt_smfs_post_cleanup(struct obd_device *obd,
634                                     struct vfsmount *mnt)
635 {
636         struct super_block *sb = NULL;
637         int rc = 0;
638         ENTRY;
639         
640         if (mnt) {
641                 sb = mnt->mnt_sb;
642                 smfs_post_cleanup(sb);
643         }
644         
645         RETURN(rc);
646 }
647
648 static int fsfilt_smfs_set_fs_flags(struct inode *inode, int flags)
649 {
650         int rc = 0;
651         ENTRY;
652
653         if (flags & SM_DO_REC)
654                 SMFS_SET(I2SMI(inode)->smi_flags, SMFS_PLG_KML);
655
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);
660         RETURN(rc);
661 }
662
663 static int fsfilt_smfs_clear_fs_flags(struct inode *inode, int flags)
664 {
665         int rc = 0;
666         ENTRY;
667         
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);
672         RETURN(rc);
673 }
674
675 static int fsfilt_smfs_get_fs_flags(struct dentry *de)
676 {
677         struct inode *inode = de->d_inode;
678         int flags = 0;
679         ENTRY;
680
681         LASSERT(inode);
682
683         if (SMFS_DO_REC(S2SMI(inode->i_sb)) && SMFS_DO_INODE_REC(inode))
684                 flags |= SM_DO_REC;
685         if (SMFS_DO_COW(S2SMI(inode->i_sb)) && SMFS_DO_INODE_COW(inode))
686                 flags |= SM_DO_COW;
687        
688         RETURN(flags); 
689 }
690 static int fsfilt_smfs_set_ost_flags(struct super_block *sb)
691 {
692         int rc = 0;
693         SET_REC_PACK_TYPE_INDEX(S2SMI(sb)->smsi_flags, PACK_OST);
694         RETURN(rc);
695 }
696
697 static int fsfilt_smfs_set_mds_flags(struct super_block *sb)
698 {
699         int rc = 0;
700         SET_REC_PACK_TYPE_INDEX(S2SMI(sb)->smsi_flags, PACK_MDS);
701         RETURN(rc);
702 }
703
704 static int fsfilt_smfs_get_reint_log_ctxt(struct super_block *sb,
705                                           struct llog_ctxt **ctxt)
706 {
707         struct smfs_super_info *smfs_info = S2SMI(sb);
708         int rc = 0;
709
710         *ctxt = smfs_info->smsi_kml_log;
711         RETURN(rc);
712 }
713
714 static int fsfilt_smfs_setup(struct obd_device *obd, struct super_block *sb)
715 {
716         struct smfs_super_info *smfs_info = S2SMI(sb);
717         struct fsfilt_operations *cache_fsfilt;
718         struct super_block *csb;
719         int rc = 0;
720
721         ENTRY;
722         
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);
726
727         if (!cache_fsfilt)
728                 RETURN(-ENOENT);
729
730         csb = S2CSB(sb);
731         if (cache_fsfilt->fs_setup) 
732                 rc = cache_fsfilt->fs_setup(obd, csb);
733         
734         duplicate_sb(sb, csb);
735         
736         RETURN(rc);
737 }
738
739 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle, char *name,
740                                  void *buffer, int buffer_size)
741 {
742         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
743         struct  inode *cache_inode = NULL;
744         int     rc = -EIO;
745
746         ENTRY;
747         
748         if (!cache_fsfilt)
749                 RETURN(rc);
750
751         cache_inode = I2CI(inode);
752         if (!cache_inode)
753                 RETURN(rc);
754
755         pre_smfs_inode(inode, cache_inode);
756
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);
761
762         RETURN(rc);
763 }
764
765 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
766                                  void *buffer, int buffer_size)
767 {
768         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
769         struct inode *cache_inode = NULL;
770         int    rc = -EIO;
771
772         if (!cache_fsfilt)
773                 RETURN(rc);
774
775         cache_inode = I2CI(inode);
776         if (!cache_inode)
777                 RETURN(rc);
778
779         pre_smfs_inode(inode, cache_inode);
780
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);
785
786         RETURN(rc);
787 }
788
789 static int fsfilt_smfs_insert_extents_ea(struct inode *inode,
790                                          unsigned long from, unsigned long num)
791 {
792         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
793         struct inode *cache_inode = NULL;
794         int    rc = -EIO;
795
796         if (!cache_fsfilt)
797                 RETURN(rc);
798
799         cache_inode = I2CI(inode);
800         if (!cache_inode)
801                 RETURN(rc);
802
803         pre_smfs_inode(inode, cache_inode);
804
805         if (cache_fsfilt->fs_insert_extents_ea)
806                 rc = cache_fsfilt->fs_insert_extents_ea(cache_inode, from, num);
807
808         post_smfs_inode(inode, cache_inode);
809         return rc;
810 }
811
812 static int fsfilt_smfs_remove_extents_ea(struct inode *inode,
813                                          unsigned long from, unsigned long num)
814 {
815         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
816         struct inode *cache_inode = NULL;
817         int    rc = -EIO;
818
819         if (!cache_fsfilt)
820                 RETURN(rc);
821
822         cache_inode = I2CI(inode);
823         if (!cache_inode)
824                 RETURN(rc);
825
826         pre_smfs_inode(inode, cache_inode);
827
828         if (cache_fsfilt->fs_remove_extents_ea)
829                 rc = cache_fsfilt->fs_remove_extents_ea(cache_inode, from, num);
830
831         post_smfs_inode(inode, cache_inode);
832         return rc;
833 }
834
835 static int fsfilt_smfs_init_extents_ea(struct inode *inode)
836 {
837         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
838         struct inode *cache_inode = NULL;
839         int    rc = -EIO;
840         ENTRY;
841
842         if (!cache_fsfilt)
843                 RETURN(rc);
844
845         cache_inode = I2CI(inode);
846         if (!cache_inode)
847                 RETURN(rc);
848
849         pre_smfs_inode(inode, cache_inode);
850
851         if (cache_fsfilt->fs_init_extents_ea)
852                 rc = cache_fsfilt->fs_init_extents_ea(cache_inode);
853
854         post_smfs_inode(inode, cache_inode);
855         return rc;
856 }
857
858 static int fsfilt_smfs_free_extents(struct super_block *sb, ino_t ino,
859                                     char *pbuf, int size)
860 {
861         OBD_FREE(pbuf, size * (sizeof(struct ldlm_extent)));
862         return 0;
863 }
864
865 static int fsfilt_smfs_write_extents(struct dentry *dentry,
866                                      unsigned long from, unsigned long num)
867 {
868         int rc = 0;
869         ENTRY;
870         if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
871                 rc = smfs_write_extents(dentry->d_inode, dentry, from, num);
872
873         return rc;
874 }
875
876 static int fsfilt_smfs_precreate_rec(struct dentry *dentry, int *count, 
877                                      struct obdo *oa)
878 {
879         int rc = 0;
880
881         if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
882                 rc = smfs_rec_precreate(dentry, count, oa);
883
884         return rc;
885 }
886
887 static int fsfilt_smfs_get_ino_write_extents(struct super_block *sb, ino_t ino,
888                                              char **pbuf, int *size)
889 {
890         struct fs_extent *fs_extents;
891         struct ldlm_extent *extents = NULL;
892         struct inode *inode;
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;
898         ENTRY;
899
900         push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
901
902         inode = iget(sb, ino);
903
904         if (!inode || is_bad_inode(inode)) {
905                 CWARN("Can not get inode %lu ino\n", ino);
906                 GOTO(out, rc = 0);
907         }
908         cache_inode = I2CI(inode);
909         cache_fsfilt = I2FOPS(inode);
910
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)) {
914                 GOTO(out, rc = 0);
915         } else if (flags & SMFS_OVER_WRITE) {
916                 *size = 1;
917                 OBD_ALLOC(ex_buf, sizeof(struct ldlm_extent));
918                 if (!ex_buf)
919                         GOTO(out, rc=-ENOMEM);
920                 extents = (struct ldlm_extent*)(ex_buf);
921                 extents->start = 0;
922                 extents->end = 0xffffffff;
923         }
924         if (rc < 0)
925                 GOTO(out, rc);
926         rc = cache_fsfilt->fs_get_write_extents_num(cache_inode, &fs_ex_size);
927         if (rc)
928                 GOTO(out, rc);
929         OBD_ALLOC(buf, fs_ex_size);
930         if (!buf)
931                 GOTO(out, rc=-ENOMEM);
932
933         rc = cache_fsfilt->fs_get_inode_write_extents(cache_inode, &buf,
934                                                       &fs_ex_size);
935         if (rc < 0)
936                 GOTO(out, rc);
937         rc = 0;
938         ex_num = fs_ex_size / sizeof(struct fs_extent);
939         *size =  ex_num;
940         OBD_ALLOC(ex_buf, ex_num* sizeof(struct ldlm_extent));
941         if (!ex_buf)
942                 GOTO(out, rc=-ENOMEM);
943
944         fs_extents = (struct fs_extent*)(buf);
945         extents = (struct ldlm_extent*)(ex_buf);
946         while (ex_num > 0) {
947                 int blk_size = I2CI(inode)->i_blksize;
948
949                 extents->start = fs_extents->e_block * blk_size;
950                 extents->end = extents->start + fs_extents->e_num * blk_size;
951                 fs_extents++;
952                 extents++;
953                 ex_num--;
954         }
955         *pbuf = ex_buf;
956 out:
957         iput(inode);
958         if (buf)
959                 OBD_FREE(buf, fs_ex_size);
960         if (rc && extents)
961                 OBD_FREE(ex_buf, (*size) * (sizeof(struct ldlm_extent)));
962         pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
963         return rc;
964 }
965
966 static int fsfilt_smfs_set_snap_item(struct super_block *sb, char *name)
967 {
968         int rc = 0;
969
970         ENTRY;
971 #if CONFIG_SNAPFS
972 #warning "still not implement for add snap item -wangdi"         
973 #endif
974         RETURN(rc);        
975 }
976 static int fsfilt_smfs_do_write_cow(struct dentry *de, void *extents,
977                                     int num_extents)
978 {
979         int rc = 0;
980 #if CONFIG_SNAPFS
981         struct write_extents *w_ext = (struct write_extents *)extents;
982         int i = 0;
983         ENTRY;
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);
988                if (rc)
989                         RETURN(rc);  
990                w_ext ++;
991         }
992 #endif
993         RETURN(rc);
994 }
995
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,
1000                                      unsigned long mds,
1001                                      unsigned long fid) 
1002 {
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);
1006         int    rc = -EIO;
1007
1008         ENTRY;
1009         
1010         if (!cache_fsfilt)
1011                 RETURN(rc);
1012
1013         if (!cache_fsfilt->fs_add_dir_entry)
1014                 RETURN(-ENOSYS);
1015
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));
1023         }
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);
1027                 l_dput(dentry);
1028                 RETURN(-EEXIST);
1029         }
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 */
1033         d_drop(dentry);
1034
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;
1040         l_dput(dentry);
1041
1042         cache_dentry = pre_smfs_dentry(NULL, cache_parent, parent);
1043         if (!cache_dentry) {
1044                 RETURN(-ENOMEM);
1045         }
1046
1047         pre_smfs_inode(parent->d_inode, cache_parent);
1048         
1049         rc = cache_fsfilt->fs_add_dir_entry(obd, cache_dentry, name, namelen,
1050                                             ino, generation, mds, fid);
1051
1052         post_smfs_inode(parent->d_inode, cache_parent);
1053         
1054         post_smfs_dentry(cache_dentry);
1055         
1056         RETURN(rc);
1057         
1058 }
1059
1060 static int fsfilt_smfs_del_dir_entry(struct obd_device * obd,
1061                                      struct dentry * dentry) 
1062 {
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;
1067         int    rc = -EIO;
1068
1069         ENTRY;
1070         
1071         if (!cache_fsfilt)
1072                 RETURN(rc);
1073
1074         if (!cache_fsfilt->fs_del_dir_entry)
1075                 RETURN(-ENOSYS);
1076
1077         if (dentry->d_inode)
1078                 cache_inode = I2CI(dentry->d_inode);
1079         
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) {
1083                 rc = (-ENOMEM);
1084                 goto exit;
1085         }
1086
1087         pre_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1088         pre_smfs_inode(dentry->d_inode, cache_inode);
1089         
1090         rc = cache_fsfilt->fs_del_dir_entry(obd, cache_dentry);
1091
1092         if (!rc)
1093                 d_drop(dentry);
1094
1095         post_smfs_inode(dentry->d_inode, cache_inode);
1096         post_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1097 exit:
1098         post_smfs_dentry(cache_dentry);
1099         post_smfs_dentry(cache_parent);
1100         RETURN(rc);
1101         
1102 }
1103
1104
1105 static struct fsfilt_operations fsfilt_smfs_ops = {
1106         .fs_type                = "smfs",
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,
1138
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,
1152  };
1153
1154 struct fsfilt_operations *get_smfs_fs_ops(void)
1155 {
1156         return (&fsfilt_smfs_ops);
1157 }
1158 EXPORT_SYMBOL(get_smfs_fs_ops);
1159
1160