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"
44 #define SNAPTABLE_SIZE(size) (sizeof(struct snap_table) + \
45 size * sizeof(struct snap))
47 int smfs_cleanup_snap_info(struct snap_info *snap_info);
49 static int smfs_init_snap_super_info(struct smfs_super_info *smfs_info)
51 struct snap_super_info *snap_sinfo;
56 OBD_ALLOC(smfs_info->smsi_snap_info,
57 sizeof(struct snap_super_info));
59 if (!smfs_info->smsi_snap_info)
60 GOTO(exit, rc = -ENOMEM);
62 snap_sinfo = smfs_info->smsi_snap_info;
64 /*init snap fsfilt operations*/
65 if (!snap_sinfo->snap_cache_fsfilt) {
66 char *snap_cache_ftype = NULL;
67 int tmp = strlen(smfs_info->smsi_cache_ftype) + strlen("_snap");
69 OBD_ALLOC(snap_cache_ftype, tmp + 1);
70 if (!snap_cache_ftype)
71 GOTO(exit, rc = -ENOMEM);
73 sprintf(snap_cache_ftype, "%s_snap", smfs_info->smsi_cache_ftype);
74 snap_sinfo->snap_cache_fsfilt = fsfilt_get_ops(snap_cache_ftype);
75 OBD_FREE(snap_cache_ftype, tmp + 1);
76 if (!snap_sinfo->snap_cache_fsfilt) {
77 CERROR("Can not get %s fsfilt ops needed by snap\n",
79 GOTO(exit, rc = -EINVAL);
82 if (!snap_sinfo->snap_fsfilt) {
83 char *snap_ftype = NULL;
84 int tmp = strlen(smfs_info->smsi_ftype) + strlen("_snap");
86 OBD_ALLOC(snap_ftype, tmp + 1);
88 GOTO(exit, rc = -ENOMEM);
90 sprintf(snap_ftype, "%s_snap", smfs_info->smsi_ftype);
91 snap_sinfo->snap_fsfilt = fsfilt_get_ops(snap_ftype);
92 OBD_FREE(snap_ftype, tmp + 1);
93 if (!snap_sinfo->snap_fsfilt) {
94 CERROR("Can not get %s fsfilt ops needed by snap\n",
96 GOTO(exit, rc = -EINVAL);
99 INIT_LIST_HEAD(&snap_sinfo->snap_list);
101 if (rc && smfs_info->smsi_snap_info)
102 OBD_FREE(snap_sinfo, sizeof(struct snap_super_info));
105 /*FIXME-wangdi Should remove it when integrated it with lustre*/
106 static struct dentry *smfs_simple_mkdir(struct dentry *dir, char *name,
109 struct dentry *dchild;
112 dchild = ll_lookup_one_len(name, dir, strlen(name));
114 GOTO(out_up, dchild);
116 if (dchild->d_inode) {
117 int old_mode = dchild->d_inode->i_mode;
118 if (!S_ISDIR(old_mode))
119 GOTO(out_err, err = -ENOTDIR);
121 /* Fixup directory permissions if necessary */
122 if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
123 CWARN("fixing permissions on %s from %o to %o\n",
124 name, old_mode, mode);
125 dchild->d_inode->i_mode = (mode & S_IALLUGO) |
126 (old_mode & ~S_IALLUGO);
127 mark_inode_dirty(dchild->d_inode);
129 GOTO(out_up, dchild);
131 err = vfs_mkdir(dir->d_inode, dchild, mode);
137 dchild = ERR_PTR(err);
142 static struct snap_info *smfs_find_snap_info(struct inode *inode)
144 struct snap_inode_info *snap_iinfo = I2SNAPI(inode);
145 struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
146 struct snap_info *snap_info = NULL, *tmp;
149 list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list,
151 if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino)
158 static int smfs_dotsnap_dir_size(struct inode *inode)
160 struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
161 struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt;
162 int size = 0, dir_size = 0, blocks, i = 0;
163 struct snap_table *snap_table = NULL;
164 struct snap_info *snap_info = NULL;
167 snap_info = smfs_find_snap_info(inode);
170 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
173 snap_table = snap_info->sni_table;
174 for (i = 0; i < snap_table->sntbl_count; i++) {
175 char *name = snap_table->sntbl_items[i].sn_name;
176 size += snapops->fs_dir_ent_size(name);
178 /*FIXME this is only for ext3 dir format, may need fix for other FS*/
179 blocks = (size + inode->i_sb->s_blocksize - 1) >>
180 inode->i_sb->s_blocksize_bits;
182 dir_size = blocks * inode->i_sb->s_blocksize;
188 static int smfs_init_snap_inode_info(struct inode *inode, struct inode *dir, int index)
197 I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags;
198 I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen;
199 I2SNAPI(inode)->sn_root_ino = I2SNAPI(dir)->sn_root_ino;
200 I2SNAPI(inode)->sn_index = I2SNAPI(inode)->sn_index;
202 I2SNAPI(inode)->sn_flags = 0;
203 I2SNAPI(inode)->sn_gen = 0;
206 I2SNAPI(inode)->sn_index = index;
208 if (smfs_dotsnap_inode(inode)) {
209 struct snap_info *snap_info;
211 snap_info = smfs_find_snap_info(inode);
215 /*init dot_snap inode info*/
216 // inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode);
217 inode->i_size = snap_info->sni_table->sntbl_count;
218 inode->i_nlink = snap_info->sni_table->sntbl_count + 2;
221 } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) &&
222 (I2SMI(inode)->smi_flags & SM_DO_COW) &&
223 smfs_primary_inode(inode)) {
224 struct snap_inode_info *sni_info = I2SNAPI(inode);
225 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
228 vallen = sizeof(sni_info->sn_gen);
230 rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION,
231 strlen(SNAP_GENERATION),
232 &sni_info->sn_gen, &vallen);
237 #define COWED_NAME_LEN (7 + 8 + 1)
238 static int smfs_init_cowed_dir(struct snap_info *snap_info, struct inode* inode)
240 struct dentry *dentry = NULL;
241 char name[COWED_NAME_LEN];
245 sprintf(name, ".cowed_%08x", (__u32)inode->i_ino);
246 /*FIXME-WANGDI: will use simple_mkdir, when integrating snap to lustre*/
247 dentry = smfs_simple_mkdir(inode->i_sb->s_root, name, 0777, 1);
248 if (IS_ERR(dentry)) {
249 rc = PTR_ERR(dentry);
250 CERROR("create cowed directory: rc = %d\n", rc);
253 snap_info->sni_cowed_dentry = dentry;
254 /*cleanup cowed inode attr for cowed dir*/
255 SMFS_CLEAN_INODE_COWED(dentry->d_inode);
259 static int smfs_init_dotinfo(struct snap_info *snap_info)
261 struct snap_dot_info *dot_info = NULL;
265 if (snap_info->sni_dot_info)
268 OBD_ALLOC(snap_info->sni_dot_info, sizeof(struct snap_dot_info));
270 if (!snap_info->sni_dot_info)
273 dot_info = snap_info->sni_dot_info;
275 OBD_ALLOC(dot_info->dot_name, strlen(DOT_SNAP_NAME) + 1);
277 if (!dot_info->dot_name) {
278 OBD_FREE(snap_info->sni_dot_info, sizeof(struct snap_dot_info));
281 memcpy(dot_info->dot_name, DOT_SNAP_NAME, strlen(DOT_SNAP_NAME));
283 dot_info->dot_name_len = strlen(DOT_SNAP_NAME);
284 dot_info->dot_snap_enable = 1;
289 static int smfs_init_snap_info(struct smfs_super_info *smb,
290 struct snap_info *snap_info, struct inode *inode)
292 struct snap_table *snap_table = NULL;
293 struct fsfilt_operations *snapcops;
294 int rc = 0, size, table_size, vallen, i;
298 snapcops = smb->smsi_snap_info->snap_cache_fsfilt;
299 /*Initialized table */
300 /*get the maxsize of snaptable*/
301 vallen = sizeof(int);
302 rc = snapcops->fs_get_snap_info(I2CI(inode), MAX_SNAPTABLE_COUNT,
303 strlen(MAX_SNAPTABLE_COUNT), &size,
306 CERROR("the Max snaptable count should not be zero\n");
309 table_size = SNAPTABLE_SIZE(size);
311 OBD_ALLOC(snap_info->sni_table, table_size);
313 if (!snap_info->sni_table) {
317 snap_table = snap_info->sni_table;
319 snap_table->sntbl_magic = cpu_to_le32((__u32)SNAPTABLE_MAGIC);
320 snap_table->sntbl_max_count = size;
321 /*init sn_index to -1*/
322 for (i = 0; i < snap_table->sntbl_max_count; i++)
323 snap_table->sntbl_items[i].sn_index = -1;
324 /*get snaptable info*/
325 rc = snapcops->fs_get_snap_info(I2CI(inode), SNAPTABLE_INFO,
326 strlen(SNAPTABLE_INFO),
327 snap_table, &table_size);
329 if (rc == -ENODATA) {
330 snap_table->sntbl_count = 0;
333 CERROR("Can not retrive the snaptable from this filesystem\n");
337 if (le32_to_cpu(snap_table->sntbl_magic) != SNAPTABLE_MAGIC) {
338 CERROR("On disk snaptable is not right \n");
339 GOTO(exit, rc = -EIO);
342 init_MUTEX(&snap_info->sni_sema);
343 snap_info->sni_root_ino = inode->i_ino;
344 rc = smfs_init_cowed_dir(snap_info, inode);
346 CERROR("Init cowed dir error rc=%d\n", rc);
349 rc = smfs_init_dotinfo(snap_info);
351 if (rc && snap_table)
352 OBD_FREE(snap_table, table_size);
356 static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo,
359 struct snap_info *snap_info = NULL;
363 OBD_ALLOC(snap_info, sizeof(struct snap_info));
365 RETURN(ERR_PTR(-ENOMEM));
366 rc = smfs_init_snap_info(sinfo, snap_info, inode);
370 /*set cow flags for the snap root inode*/
371 I2SMI(inode)->smi_flags |= SM_DO_COW;
372 I2SNAPI(inode)->sn_root_ino = inode->i_ino;
375 OBD_FREE(snap_info, sizeof(struct snap_info));
376 snap_info = ERR_PTR(rc);
381 static int smfs_cow_pre(struct inode *dir, void *dentry, void *new_dir,
382 void *new_dentry, int op);
384 static int smfs_cow_post(struct inode *dir, void *dentry, void *new_dir,
385 void *new_dentry, int op);
386 #define COW_HOOK "cow_hook"
387 static int smfs_cow_pre_hook(struct inode *inode, void *dentry, void *data1,
388 void *data2, int op, void *handle)
393 if (smfs_do_cow(inode)) {
394 /*FIXME:WANGDI, get index from the dentry*/
397 smfs_get_dentry_name_index(dentry, &name, index);
398 smfs_free_dentry_name(&name);
400 rc = smfs_cow_pre(inode, dentry, data1, data2, op);
404 static int smfs_cow_post_hook(struct inode *inode, void *dentry, void *data1,
405 void *data2, int op, void *handle)
410 if (smfs_do_cow(inode)) {
411 rc = smfs_cow_post(inode, dentry, data1, data2, op);
416 int smfs_cow_cleanup(struct smfs_super_info *smb)
418 struct snap_super_info *snap_sinfo = smb->smsi_snap_info;
419 struct list_head *snap_list = &snap_sinfo->snap_list;
420 struct smfs_hook_ops *cow_hops;
424 while (!list_empty(snap_list)) {
425 struct snap_info *snap_info;
427 snap_info = list_entry(snap_list->next, struct snap_info,
429 rc = smfs_cleanup_snap_info(snap_info);
431 CERROR("cleanup snap_info error rc=%d\n", rc);
432 list_del(&snap_info->sni_list);
433 OBD_FREE(snap_info, sizeof(struct snap_info));
436 if (snap_sinfo->snap_fsfilt)
437 fsfilt_put_ops(snap_sinfo->snap_fsfilt);
438 if (snap_sinfo->snap_cache_fsfilt)
439 fsfilt_put_ops(snap_sinfo->snap_cache_fsfilt);
441 cow_hops = smfs_unregister_hook_ops(smb, COW_HOOK);
442 smfs_free_hook_ops(cow_hops);
446 OBD_FREE(snap_sinfo, sizeof(struct snap_super_info));
450 int smfs_cow_init(struct super_block *sb)
452 struct smfs_super_info *smfs_info = S2SMI(sb);
453 struct smfs_hook_ops *cow_hops = NULL;
454 struct fsfilt_operations *sops;
455 struct inode *root_inode = smfs_info->smsi_sb->s_root->d_inode;
456 int snap_count = 0, rc = 0, vallen;
460 SMFS_SET_COW(smfs_info);
462 cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook,
468 rc = smfs_register_hook_ops(smfs_info, cow_hops);
470 smfs_free_hook_ops(cow_hops);
474 rc = smfs_init_snap_super_info(smfs_info);
475 if (rc && cow_hops) {
476 smfs_unregister_hook_ops(smfs_info, cow_hops->smh_name);
477 smfs_free_hook_ops(cow_hops);
480 sops = smfs_info->smsi_snap_info->snap_cache_fsfilt;
482 vallen = sizeof(int);
483 rc = sops->fs_get_snap_info(root_inode, SNAP_COUNT, strlen(SNAP_COUNT),
484 &snap_count, &vallen);
488 if (snap_count > 0) {
489 int snap_root_size = snap_count * sizeof(ino_t);
493 OBD_ALLOC(snap_root, snap_root_size);
496 GOTO(exit, rc = -ENOMEM);
498 rc = sops->fs_get_snap_info(root_inode, SNAP_ROOT_INO,
499 strlen(SNAP_ROOT_INO), snap_root,
502 OBD_FREE(snap_root, sizeof(int) * snap_count);
505 for (i = 0; i < snap_count; i++) {
506 ino_t root_ino = le32_to_cpu(snap_root[i]);
507 struct snap_info *snap_info;
509 root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
510 smfs_init_snap_inode_info(root_inode, NULL, 0);
511 snap_info = smfs_create_snap_info(S2SMI(sb), root_inode);
513 if (IS_ERR(snap_info)) {
514 OBD_FREE(snap_root, sizeof(int) * snap_count);
515 GOTO(exit, rc = PTR_ERR(snap_info));
517 list_add(&snap_info->sni_list,
518 &(S2SNAPI(sb)->snap_list));
521 smfs_info->smsi_snap_info->snap_count = snap_count;
524 smfs_cow_cleanup(smfs_info);
528 static int smfs_cleanup_dotinfo(struct snap_info *snap_info)
530 struct snap_dot_info *dot_info = NULL;
534 if (!snap_info->sni_dot_info)
537 dot_info = snap_info->sni_dot_info;
539 if (dot_info->dot_name) {
540 OBD_FREE(dot_info->dot_name, dot_info->dot_name_len + 1);
543 OBD_FREE(dot_info, sizeof(struct snap_dot_info));
548 int smfs_cleanup_snap_info(struct snap_info *snap_info)
550 struct snap_table *snap_table = snap_info->sni_table;
551 int rc = 0, table_size;
554 l_dput(snap_info->sni_cowed_dentry);
555 //d_unalloc(snap_info->sni_cowed_dentry);
557 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
558 OBD_FREE(snap_info->sni_table, table_size);
560 smfs_cleanup_dotinfo(snap_info);
564 int smfs_snap_test_inode(struct inode *inode, void *args)
566 struct smfs_iget_args *sargs = (struct smfs_iget_args*)args;
571 dir = sargs->s_inode;
573 if (sargs->s_index > 0) {
574 if (I2SNAPI(inode)->sn_index != sargs->s_index)
577 if (dir && I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index)
582 /* latest snap: returns
583 - the index of the latest snapshot before NOW
584 - hence it returns 0 in case all the volume snapshots lie in the future
585 - this is the index where a COW will land (will be created)
587 void snap_last(struct inode *inode, struct snap *snap)
589 time_t now = LTIME_S(CURRENT_TIME);
590 struct snap_table *snap_table;
591 struct snap_info *snap_info;
596 snap_info = smfs_find_snap_info(inode);
598 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
602 snap_table = snap_info->sni_table;
603 /* start at the highest index in the superblock snaptime array */
604 if (snap_table->sntbl_count == 0) {
605 memset(snap, 0, sizeof(struct snap));
607 i = snap_table->sntbl_count - 1;
608 snap->sn_index = snap_table->sntbl_items[i].sn_index;
609 snap->sn_time = snap_table->sntbl_items[i].sn_time;
610 snap->sn_gen = snap_table->sntbl_items[i].sn_gen;
612 CDEBUG(D_INFO, "index: %d, time[i]: %ld, now: %ld\n",
613 snap->sn_index, snap->sn_time, now);
618 static inline int get_index_of_item(struct snap_table *table, char *name)
620 int count = table->sntbl_count;
624 for (i = 0; i < table->sntbl_max_count; i++) {
625 if (!strcmp(name, table->sntbl_items[i].sn_name)) {
626 CERROR("Duplicate name %s in snaptable\n", name);
631 for (i = 1; i <= table->sntbl_max_count; i++) {
633 for (j = 0; j < (count + 1); j++) {
634 if (table->sntbl_items[j].sn_index == i) {
642 CERROR("snaptable Full\n");
646 static struct dentry *smfs_find_snap_root(struct super_block *sb,
649 struct dentry *dentry = NULL;
653 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
654 if (path_init(path_name, LOOKUP_FOLLOW, &nd)) {
655 int error = path_walk(path_name, &nd);
664 if (path_lookup(path_name, LOOKUP_FOLLOW, &nd))
667 dentry = dget(nd.dentry);
672 static int snap_add_item(struct smfs_super_info *smb,
673 struct snap_info *snap_info,
676 struct fsfilt_operations *snapops;
677 struct snap_table *snap_table = snap_info->sni_table;
678 struct inode *root_inode = NULL;
679 int table_size, count = 0, index = 0, rc = 0;
680 struct snap *snap_item;
683 count = snap_table->sntbl_count;
684 root_inode = iget(smb->smsi_sb, snap_info->sni_root_ino);
685 if (!root_inode || is_bad_inode(root_inode))
687 /* XXX Is down this sema necessary*/
688 down_interruptible(&snap_info->sni_sema);
689 snap_item = &snap_table->sntbl_items[count];
690 snapops = smb->smsi_snap_info->snap_cache_fsfilt;
691 /*add item in snap_table set generation*/
692 snap_item->sn_time = LTIME_S(CURRENT_TIME);
693 /* find table index */
694 index = get_index_of_item(snap_table, name);
696 GOTO(exit, rc = index);
698 snap_item->sn_index = index;
699 snap_item->sn_flags = 0;
700 snap_item->sn_gen = snap_table->sntbl_generation + 1;
701 memcpy(snap_item->sn_name, name, SNAP_MAX_NAMELEN);
702 /* Wrote the whole snap_table to disk */
703 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
705 snap_table->sntbl_count++;
706 snap_table->sntbl_generation++;
707 rc = snapops->fs_set_snap_info(root_inode, SNAPTABLE_INFO,
708 strlen(SNAPTABLE_INFO),
709 snap_table, &table_size);
711 snap_table->sntbl_count--;
712 snap_table->sntbl_generation--;
713 CERROR("Set snaptable error rc=%d\n", rc);
717 up(&snap_info->sni_sema);
723 static struct snap_info * smfs_find_create_snap_info(struct super_block *sb,
726 struct snap_super_info *snap_sinfo = S2SNAPI(sb);
727 struct fsfilt_operations *sops = snap_sinfo->snap_cache_fsfilt;
728 struct snap_info *snap_info, *tmp;
729 ino_t *snap_root = NULL;
730 int rino_size, snap_count_size, rc = 0;
733 list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list,
735 if (snap_info->sni_root_ino == inode->i_ino) {
740 CDEBUG(D_INFO, "create a new snap info root ino %lu\n", inode->i_ino);
742 snap_info = smfs_create_snap_info(S2SMI(sb), inode);
744 if (IS_ERR(snap_info))
747 snap_sinfo->snap_count++;
749 rino_size = snap_sinfo->snap_count * sizeof(ino_t);
751 OBD_ALLOC(snap_root, rino_size);
754 GOTO(exit, rc = -ENOMEM);
756 rc = sops->fs_get_snap_info(I2CI(inode), SNAP_ROOT_INO,
757 strlen(SNAP_ROOT_INO), snap_root,
760 if (rc == -ENODATA) {
766 snap_root[snap_sinfo->snap_count - 1] = inode->i_ino;
768 snap_count_size = sizeof(int);
769 rc = sops->fs_set_snap_info(I2CI(inode), SNAP_COUNT, strlen(SNAP_COUNT),
770 &snap_sinfo->snap_count, &snap_count_size);
774 rc = sops->fs_set_snap_info(I2CI(inode), SNAP_ROOT_INO,
775 strlen(SNAP_ROOT_INO), snap_root,
781 list_add(&snap_info->sni_list, &snap_sinfo->snap_list);
784 smfs_cleanup_snap_info(snap_info);
785 OBD_FREE(snap_info, sizeof(struct snap_info));
788 OBD_FREE(snap_root, rino_size);
792 int smfs_add_snap_item(struct super_block *sb, char *path_name, char *name)
794 struct dentry *dentry = NULL;
795 struct snap_info *snap_info;
799 if (!SMFS_DO_COW(S2SMI(sb))) {
803 if (!path_name || !name) {
804 CERROR("patch_name and snapshot_name is NULL");
807 dentry = smfs_find_snap_root(sb, path_name);
808 if (IS_ERR(dentry)) {
809 CERROR("can not find snap_shot root by %s\n", path_name);
810 RETURN(PTR_ERR(dentry));
812 snap_info = smfs_find_create_snap_info(sb, dentry->d_inode);
813 if (IS_ERR(snap_info)) {
814 CERROR("can not find snap_info by %s rc=%lu\n", path_name,
816 GOTO(exit, rc = PTR_ERR(snap_info));
819 rc = snap_add_item(S2SMI(sb), snap_info, name);
824 //EXPORT_SYMBOL(smfs_add_snap_item);
826 * Note: this function should be differnet with snap_do_cow.
827 * In smfs_do_cow, we check the EA for whether do cow for that inode.
828 * In smfs_needs_cow, we check whether we do need to do cow.
830 int smfs_needs_cow(struct inode *inode)
832 struct smfs_inode_info *smi_info = I2SMI(inode);
833 struct snap_inode_info *snap_info = NULL;
838 snap_info = &(smi_info->sm_sninfo);
840 snap_last(inode, &snap);
841 /* decision .... if the snapshot is more recent than the object,
842 * then any change to the object should cause a COW.
844 if (snap_info->sn_gen < snap.sn_gen )
845 index = snap.sn_index;
847 CDEBUG(D_INFO, "snap_needs_cow, ino %lu , get index %d\n",
848 inode->i_ino, index);
851 } /* snap_needs_cow */
853 static int link_cowed_inode(struct inode *inode)
855 struct dentry *cowed_dir = NULL;
856 char idname[LL_ID_NAMELEN];
857 struct snap_info *snap_info;
858 int idlen = 0, rc = 0;
859 struct dentry *dchild = NULL;
860 struct dentry *tmp = NULL;
863 snap_info = smfs_find_snap_info(inode);
865 CERROR("can not find snap info for inode %p\n", inode);
869 cowed_dir = snap_info->sni_cowed_dentry;
871 down(&cowed_dir->d_inode->i_sem);
873 idlen = ll_id2str(idname, inode->i_ino, inode->i_generation);
874 dchild = lookup_one_len(idname, cowed_dir, idlen);
875 if (IS_ERR(dchild)) {
876 rc = PTR_ERR(dchild);
877 if (rc != -EPERM && rc != -EACCES)
878 CERROR("child lookup error %d\n", rc);
881 if (dchild->d_inode != NULL) {
882 CERROR("re-cowed file %s?\n", dchild->d_name.name);
883 LASSERT(dchild->d_inode == inode);
884 GOTO(out_dput, rc = 0);
886 tmp = pre_smfs_dentry(NULL, inode, cowed_dir);
887 /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG
888 * for linking and return real mode back then -bzzz */
889 mode = inode->i_mode;
890 inode->i_mode = S_IFREG;
892 rc = cowed_dir->d_inode->i_op->link(tmp, cowed_dir->d_inode, dchild);
894 post_smfs_dentry(tmp);
896 CERROR("error linking cowed inode %s to COWED: rc = %d\n",
899 inode->i_mode = mode;
900 if ((mode & S_IFMT) == S_IFDIR) {
901 dchild->d_inode->i_nlink++;
902 cowed_dir->d_inode->i_nlink++;
903 mark_inode_dirty(cowed_dir->d_inode);
904 mark_inode_dirty(dchild->d_inode);
907 up(&cowed_dir->d_inode->i_sem);
913 * Make a copy of the data and plug a redirector in between if there
914 * is no redirector yet.
916 int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
918 struct fsfilt_operations *snapops = I2SNAPCOPS(inode);
920 struct inode *cache_ind = NULL;
923 if (!snapops || !snapops->fs_create_indirect)
926 snap_last(inode, &snap);
927 cache_ind = snapops->fs_create_indirect(I2CI(inode), snap.sn_index,
928 snap.sn_gen, I2CI(dparent->d_inode),
930 if(cache_ind && IS_ERR(cache_ind)) {
931 CERROR("Create ind inode %lu index %d gen %d del %d rc%lu\n",
932 inode->i_ino, snap.sn_index, snap.sn_gen, del,
934 RETURN(PTR_ERR(cache_ind));
938 if (!SMFS_DO_INODE_COWED(inode)) {
939 /*insert the inode to cowed inode*/
940 SMFS_SET_INODE_COWED(inode);
941 link_cowed_inode(inode);
946 /*Dir inode will do cow*/
947 int smfs_cow_create_pre(struct inode *dir, void *de, void *data1, void *data2)
949 struct dentry *dparent;
950 struct dentry *dentry = (struct dentry *)de;
954 if (smfs_needs_cow(dir) != -1) {
955 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
956 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
957 dparent = dentry->d_parent->d_parent;
958 if ((rc = snap_do_cow(dir, dparent, 0))) {
959 CERROR("Do cow error %d\n", rc);
966 int smfs_cow_setattr_pre(struct inode *dir, void *de, void *data1, void *data2)
968 struct dentry *dentry = (struct dentry *)de;
971 if (smfs_needs_cow(dir) != -1) {
972 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
973 if ((snap_do_cow(dir, dentry->d_parent, 0))) {
974 CERROR("Do cow error\n");
981 int smfs_cow_link_pre(struct inode *dir, void *de, void *data1, void *data2)
983 struct dentry *dparent;
984 struct dentry *dentry = (struct dentry *)de;
988 if (smfs_needs_cow(dir) != -1) {
989 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
990 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
991 dparent = dentry->d_parent->d_parent;
992 if ((snap_do_cow(dir, dparent, 0))) {
993 CERROR("Do cow error\n");
996 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
997 CERROR("Do cow error\n");
1004 int smfs_cow_unlink_pre(struct inode *dir, void *de, void *data1, void *data2)
1006 struct dentry *dentry = (struct dentry *)de;
1007 struct dentry *dparent;
1011 if (smfs_needs_cow(dir) != -1) {
1012 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
1013 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
1014 dparent = dentry->d_parent->d_parent;
1015 if ((snap_do_cow(dir, dparent, 0))) {
1016 CERROR("Do cow error\n");
1019 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 1))) {
1020 CERROR("Do cow error\n");
1028 int smfs_cow_rename_pre(struct inode *dir, void *de, void *data1, void *data2)
1030 struct dentry *dentry = (struct dentry*)de;
1031 struct inode *new_dir = (struct inode *)data1;
1032 struct dentry *new_dentry = (struct dentry *)data2;
1033 struct dentry *dparent;
1038 LASSERT(new_dentry);
1039 if (smfs_needs_cow(dir) != -1) {
1040 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", dir->i_ino);
1041 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
1042 dparent = dentry->d_parent->d_parent;
1043 if ((snap_do_cow(dir, dparent, 0))) {
1044 CERROR("Do cow error\n");
1047 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
1048 CERROR("Do cow error\n");
1052 if (smfs_needs_cow(new_dir) != -1) {
1053 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", new_dir->i_ino);
1054 LASSERT(new_dentry->d_parent && new_dentry->d_parent->d_parent);
1055 dparent = new_dentry->d_parent->d_parent;
1056 if ((new_dir != dir) && (snap_do_cow(new_dir, dparent, 0))){
1057 CERROR("Do cow error\n");
1060 if (new_dentry->d_inode && new_dentry->d_inode->i_nlink == 1) {
1061 if ((snap_do_cow(new_dentry->d_inode,
1062 new_dentry->d_parent, 0))) {
1063 CERROR("Do cow error\n");
1071 int smfs_cow_write_pre(struct inode *inode, void *de, void *data1, void *data2)
1073 struct dentry *dentry = (struct dentry*)de;
1074 struct snap_info *snap_info = NULL;
1075 struct snap_table *table;
1076 long blocks[2]={-1,-1};
1077 int index = 0, i, rc = 0;
1083 snap_info = smfs_find_snap_info(inode);
1085 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1088 table = snap_info->sni_table;
1093 count = *(size_t *)data1;
1094 pos = *(loff_t*)data2;
1096 down(&inode->i_sem);
1098 if (smfs_needs_cow(inode) != -1 ) {
1099 CDEBUG(D_INFO, "snap_needs_cow for ino %lu \n",inode->i_ino);
1100 snap_do_cow(inode, dentry->d_parent, 0);
1103 CDEBUG(D_INFO, "write offset %lld count %u \n", pos, count);
1105 if(pos & (PAGE_CACHE_SIZE - 1)){
1106 blocks[0] = pos >> inode->i_sb->s_blocksize_bits;
1109 if((pos + 1) & (PAGE_CACHE_SIZE - 1)){
1110 blocks[1] = pos >> inode->i_sb->s_blocksize_bits;
1113 if (blocks[0] == blocks[1])
1116 for (i = 0; i < 2; i++) {
1118 if (blocks[i] == -1)
1120 /*Find the nearest page in snaptable and copy back it*/
1121 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
1122 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1123 struct inode *cind = NULL;
1126 index = table->sntbl_items[slot].sn_index;
1127 cind = sops->fs_get_indirect(I2CI(inode), NULL, index);
1128 if (!cind) continue;
1130 CDEBUG(D_INFO, "find cache_ino %lu\n", cind->i_ino);
1132 result = sops->fs_copy_block(I2CI(inode), cind,
1142 GOTO(exit, rc = result);
1151 EXPORT_SYMBOL(smfs_cow_write_pre);
1152 /*lookup inode in dotsnap inode */
1153 static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry,
1154 struct snap_info *snap_info)
1156 if (dentry->d_name.len == 1 &&
1157 !strcmp(dentry->d_name.name, ".")) {
1158 d_add(dentry, iget(dir->i_sb, dir->i_ino));
1159 } else if (dentry->d_name.len == 2 &&
1160 !strcmp(dentry->d_name.name, "..")) {
1161 struct inode *inode;
1162 struct dentry *dparent = dentry->d_parent;
1163 if (dparent->d_inode) {
1164 inode = iget(dir->i_sb, dparent->d_inode->i_ino);
1166 if (!is_bad_inode(inode))
1167 d_add(dentry, inode);
1173 /*find the name from the snaptable*/
1174 struct fsfilt_operations *sops = I2SNAPCOPS(dir);
1175 struct snap_table *table;
1176 struct inode *inode;
1178 int i = 0, index = -1;
1180 table = snap_info->sni_table;
1182 for (i = 0; i < table->sntbl_count; i++) {
1183 char *name = table->sntbl_items[i].sn_name;
1184 if ((dentry->d_name.len == strlen(name)) &&
1185 (memcmp(dentry->d_name.name, name,
1186 dentry->d_name.len) == 0)) {
1187 index = table->sntbl_items[i].sn_index;
1192 CERROR("No such %s in this .snap dir \n",
1193 dentry->d_name.name);
1196 cino = sops->fs_get_indirect_ino(S2CSB(dir->i_sb), dir->i_ino,
1200 inode = smfs_get_inode(dir->i_sb, cino, dir, index);
1201 if (!inode || is_bad_inode(inode)) {
1202 CERROR("Can not find cino %lu inode\n", cino);
1205 smfs_init_snap_inode_info(inode, dir, index);
1206 d_add(dentry, inode);
1210 int smfs_cow_lookup_pre(struct inode *inode, void *de, void *data1,
1213 struct dentry *dentry = (struct dentry*)de;
1214 struct snap_info *snap_info;
1215 struct snap_dot_info *dot_info;
1219 snap_info = smfs_find_snap_info(inode);
1221 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1225 dot_info = snap_info->sni_dot_info;
1227 if (smfs_primary_inode(inode) &&
1228 dentry->d_name.len == dot_info->dot_name_len &&
1229 memcmp(dentry->d_name.name, dot_info->dot_name,
1230 strlen(dot_info->dot_name)) == 0) {
1231 struct inode *dot_inode = NULL;
1233 dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode,
1235 smfs_init_snap_inode_info(dot_inode, inode, DOT_SNAP_INDEX);
1236 d_add(dentry, dot_inode);
1239 } else if (smfs_dotsnap_inode(inode)) {
1240 rc = smfs_dotsnap_lookup(inode, dentry, snap_info);
1245 /*HERE: will replace ino in dentry->d_name according to index,
1246 *For iopen, will fix it in integrating snapfs to Lustre*/
1248 struct fsfilt_operations *snapops = I2SNAPOPS(inode);
1249 char *name = (char *)dentry->d_name.name;
1250 unsigned long ino, hash, ind_ino;
1251 int len = sizeof(ind_ino);
1253 ino = simple_strtoul(name, 0, 0);
1255 ind_ino = snapops->fs_get_indirect_ino(inode->i_sb, ino, index);
1257 snprintf(name, strlen(name), "0x%lx", ind_ino);
1259 hash = init_name_hash();
1262 c = *(const unsigned char *)name++;
1263 if (c == '\0') break;
1264 hash = partial_name_hash(c, hash);
1266 dentry->d_name.hash = end_name_hash(hash);
1272 struct inode *smfs_cow_get_ind(struct inode *inode, int index)
1274 long block=(index << PAGE_CACHE_SHIFT) >> inode->i_sb->s_blocksize_bits;
1275 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1276 struct snap_info *snap_info = NULL;
1277 struct snap_table *table = NULL;
1282 snap_info = smfs_find_snap_info(inode);
1284 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1288 table = snap_info->sni_table;
1290 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
1291 struct address_space_operations *aops = inode->i_mapping->a_ops;
1292 struct inode *cache_inode = NULL;
1295 index = table->sntbl_items[slot].sn_index;
1296 cache_inode = sops->fs_get_indirect(I2CI(inode), NULL, index);
1298 if (!cache_inode ) continue;
1300 if (aops->bmap(cache_inode->i_mapping, block))
1301 RETURN(cache_inode);
1307 EXPORT_SYMBOL(smfs_cow_get_ind);
1309 static int smfs_cow_readdir_pre(struct inode *dir, void *de, void *data1,
1312 struct file *filp = (struct file*)de;
1313 void *dirent = data1;
1314 filldir_t filldir = (filldir_t)data2;
1315 struct snap_info *snap_info = NULL;
1317 if (smfs_under_dotsnap_inode(dir))
1320 snap_info = smfs_find_snap_info(dir);
1323 CDEBUG(D_INFO, "can not find snap info for ino %lu\n",
1328 if (smfs_primary_inode(dir)) {
1329 if (filp->f_pos == 0) {
1330 struct snap_dot_info *dot = snap_info->sni_dot_info;
1331 if (filldir(dirent, dot->dot_name, dot->dot_name_len,
1332 filp->f_pos, -1, 0)) {
1333 CERROR("fill .snap error \n");
1339 } else if (smfs_dotsnap_inode(dir)) {
1340 struct snap_table *table = snap_info->sni_table;
1343 if (filp->f_pos < 0)
1346 if ((filp->f_pos == 0) && filldir(dirent, ".", 1,
1350 if ((filp->f_pos == 1) && filldir(dirent, "..", 2,
1355 for (i = filp->f_pos - 2; i < table->sntbl_count; i++,
1357 int slot = table->sntbl_count - i - 1;
1359 if (filldir(dirent, table->sntbl_items[slot].sn_name,
1360 strlen(table->sntbl_items[slot].sn_name),
1361 filp->f_pos, dir->i_ino, 0))
1372 typedef int (*cow_funcs)(struct inode *dir, void *dentry, void *new_dir,
1375 static cow_funcs smfs_cow_pre_funcs[HOOK_MAX + 1] = {
1376 [HOOK_CREATE] smfs_cow_create_pre,
1377 [HOOK_LOOKUP] smfs_cow_lookup_pre,
1378 [HOOK_LINK] smfs_cow_link_pre,
1379 [HOOK_UNLINK] smfs_cow_unlink_pre,
1380 [HOOK_SYMLINK] smfs_cow_create_pre,
1381 [HOOK_MKDIR] smfs_cow_create_pre,
1382 [HOOK_RMDIR] smfs_cow_unlink_pre,
1383 [HOOK_MKNOD] smfs_cow_create_pre,
1384 [HOOK_RENAME] smfs_cow_rename_pre,
1385 [HOOK_SETATTR] smfs_cow_setattr_pre,
1386 [HOOK_WRITE] smfs_cow_write_pre,
1387 [HOOK_READDIR] smfs_cow_readdir_pre,
1390 static int smfs_revalidate_dotsnap_dentry(struct dentry *dentry,
1391 struct inode *dir, int index)
1393 struct inode *inode = dentry->d_inode;
1399 if (index > 0 && index != DOT_SNAP_INDEX) {
1400 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1401 struct inode *cache_ind = NULL;
1403 cache_ind = sops->fs_get_indirect(I2CI(inode), NULL, index);
1406 struct inode *ind_inode = NULL;
1408 LASSERT(cache_ind->i_ino != I2CI(inode)->i_ino);
1410 ind_inode = smfs_get_inode(inode->i_sb, cache_ind->i_ino,
1412 list_del_init(&dentry->d_alias);
1414 d_instantiate(dentry, ind_inode);
1421 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1423 smfs_revalidate_nd(struct dentry *de, struct nameidata *nd)
1425 struct inode *inode = de->d_inode;
1431 if (smfs_under_dotsnap_inode(inode)) {
1432 struct inode *dir = de->d_parent->d_inode;
1433 int index = I2SNAPI(inode)->sn_index;
1435 smfs_revalidate_dotsnap_dentry(de, dir, index);
1436 smfs_init_snap_inode_info(de->d_inode, dir, index);
1443 smfs_revalidate_it(struct dentry *de, int flags,
1444 struct nameidata *nd,
1445 struct lookup_intent *it)
1447 struct inode *inode = de->d_inode;
1453 if (smfs_under_dotsnap_inode(inode)) {
1454 struct inode *dir = de->d_parent->d_inode;
1455 int index = I2SNAPI(inode)->sn_index;
1457 smfs_revalidate_dotsnap_dentry(de, dir, index);
1458 smfs_init_snap_inode_info(de->d_inode, dir, index);
1465 static int smfs_delete_dentry(struct dentry *dentry)
1467 dentry->d_op = NULL;
1471 struct dentry_operations smfs_cow_dops = {
1472 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1473 .d_revalidate = smfs_revalidate_nd,
1475 .d_revalidate_it = smfs_revalidate_it,
1477 .d_delete = smfs_delete_dentry,
1480 int smfs_cow_lookup_post(struct inode *dir, void *de, void *data1,
1483 struct dentry *dentry = (struct dentry*)de;
1484 struct inode *inode = dentry->d_inode;
1487 if (inode && smfs_under_dotsnap_inode(inode)) {
1488 int index = I2SNAPI(dir)->sn_index;
1490 smfs_revalidate_dotsnap_dentry(dentry, dir, index);
1491 smfs_init_snap_inode_info(inode, dir, index);
1493 dentry->d_op = &smfs_cow_dops;
1497 static int smfs_cow_readdir_post(struct inode *dir, void *de, void *data1,
1500 struct file *filp = (struct file*)de;
1502 if (smfs_primary_inode(dir)) {
1509 static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = {
1511 [HOOK_LOOKUP] smfs_cow_lookup_post,
1514 [HOOK_SYMLINK] NULL,
1519 [HOOK_SETATTR] NULL,
1521 [HOOK_READDIR] smfs_cow_readdir_post,
1524 static int smfs_cow_pre(struct inode *dir, void *dentry, void *new_dir,
1525 void *new_dentry, int op)
1527 if (smfs_cow_pre_funcs[op]) {
1528 return smfs_cow_pre_funcs[op](dir, dentry, new_dir, new_dentry);
1533 static int smfs_cow_post(struct inode *dir, void *dentry, void *new_dir,
1534 void *new_dentry, int op)
1536 if (smfs_cow_post_funcs[op]) {
1537 return smfs_cow_post_funcs[op](dir, dentry, new_dir, new_dentry);