1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define DEBUG_SUBSYSTEM S_SM
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/pagemap.h>
28 #include <linux/string.h>
29 #include <linux/slab.h>
30 #include <linux/stat.h>
31 #include <linux/unistd.h>
32 #include <linux/smp_lock.h>
33 #include <linux/obd_class.h>
34 #include <linux/obd_support.h>
35 #include <linux/lustre_lib.h>
36 #include <linux/lustre_idl.h>
37 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
40 #include <linux/lustre_snap.h>
42 #include "smfs_internal.h"
43 #define SNAPTABLE_SIZE(size) (sizeof(struct snap_table) + size * sizeof(struct snap))
44 static int smfs_init_snaptabe(struct super_block *sb)
46 struct snap_info *snap_info = S2SNAPI(sb);
47 struct snap_table *snap_table = NULL;
48 struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
49 struct dentry *d_root = snap_info->snap_root;
50 int rc = 0, size, table_size, vallen, i;
54 init_MUTEX(&snap_info->sntbl_sema);
55 /*Initialized table */
56 /*get the maxsize of snaptable*/
58 rc = snapops->fs_get_snap_info(d_root->d_inode, MAX_SNAPTABLE_COUNT,
59 strlen(MAX_SNAPTABLE_COUNT), &size,
62 CERROR("the Max snaptable count should not be zero\n");
66 table_size = SNAPTABLE_SIZE(size);
68 OBD_ALLOC(snap_info->sntbl, table_size);
70 if (!snap_info->sntbl) {
74 snap_table = snap_info->sntbl;
76 snap_table->sntbl_magic = cpu_to_le32((__u32)SNAPTABLE_MAGIC);
77 snap_table->sntbl_max_count = size;
78 for (i = 0; i < snap_table->sntbl_max_count; i++) {
79 /*init sn_index to -1*/
80 snap_table->sntbl_items[i].sn_index = -1;
82 /*get snaptable info*/
83 rc = snapops->fs_get_snap_info(d_root->d_inode, SNAPTABLE_INFO,
84 strlen(SNAPTABLE_INFO),
85 snap_table, &table_size);
88 snap_table->sntbl_count = 0;
89 CDEBUG(D_INFO, "No snaptable here\n");
92 CERROR("Can not retrive the snaptable from this filesystem\n");
93 OBD_FREE(snap_table, table_size);
97 if (le32_to_cpu(snap_table->sntbl_magic) != SNAPTABLE_MAGIC) {
98 CERROR("On disk snaptable is not right \n");
99 OBD_FREE(snap_table, table_size);
104 #define COWED_NAME_LEN (7 + 8 + 1)
105 static int smfs_init_cowed_dir(struct super_block *sb, struct dentry* cowed_dir)
107 struct snap_info *snap_info = S2SNAPI(sb);
108 struct dentry *dentry = NULL;
109 struct lvfs_run_ctxt saved;
110 char name[COWED_NAME_LEN];
114 sprintf(name, ".cowed_%08x", (__u32)cowed_dir->d_inode->i_ino);
115 push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
116 dentry = simple_mkdir(cowed_dir, name, 0777, 1);
117 pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
118 if (IS_ERR(dentry)) {
119 rc = PTR_ERR(dentry);
120 CERROR("create cowed directory: rc = %d\n", rc);
123 snap_info->sn_cowed_dentry = dentry;
126 static int smfs_init_dotinfo(struct super_block *sb)
128 struct snap_info *snap_info = S2SNAPI(sb);
129 struct snap_dot_info *dot_info = NULL;
133 if (snap_info->sn_dot_info)
136 OBD_ALLOC(snap_info->sn_dot_info, sizeof(struct snap_dot_info));
138 if (!snap_info->sn_dot_info)
141 dot_info = snap_info->sn_dot_info;
143 OBD_ALLOC(dot_info->dot_name, strlen(DOT_SNAP_NAME) + 1);
145 if (!dot_info->dot_name) {
146 OBD_FREE(snap_info->sn_dot_info, sizeof(struct snap_dot_info));
149 memcpy(dot_info->dot_name, DOT_SNAP_NAME, strlen(DOT_SNAP_NAME));
151 dot_info->dot_name_len = strlen(DOT_SNAP_NAME);
152 dot_info->dot_snap_enable = 1;
157 static int smfs_cleanup_dotinfo(struct super_block *sb)
159 struct snap_info *snap_info = S2SNAPI(sb);
160 struct snap_dot_info *dot_info = NULL;
164 if (!snap_info->sn_dot_info)
167 dot_info = snap_info->sn_dot_info;
169 if (dot_info->dot_name) {
170 OBD_FREE(dot_info->dot_name, dot_info->dot_name_len + 1);
173 OBD_FREE(dot_info, sizeof(struct snap_dot_info));
178 int smfs_start_cow(struct super_block *sb)
184 /*init snap fsfilt operations*/
185 if (!S2SNAPI(sb)->snap_cache_fsfilt) {
186 char *snap_cache_ftype = NULL;
187 int tmp = strlen(S2SMI(sb)->smsi_cache_ftype) + strlen("_snap");
189 OBD_ALLOC(snap_cache_ftype, tmp + 1);
190 sprintf(snap_cache_ftype, "%s_snap", S2SMI(sb)->smsi_cache_ftype);
191 S2SNAPI(sb)->snap_cache_fsfilt = fsfilt_get_ops(snap_cache_ftype);
192 OBD_FREE(snap_cache_ftype, tmp + 1);
193 if (!S2SNAPI(sb)->snap_cache_fsfilt) {
194 CERROR("Can not get %s fsfilt ops needed by snap\n",
199 if (!S2SNAPI(sb)->snap_fsfilt) {
200 char *snap_ftype = NULL;
201 int tmp = strlen(S2SMI(sb)->smsi_ftype) + strlen("_snap");
203 OBD_ALLOC(snap_ftype, tmp + 1);
204 sprintf(snap_ftype, "%s_snap", S2SMI(sb)->smsi_ftype);
205 S2SNAPI(sb)->snap_fsfilt = fsfilt_get_ops(snap_ftype);
206 OBD_FREE(snap_ftype, tmp + 1);
207 if (!S2SNAPI(sb)->snap_fsfilt) {
208 CERROR("Can not get %s fsfilt ops needed by snap\n",
213 rc = smfs_init_snaptabe(sb);
215 CERROR("can not init snaptable rc=%d\n", rc);
218 /*init dot snap info*/
219 rc = smfs_init_dotinfo(sb);
221 CERROR("can not init dot snap info rc=%d\n", rc);
224 /*init cowed dir to put the primary cowed inode
225 *FIXME-WANGDI, later the s_root may not be the
226 *snap dir, we can indicate any dir to be cowed*/
227 rc = smfs_init_cowed_dir(sb, sb->s_root);
230 EXPORT_SYMBOL(smfs_start_cow);
231 int smfs_stop_cow(struct super_block *sb)
233 struct snap_info *snap_info = S2SNAPI(sb);
234 struct snap_table *snap_table = snap_info->sntbl;
235 int rc = 0, table_size;
238 l_dput(snap_info->sn_cowed_dentry);
240 if (snap_info->snap_fsfilt)
241 fsfilt_put_ops(snap_info->snap_fsfilt);
242 if (snap_info->snap_cache_fsfilt)
243 fsfilt_put_ops(snap_info->snap_cache_fsfilt);
246 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
247 OBD_FREE(snap_info->sntbl, table_size);
249 smfs_cleanup_dotinfo(sb);
253 EXPORT_SYMBOL(smfs_stop_cow);
255 #define COW_HOOK "cow_hook"
256 static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry,
257 void *data1, void *data2, int op, void *handle)
262 if (smfs_do_cow(inode)) {
263 rc = smfs_cow(inode, dentry, data1, data2, op);
267 int smfs_cow_init(struct super_block *sb)
269 struct smfs_super_info *smfs_info = S2SMI(sb);
270 struct smfs_hook_ops *cow_hops = NULL;
275 SMFS_SET_COW(smfs_info);
277 cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook, NULL);
282 rc = smfs_register_hook_ops(sb, cow_hops);
285 smfs_free_hook_ops(cow_hops);
289 OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
291 if (!smfs_info->smsi_snap_info)
292 GOTO(exit, rc = -ENOMEM);
294 if (rc && cow_hops) {
295 smfs_unregister_hook_ops(sb, cow_hops->smh_name);
296 smfs_free_hook_ops(cow_hops);
301 int smfs_cow_cleanup(struct super_block *sb)
304 struct snap_info *snap_info = S2SNAPI(sb);
305 struct smfs_hook_ops *cow_hops;
308 cow_hops = smfs_unregister_hook_ops(sb, COW_HOOK);
309 smfs_free_hook_ops(cow_hops);
311 SMFS_CLEAN_COW(S2SMI(sb));
313 OBD_FREE(snap_info, sizeof(*snap_info));
317 static int smfs_dotsnap_dir_size(struct inode *inode)
319 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
320 struct fsfilt_operations *snapops = snap_info->snap_cache_fsfilt;
321 struct snap_table *stbl = snap_info->sntbl;
322 int size = 0, dir_size = 0, blocks;
326 for (i = 0; i < stbl->sntbl_count; i++) {
327 size += snapops->fs_dir_ent_size(stbl->sntbl_items[i].sn_name);
329 /*FIXME this is only for ext3 dir format, may need fix for other FS*/
330 blocks = (size + inode->i_sb->s_blocksize - 1) >>
331 inode->i_sb->s_blocksize_bits;
333 dir_size = blocks * inode->i_sb->s_blocksize;
337 /*FIXME Note indirect and primary inode
338 * should be recorgnized here*/
339 int smfs_init_snap_inode_info(struct inode *inode,
340 struct snap_inode_info *sn_info)
342 struct smfs_inode_info *smi = I2SMI(inode);
346 LASSERT(sn_info && smi);
347 smi->sm_sninfo.sn_flags = sn_info->sn_flags;
348 smi->sm_sninfo.sn_gen = sn_info->sn_gen;
349 smi->sm_sninfo.sn_index = sn_info->sn_index;
351 if (smfs_dotsnap_inode(inode)) {
352 struct snap_table *stbl= S2SNAPI(inode->i_sb)->sntbl;
354 /*init dot_snap inode info*/
355 size = smfs_dotsnap_dir_size(inode);
356 inode->i_size = (loff_t)size;
357 inode->i_nlink = stbl->sntbl_count + 2;
360 } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) &&
361 (smi->smi_flags & SM_DO_COW) &&
362 smfs_primary_inode(inode)) {
363 struct snap_inode_info *sni_info = I2SNAPI(inode);
364 struct fsfilt_operations *snapops = I2SNAPOPS(inode);
366 vallen = sizeof(sni_info->sn_gen);
368 rc = snapops->fs_get_snap_info(inode, SNAP_GENERATION,
369 strlen(SNAP_GENERATION),
370 &sni_info->sn_gen, &vallen);
374 /* latest snap: returns
375 - the index of the latest snapshot before NOW
376 - hence it returns 0 in case all the volume snapshots lie in the future
377 - this is the index where a COW will land (will be created)
379 void snap_last(struct super_block *sb, struct snap *snap)
381 struct snap_info *snap_info = S2SNAPI(sb);
382 struct snap_table *table = snap_info->sntbl;
383 time_t now = LTIME_S(CURRENT_TIME);
387 /* start at the highest index in the superblock snaptime array */
388 if (table->sntbl_count == 0) {
389 memset(snap, 0, sizeof(struct snap));
391 i = table->sntbl_count - 1;
392 snap->sn_index = table->sntbl_items[i].sn_index;
393 snap->sn_time = table->sntbl_items[i].sn_time;
394 snap->sn_gen = table->sntbl_items[i].sn_gen;
396 CDEBUG(D_INFO, "index: %d, time[i]: %ld, now: %ld\n",
397 snap->sn_index, snap->sn_time, now);
402 static int inline get_index_of_item(struct snap_table *table, char *name)
404 int count = table->sntbl_count;
408 for (i = 0; i < table->sntbl_max_count; i++) {
409 if (!strcmp(name, table->sntbl_items[i].sn_name)) {
410 CERROR("Duplicate name %s in snaptable\n", name);
415 for (i = 0; i < table->sntbl_max_count; i++) {
417 for (j = 0; j < (count + 1); j++) {
418 if (table->sntbl_items[j].sn_index == i) {
426 CERROR("snaptable Full\n");
430 int smfs_add_snap_item(struct super_block *sb, char *name)
432 struct snap_info *snap_info = S2SNAPI(sb);
433 struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
434 struct snap_table *snap_table = snap_info->sntbl;
435 struct dentry *d_root = snap_info->snap_root;
436 struct snap *snap_item;
437 int table_size, count = 0, index = 0, rc = 0;
439 count = snap_table->sntbl_count;
440 /* XXX Is down this sema necessary*/
441 down_interruptible(&snap_info->sntbl_sema);
442 snap_item = &snap_table->sntbl_items[count];
444 /*add item in snap_table set generation*/
445 snap_item->sn_time = LTIME_S(CURRENT_TIME);
446 /* find table index */
447 index = get_index_of_item(snap_table, name);
449 GOTO(exit, rc = index);
451 snap_item->sn_index = index;
452 snap_item->sn_flags = 0;
453 snap_item->sn_gen = snap_table->sntbl_generation + 1;
454 memcpy(snap_item->sn_name, name, SNAP_MAX_NAMELEN);
455 /* Wrote the whole snap_table to disk */
456 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
458 rc = snapops->fs_set_snap_info(d_root->d_inode, SNAPTABLE_INFO,
459 strlen(SNAPTABLE_INFO),
460 snap_table, &table_size);
462 CERROR("Set snaptable error rc=%d\n", rc);
465 snap_table->sntbl_count++;
466 snap_table->sntbl_generation++;
468 up(&snap_info->sntbl_sema);
471 EXPORT_SYMBOL(smfs_add_snap_item);
473 * Note: this function should be differnet with snap_do_cow.
474 * In smfs_do_cow, we check the EA for whether do cow for that inode.
475 * In smfs_needs_cow, we check whether we do need to do cow.
477 int smfs_needs_cow(struct inode *inode)
479 struct smfs_inode_info *smi_info = I2SMI(inode);
480 struct snap_inode_info *snap_info = NULL;
485 snap_info = &(smi_info->sm_sninfo);
487 snap_last(inode->i_sb, &snap);
488 /* decision .... if the snapshot is more recent than the object,
489 * then any change to the object should cause a COW.
491 if (snap_info->sn_gen < snap.sn_gen )
492 index = snap.sn_index;
494 CDEBUG(D_INFO, "snap_needs_cow, ino %lu , get index %d\n",
495 inode->i_ino, index);
498 } /* snap_needs_cow */
500 static int link_cowed_inode(struct inode *inode)
502 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
503 struct dentry *cowed_dir = NULL;
504 char fidname[LL_FID_NAMELEN];
505 int fidlen = 0, rc = 0;
506 struct dentry *dchild = NULL;
507 struct dentry *tmp = NULL;
510 cowed_dir = snap_info->sn_cowed_dentry;
512 fidlen = ll_fid2str(fidname, inode->i_ino, inode->i_generation);
514 down(&cowed_dir->d_inode->i_sem);
515 dchild = ll_lookup_one_len(fidname, cowed_dir, fidlen);
516 if (IS_ERR(dchild)) {
517 rc = PTR_ERR(dchild);
518 if (rc != -EPERM && rc != -EACCES)
519 CERROR("child lookup error %d\n", rc);
522 if (dchild->d_inode != NULL) {
523 CERROR("re-cowed file %s?\n", dchild->d_name.name);
524 LASSERT(dchild->d_inode == inode);
525 GOTO(out_dput, rc = 0);
527 tmp = pre_smfs_dentry(NULL, inode, cowed_dir, NULL);
528 /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG
529 * for linking and return real mode back then -bzzz */
530 mode = inode->i_mode;
531 inode->i_mode = S_IFREG;
532 rc = vfs_link(tmp, cowed_dir->d_inode, dchild);
533 post_smfs_dentry(tmp);
535 CERROR("error linking cowed inode %s to COWED: rc = %d\n",
538 inode->i_mode = mode;
539 if ((mode & S_IFMT) == S_IFDIR) {
540 dchild->d_inode->i_nlink++;
541 cowed_dir->d_inode->i_nlink++;
543 mark_inode_dirty(dchild->d_inode);
547 up(&cowed_dir->d_inode->i_sem);
551 * Make a copy of the data and plug a redirector in between if there
552 * is no redirector yet.
554 int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
556 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
557 struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
559 struct inode *ind = NULL;
563 if (!snapops || !snapops->fs_create_indirect)
566 snap_last(inode->i_sb, &snap);
567 ind = snapops->fs_create_indirect(inode, snap.sn_index, snap.sn_gen,
568 dparent->d_inode, del);
569 if(ind && IS_ERR(ind)) {
570 CERROR("Create ind inode %lu index %d gen %d del %d rc%lu\n",
571 inode->i_ino, snap.sn_index, snap.sn_gen, del,
573 RETURN(PTR_ERR(ind));
576 if (!SMFS_DO_INODE_COWED(inode)) {
577 /*insert the inode to cowed inode*/
578 SMFS_SET_INODE_COWED(inode);
579 link_cowed_inode(inode);
582 I2SMI(ind)->sm_sninfo.sn_flags = 0;
583 I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen;
584 I2SMI(ind)->sm_sninfo.sn_index = snap.sn_index;
590 /*Dir inode will do cow*/
591 int smfs_cow_create(struct inode *dir, struct dentry *dentry,
592 void *data1, void *data2)
595 struct dentry *dparent;
598 if (smfs_needs_cow(dir) != -1) {
599 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
600 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
601 dparent = dentry->d_parent->d_parent;
602 if ((rc = snap_do_cow(dir, dparent, 0))) {
603 CERROR("Do cow error %d\n", rc);
610 int smfs_cow_setattr(struct inode *dir, struct dentry *dentry,
611 void *data1, void *data2)
615 if (smfs_needs_cow(dir) != -1) {
616 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
617 if ((snap_do_cow(dir, dentry->d_parent, 0))) {
618 CERROR("Do cow error\n");
625 int smfs_cow_link(struct inode *dir, struct dentry *dentry,
626 void *data1, void *data2)
629 struct dentry *dparent;
632 if (smfs_needs_cow(dir) != -1) {
633 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
634 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
635 dparent = dentry->d_parent->d_parent;
636 if ((snap_do_cow(dir, dparent, 0))) {
637 CERROR("Do cow error\n");
640 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
641 CERROR("Do cow error\n");
648 int smfs_cow_unlink(struct inode *dir, struct dentry *dentry,
649 void *data1, void *data2)
651 struct dentry *dparent;
655 if (smfs_needs_cow(dir) != -1) {
656 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
657 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
658 dparent = dentry->d_parent->d_parent;
659 if ((snap_do_cow(dir, dparent, 0))) {
660 CERROR("Do cow error\n");
663 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 1))) {
664 CERROR("Do cow error\n");
672 int smfs_cow_rename(struct inode *dir, struct dentry *dentry,
673 void *data1, void *data2)
675 struct inode *new_dir = (struct inode *)data1;
676 struct dentry *new_dentry = (struct dentry *)data2;
677 struct dentry *dparent;
683 if (smfs_needs_cow(dir) != -1) {
684 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", dir->i_ino);
685 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
686 dparent = dentry->d_parent->d_parent;
687 if ((snap_do_cow(dir, dparent, 0))) {
688 CERROR("Do cow error\n");
691 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
692 CERROR("Do cow error\n");
696 if (smfs_needs_cow(new_dir) != -1) {
697 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", new_dir->i_ino);
698 LASSERT(new_dentry->d_parent && new_dentry->d_parent->d_parent);
699 dparent = new_dentry->d_parent->d_parent;
700 if ((new_dir != dir) && (snap_do_cow(new_dir, dparent, 0))){
701 CERROR("Do cow error\n");
704 if (new_dentry->d_inode && new_dentry->d_inode->i_nlink == 1) {
705 if ((snap_do_cow(new_dentry->d_inode,
706 new_dentry->d_parent, 0))) {
707 CERROR("Do cow error\n");
715 int smfs_cow_write(struct inode *inode, struct dentry *dentry, void *data1,
718 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
719 struct snap_table *table = snap_info->sntbl;
720 long blocks[2]={-1,-1};
721 int index = 0, i, rc = 0;
730 count = *(size_t *)data1;
731 pos = *(loff_t*)data2;
735 if (smfs_needs_cow(inode) != -1 ) {
736 CDEBUG(D_INFO, "snap_needs_cow for ino %lu \n",inode->i_ino);
737 snap_do_cow(inode, dentry->d_parent, 0);
740 CDEBUG(D_INFO, "write offset %lld count %u \n", pos, count);
742 if(pos & (PAGE_CACHE_SIZE - 1)){
743 blocks[0] = pos >> inode->i_sb->s_blocksize_bits;
746 if((pos + 1) & (PAGE_CACHE_SIZE - 1)){
747 blocks[1] = pos >> inode->i_sb->s_blocksize_bits;
750 if (blocks[0] == blocks[1])
753 for (i = 0; i < 2; i++) {
757 /*Find the nearest page in snaptable and copy back it*/
758 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
759 struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
760 struct inode *cache_inode = NULL;
763 index = table->sntbl_items[slot].sn_index;
764 cache_inode = snapops->fs_get_indirect(inode, NULL, index);
766 if (!cache_inode) continue;
768 CDEBUG(D_INFO, "find cache_ino %lu\n", cache_inode->i_ino);
770 result = snapops->fs_copy_block(inode, cache_inode, blocks[i]);
779 GOTO(exit, rc = result);
788 EXPORT_SYMBOL(smfs_cow_write);
789 /*lookup inode in dotsnap inode */
790 static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry)
792 if (dentry->d_name.len == 1 &&
793 !strcmp(dentry->d_name.name, ".")) {
794 d_add(dentry, iget(dir->i_sb, dir->i_ino));
795 } else if (dentry->d_name.len == 2 &&
796 !strcmp(dentry->d_name.name, "..")) {
798 struct dentry *dparent = dentry->d_parent;
799 if (dparent->d_inode) {
800 inode = iget(dir->i_sb, dparent->d_inode->i_ino);
802 if (!is_bad_inode(inode))
803 d_add(dentry, inode);
809 /*find the name from the snaptable*/
810 struct fsfilt_operations *snapops = I2SNAPOPS(dir);
811 struct snap_table *table = S2SNAPI(dir->i_sb)->sntbl;
813 int i = 0, index = -1;
814 for (i = 0; i < table->sntbl_count; i++) {
815 char *name = table->sntbl_items[i].sn_name;
816 if ((dentry->d_name.len == strlen(name)) &&
817 (memcmp(dentry->d_name.name, name,
818 dentry->d_name.len) == 0)) {
819 index = table->sntbl_items[i].sn_index;
824 CERROR("No such %s in this .snap dir \n",
825 dentry->d_name.name);
828 inode = snapops->fs_get_indirect(dir, NULL, index);
829 d_add(dentry, inode);
833 int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1,
836 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
837 struct snap_dot_info *dot_info = snap_info->sn_dot_info;
838 int rc = 0, index = 0;
841 LASSERT(dot_info != NULL);
842 LASSERT(data1 != NULL);
844 index = *(int *)data1;
846 if (smfs_primary_inode(inode) &&
847 dentry->d_name.len == dot_info->dot_name_len &&
848 memcmp(dentry->d_name.name, dot_info->dot_name,
849 strlen(dot_info->dot_name)) == 0) {
850 struct inode *dot_inode = NULL;
852 dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode,
854 d_add(dentry, dot_inode);
858 if (smfs_dotsnap_inode(inode)) {
859 rc = smfs_dotsnap_lookup(inode, dentry);
865 /*HERE: will replace ino in dentry->d_name according to index*/
866 struct fsfilt_operations *snapops = I2SNAPOPS(inode);
867 char *name = (char *)dentry->d_name.name;
868 unsigned long ino, hash, ind_ino;
869 int len = sizeof(ind_ino);
871 ino = simple_strtoul(name, 0, 0);
873 ind_ino = snapops->fs_get_indirect_ino(inode->i_sb, ino, index);
875 snprintf(name, strlen(name), "0x%lx", ind_ino);
877 hash = init_name_hash();
880 c = *(const unsigned char *)name++;
881 if (c == '\0') break;
882 hash = partial_name_hash(c, hash);
884 dentry->d_name.hash = end_name_hash(hash);
889 struct inode *smfs_cow_get_ind(struct inode *inode, int index)
891 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
892 struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
893 struct snap_table *table = snap_info->sntbl;
894 long block=(index << PAGE_CACHE_SHIFT) >> inode->i_sb->s_blocksize_bits;
898 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
899 struct address_space_operations *aops = inode->i_mapping->a_ops;
900 struct inode *cache_inode = NULL;
903 index = table->sntbl_items[slot].sn_index;
904 cache_inode = snapops->fs_get_indirect(inode, NULL, index);
906 if (!cache_inode ) continue;
908 if (aops->bmap(cache_inode->i_mapping, block))
915 EXPORT_SYMBOL(smfs_cow_get_ind);
917 typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry,
918 void *new_dir, void *new_dentry);
920 static cow_funcs smfs_cow_funcs[HOOK_MAX + 1] = {
921 [HOOK_CREATE] smfs_cow_create,
922 [HOOK_LOOKUP] smfs_cow_lookup,
923 [HOOK_LINK] smfs_cow_link,
924 [HOOK_UNLINK] smfs_cow_unlink,
925 [HOOK_SYMLINK] smfs_cow_create,
926 [HOOK_MKDIR] smfs_cow_create,
927 [HOOK_RMDIR] smfs_cow_unlink,
928 [HOOK_MKNOD] smfs_cow_create,
929 [HOOK_RENAME] smfs_cow_rename,
930 [HOOK_SETATTR] smfs_cow_setattr,
931 [HOOK_WRITE] smfs_cow_write,
934 int smfs_cow(struct inode *dir, struct dentry *dentry, void *new_dir,
935 void *new_dentry, int op)
937 if (smfs_cow_funcs[op]) {
938 return smfs_cow_funcs[op](dir, dentry, new_dir, new_dentry);