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))
46 static int smfs_init_snap_super_info(struct smfs_super_info *smfs_info)
48 struct snap_super_info *snap_sinfo;
53 OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_super_info));
54 if (!smfs_info->smsi_snap_info)
55 GOTO(exit, rc = -ENOMEM);
57 snap_sinfo = smfs_info->smsi_snap_info;
59 /*init snap fsfilt operations*/
60 if (!snap_sinfo->snap_cache_fsfilt) {
61 char *snap_cache_ftype = NULL;
62 int tmp = strlen(smfs_info->smsi_cache_ftype) + strlen("_snap");
64 OBD_ALLOC(snap_cache_ftype, tmp + 1);
65 sprintf(snap_cache_ftype, "%s_snap", smfs_info->smsi_cache_ftype);
66 snap_sinfo->snap_cache_fsfilt = fsfilt_get_ops(snap_cache_ftype);
67 OBD_FREE(snap_cache_ftype, tmp + 1);
68 if (!snap_sinfo->snap_cache_fsfilt) {
69 CERROR("Can not get %s fsfilt ops needed by snap\n",
71 GOTO(exit, rc = -EINVAL);
74 if (!snap_sinfo->snap_fsfilt) {
75 char *snap_ftype = NULL;
76 int tmp = strlen(smfs_info->smsi_ftype) + strlen("_snap");
78 OBD_ALLOC(snap_ftype, tmp + 1);
79 sprintf(snap_ftype, "%s_snap", smfs_info->smsi_ftype);
80 snap_sinfo->snap_fsfilt = fsfilt_get_ops(snap_ftype);
81 OBD_FREE(snap_ftype, tmp + 1);
82 if (!snap_sinfo->snap_fsfilt) {
83 CERROR("Can not get %s fsfilt ops needed by snap\n",
85 GOTO(exit, rc = -EINVAL);
88 INIT_LIST_HEAD(&snap_sinfo->snap_list);
90 if (rc && smfs_info->smsi_snap_info)
91 OBD_FREE(snap_sinfo, sizeof(struct snap_super_info));
94 /*FIXME-wangdi Should remove it when integrated it with lustre*/
95 static struct dentry *smfs_simple_mkdir(struct dentry *dir, char *name,
98 struct dentry *dchild;
101 dchild = ll_lookup_one_len(name, dir, strlen(name));
103 GOTO(out_up, dchild);
105 if (dchild->d_inode) {
106 int old_mode = dchild->d_inode->i_mode;
107 if (!S_ISDIR(old_mode))
108 GOTO(out_err, err = -ENOTDIR);
110 /* Fixup directory permissions if necessary */
111 if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
112 CWARN("fixing permissions on %s from %o to %o\n",
113 name, old_mode, mode);
114 dchild->d_inode->i_mode = (mode & S_IALLUGO) |
115 (old_mode & ~S_IALLUGO);
116 mark_inode_dirty(dchild->d_inode);
118 GOTO(out_up, dchild);
120 err = vfs_mkdir(dir->d_inode, dchild, mode);
126 dchild = ERR_PTR(err);
131 static struct snap_info *smfs_find_snap_info(struct inode *inode)
133 struct snap_inode_info *snap_iinfo = I2SNAPI(inode);
134 struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
135 struct snap_info *snap_info = NULL, *tmp;
138 list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list,
140 if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino)
146 static int smfs_dotsnap_dir_size(struct inode *inode)
148 struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
149 struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt;
150 int size = 0, dir_size = 0, blocks, i = 0;
151 struct snap_table *snap_table = NULL;
152 struct snap_info *snap_info = NULL;
155 snap_info = smfs_find_snap_info(inode);
158 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
161 snap_table = snap_info->sni_table;
162 for (i = 0; i < snap_table->sntbl_count; i++) {
163 char *name = snap_table->sntbl_items[i].sn_name;
164 size += snapops->fs_dir_ent_size(name);
166 /*FIXME this is only for ext3 dir format, may need fix for other FS*/
167 blocks = (size + inode->i_sb->s_blocksize - 1) >>
168 inode->i_sb->s_blocksize_bits;
170 dir_size = blocks * inode->i_sb->s_blocksize;
175 static int smfs_init_snap_inode_info(struct inode *inode, struct inode *dir, int index)
181 I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags;
182 I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen;
183 I2SNAPI(inode)->sn_root_ino = I2SNAPI(dir)->sn_root_ino;
184 I2SNAPI(inode)->sn_index = I2SNAPI(inode)->sn_index;
186 I2SNAPI(inode)->sn_flags = 0;
187 I2SNAPI(inode)->sn_gen = 0;
190 I2SNAPI(inode)->sn_index = index;
192 if (smfs_dotsnap_inode(inode)) {
193 struct snap_info *snap_info;
195 snap_info = smfs_find_snap_info(inode);
199 /*init dot_snap inode info*/
200 inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode);
201 inode->i_nlink = snap_info->sni_table->sntbl_count + 2;
204 } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) &&
205 (I2SMI(inode)->smi_flags & SM_DO_COW) &&
206 smfs_primary_inode(inode)) {
207 struct snap_inode_info *sni_info = I2SNAPI(inode);
208 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
211 vallen = sizeof(sni_info->sn_gen);
213 rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION,
214 strlen(SNAP_GENERATION),
215 &sni_info->sn_gen, &vallen);
220 #define COWED_NAME_LEN (7 + 8 + 1)
221 static int smfs_init_cowed_dir(struct snap_info *snap_info, struct dentry* dir)
223 struct dentry *dentry = NULL;
224 char name[COWED_NAME_LEN];
228 sprintf(name, ".cowed_%08x", (__u32)dir->d_inode->i_ino);
229 /*FIXME-WANGDI: will use simple_mkdir, when integrating snap to lustre*/
230 dentry = smfs_simple_mkdir(dir, name, 0777, 1);
231 if (IS_ERR(dentry)) {
232 rc = PTR_ERR(dentry);
233 CERROR("create cowed directory: rc = %d\n", rc);
236 snap_info->sni_cowed_dentry = dentry;
240 static int smfs_init_dotinfo(struct snap_info *snap_info)
242 struct snap_dot_info *dot_info = NULL;
246 if (snap_info->sni_dot_info)
249 OBD_ALLOC(snap_info->sni_dot_info, sizeof(struct snap_dot_info));
251 if (!snap_info->sni_dot_info)
254 dot_info = snap_info->sni_dot_info;
256 OBD_ALLOC(dot_info->dot_name, strlen(DOT_SNAP_NAME) + 1);
258 if (!dot_info->dot_name) {
259 OBD_FREE(snap_info->sni_dot_info, sizeof(struct snap_dot_info));
262 memcpy(dot_info->dot_name, DOT_SNAP_NAME, strlen(DOT_SNAP_NAME));
264 dot_info->dot_name_len = strlen(DOT_SNAP_NAME);
265 dot_info->dot_snap_enable = 1;
270 static int smfs_init_snap_info(struct smfs_super_info *smb,
271 struct snap_info *snap_info, struct dentry *de)
273 struct snap_table *snap_table = NULL;
274 struct fsfilt_operations *snapcops;
275 int rc = 0, size, table_size, vallen, i;
276 struct inode *root_inode = NULL;
280 root_inode = iget(smb->smsi_sb, de->d_inode->i_ino);
281 if (!root_inode || is_bad_inode(root_inode))
283 snapcops = smb->smsi_snap_info->snap_cache_fsfilt;
284 /*Initialized table */
285 /*get the maxsize of snaptable*/
286 vallen = sizeof(int);
287 rc = snapcops->fs_get_snap_info(root_inode, MAX_SNAPTABLE_COUNT,
288 strlen(MAX_SNAPTABLE_COUNT), &size,
291 CERROR("the Max snaptable count should not be zero\n");
294 table_size = SNAPTABLE_SIZE(size);
296 OBD_ALLOC(snap_info->sni_table, table_size);
298 if (!snap_info->sni_table) {
302 snap_table = snap_info->sni_table;
304 snap_table->sntbl_magic = cpu_to_le32((__u32)SNAPTABLE_MAGIC);
305 snap_table->sntbl_max_count = size;
306 /*init sn_index to -1*/
307 for (i = 0; i < snap_table->sntbl_max_count; i++)
308 snap_table->sntbl_items[i].sn_index = -1;
309 /*get snaptable info*/
310 rc = snapcops->fs_get_snap_info(root_inode, SNAPTABLE_INFO,
311 strlen(SNAPTABLE_INFO),
312 snap_table, &table_size);
314 if (rc == -ENODATA) {
315 snap_table->sntbl_count = 0;
317 CERROR("Can not retrive the snaptable from this filesystem\n");
321 if (le32_to_cpu(snap_table->sntbl_magic) != SNAPTABLE_MAGIC) {
322 CERROR("On disk snaptable is not right \n");
323 GOTO(exit, rc = -EIO);
326 init_MUTEX(&snap_info->sni_sema);
327 snap_info->sni_root_ino = de->d_inode->i_ino;
328 rc = smfs_init_cowed_dir(snap_info, de);
330 CERROR("Init cowed dir error rc=%d\n", rc);
333 rc = smfs_init_dotinfo(snap_info);
337 if (rc && snap_table)
338 OBD_FREE(snap_table, table_size);
342 static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo,
343 struct dentry *dentry)
345 struct snap_info *snap_info = NULL;
349 OBD_ALLOC(snap_info, sizeof(struct snap_info));
351 RETURN(ERR_PTR(-ENOMEM));
352 rc = smfs_init_snap_info(sinfo, snap_info, dentry);
354 GOTO(exit, snap_info = ERR_PTR(rc));
356 /*set cow flags for the snap root inode*/
357 I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW;
358 I2SNAPI(dentry->d_inode)->sn_root_ino = dentry->d_inode->i_ino;
361 OBD_FREE(snap_info, sizeof(struct snap_info));
365 static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir,
366 void *new_dentry, int op);
368 static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir,
369 void *new_dentry, int op);
370 #define COW_HOOK "cow_hook"
371 static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry,
372 void *data1, void *data2, int op, void *handle)
377 if (smfs_do_cow(inode)) {
378 /*FIXME:WANGDI, get index from the dentry*/
381 smfs_get_dentry_name_index(dentry, &name, index);
382 smfs_free_dentry_name(&name);
384 rc = smfs_cow_pre(inode, dentry, data1, data2, op);
388 static int smfs_cow_post_hook(struct inode *inode, struct dentry *dentry,
389 void *data1, void *data2, int op, void *handle)
394 if (smfs_do_cow(inode)) {
395 rc = smfs_cow_post(inode, dentry, data1, data2, op);
400 int smfs_cow_init(struct super_block *sb)
402 struct smfs_super_info *smfs_info = S2SMI(sb);
403 struct smfs_hook_ops *cow_hops = NULL;
404 struct fsfilt_operations *sops;
405 struct inode *root_inode = smfs_info->smsi_sb->s_root->d_inode;
406 int snap_count = 0, rc = 0, vallen;
410 SMFS_SET_COW(smfs_info);
412 cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook,
418 rc = smfs_register_hook_ops(smfs_info, cow_hops);
420 smfs_free_hook_ops(cow_hops);
424 rc = smfs_init_snap_super_info(smfs_info);
425 if (rc && cow_hops) {
426 smfs_unregister_hook_ops(smfs_info, cow_hops->smh_name);
427 smfs_free_hook_ops(cow_hops);
430 sops = smfs_info->smsi_snap_info->snap_cache_fsfilt;
432 vallen = sizeof(int);
433 rc = sops->fs_get_snap_info(root_inode, SNAP_COUNT, strlen(SNAP_COUNT),
434 &snap_count, &vallen);
438 if (snap_count > 0) {
439 int snap_root_size = snap_count * sizeof(ino_t);
443 OBD_ALLOC(snap_root, snap_root_size);
446 GOTO(exit, rc = -ENOMEM);
448 rc = sops->fs_get_snap_info(root_inode, SNAP_ROOT_INO,
449 strlen(SNAP_ROOT_INO), snap_root,
452 OBD_FREE(snap_root, sizeof(int) * snap_count);
455 for (i = 0; i < snap_count; i++) {
456 ino_t root_ino = le32_to_cpu(snap_root[i]);
457 struct dentry *tmp = smfs_info->smsi_sb->s_root;
458 struct snap_info *snap_info;
459 struct dentry *dentry;
461 root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
462 smfs_init_snap_inode_info(root_inode, NULL, 0);
463 dentry = pre_smfs_dentry(NULL, root_inode, tmp);
464 snap_info = smfs_create_snap_info(S2SMI(sb), dentry);
465 post_smfs_dentry(dentry);
466 if (IS_ERR(snap_info)) {
467 OBD_FREE(snap_root, sizeof(int) * snap_count);
468 GOTO(exit, rc = PTR_ERR(snap_info));
470 list_add(&snap_info->sni_list,
471 &(S2SNAPI(sb)->snap_list));
476 smfs_cow_cleanup(smfs_info);
481 static int smfs_cleanup_dotinfo(struct snap_info *snap_info)
483 struct snap_dot_info *dot_info = NULL;
487 if (!snap_info->sni_dot_info)
490 dot_info = snap_info->sni_dot_info;
492 if (dot_info->dot_name) {
493 OBD_FREE(dot_info->dot_name, dot_info->dot_name_len + 1);
496 OBD_FREE(dot_info, sizeof(struct snap_dot_info));
501 int smfs_cleanup_snap_info(struct snap_info *snap_info)
503 struct snap_table *snap_table = snap_info->sni_table;
504 int rc = 0, table_size;
507 l_dput(snap_info->sni_cowed_dentry);
509 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
510 OBD_FREE(snap_info->sni_table, table_size);
512 smfs_cleanup_dotinfo(snap_info);
516 int smfs_cow_cleanup(struct smfs_super_info *smb)
518 struct snap_super_info *snap_sinfo = smb->smsi_snap_info;
519 struct list_head *snap_list = &snap_sinfo->snap_list;
520 struct smfs_hook_ops *cow_hops;
524 while (!list_empty(snap_list)) {
525 struct snap_info *snap_info;
527 snap_info = list_entry(snap_list->next, struct snap_info,
529 rc = smfs_cleanup_snap_info(snap_info);
531 CERROR("cleanup snap_info error rc=%d\n", rc);
532 list_del(&snap_info->sni_list);
533 OBD_FREE(snap_info, sizeof(struct snap_info));
536 if (snap_sinfo->snap_fsfilt)
537 fsfilt_put_ops(snap_sinfo->snap_fsfilt);
538 if (snap_sinfo->snap_cache_fsfilt)
539 fsfilt_put_ops(snap_sinfo->snap_cache_fsfilt);
541 cow_hops = smfs_unregister_hook_ops(smb, COW_HOOK);
542 smfs_free_hook_ops(cow_hops);
546 OBD_FREE(snap_sinfo, sizeof(struct snap_super_info));
550 int smfs_snap_test_inode(struct inode *inode, void *args)
552 struct smfs_iget_args *sargs = (struct smfs_iget_args*)args;
557 dir = sargs->s_inode;
559 if (sargs->s_index > 0) {
560 if (I2SNAPI(inode)->sn_index != sargs->s_index)
563 if (dir && I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index)
568 /* latest snap: returns
569 - the index of the latest snapshot before NOW
570 - hence it returns 0 in case all the volume snapshots lie in the future
571 - this is the index where a COW will land (will be created)
573 void snap_last(struct inode *inode, struct snap *snap)
575 time_t now = LTIME_S(CURRENT_TIME);
576 struct snap_table *snap_table;
577 struct snap_info *snap_info;
582 snap_info = smfs_find_snap_info(inode);
584 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
588 snap_table = snap_info->sni_table;
589 /* start at the highest index in the superblock snaptime array */
590 if (snap_table->sntbl_count == 0) {
591 memset(snap, 0, sizeof(struct snap));
593 i = snap_table->sntbl_count - 1;
594 snap->sn_index = snap_table->sntbl_items[i].sn_index;
595 snap->sn_time = snap_table->sntbl_items[i].sn_time;
596 snap->sn_gen = snap_table->sntbl_items[i].sn_gen;
598 CDEBUG(D_INFO, "index: %d, time[i]: %ld, now: %ld\n",
599 snap->sn_index, snap->sn_time, now);
604 static inline int get_index_of_item(struct snap_table *table, char *name)
606 int count = table->sntbl_count;
610 for (i = 0; i < table->sntbl_max_count; i++) {
611 if (!strcmp(name, table->sntbl_items[i].sn_name)) {
612 CERROR("Duplicate name %s in snaptable\n", name);
617 for (i = 0; i < table->sntbl_max_count; i++) {
619 for (j = 0; j < (count + 1); j++) {
620 if (table->sntbl_items[j].sn_index == i) {
628 CERROR("snaptable Full\n");
632 static struct dentry *smfs_find_snap_root(struct super_block *sb,
635 struct dentry *dentry = NULL;
639 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
640 if (path_init(path_name, LOOKUP_FOLLOW, &nd)) {
641 error = path_walk(path_name, &nd);
650 if (path_lookup(path_name, LOOKUP_FOLLOW, &nd))
654 dentry = dget(nd.dentry);
658 static int snap_add_item(struct smfs_super_info *smb,
659 struct snap_info *snap_info,
662 struct fsfilt_operations *snapops;
663 struct snap_table *snap_table = snap_info->sni_table;
664 struct inode *root_inode = NULL;
665 int table_size, count = 0, index = 0, rc = 0;
666 struct snap *snap_item;
669 count = snap_table->sntbl_count;
670 root_inode = iget(smb->smsi_sb, snap_info->sni_root_ino);
671 if (!root_inode || is_bad_inode(root_inode))
673 /* XXX Is down this sema necessary*/
674 down_interruptible(&snap_info->sni_sema);
675 snap_item = &snap_table->sntbl_items[count];
676 snapops = smb->smsi_snap_info->snap_cache_fsfilt;
677 /*add item in snap_table set generation*/
678 snap_item->sn_time = LTIME_S(CURRENT_TIME);
679 /* find table index */
680 index = get_index_of_item(snap_table, name);
682 GOTO(exit, rc = index);
684 snap_item->sn_index = index;
685 snap_item->sn_flags = 0;
686 snap_item->sn_gen = snap_table->sntbl_generation + 1;
687 memcpy(snap_item->sn_name, name, SNAP_MAX_NAMELEN);
688 /* Wrote the whole snap_table to disk */
689 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
691 rc = snapops->fs_set_snap_info(root_inode, SNAPTABLE_INFO,
692 strlen(SNAPTABLE_INFO),
693 snap_table, &table_size);
695 CERROR("Set snaptable error rc=%d\n", rc);
698 snap_table->sntbl_count++;
699 snap_table->sntbl_generation++;
701 up(&snap_info->sni_sema);
707 static struct snap_info * smfs_find_create_snap_info(struct super_block *sb,
708 struct dentry *dentry)
710 struct snap_super_info *snap_sinfo = S2SNAPI(sb);
711 struct snap_info *snap_info, *tmp;
714 list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list,
716 if (snap_info->sni_root_ino == dentry->d_inode->i_ino) {
721 CDEBUG(D_INFO, "create a new snap info root ino %lu\n",
722 dentry->d_inode->i_ino);
724 snap_info = smfs_create_snap_info(S2SMI(sb), dentry);
726 if (IS_ERR(snap_info))
729 list_add(&snap_info->sni_list, &snap_sinfo->snap_list);
733 int smfs_add_snap_item(struct super_block *sb, char *path_name, char *name)
735 struct dentry *dentry = NULL;
736 struct snap_info *snap_info;
740 if (!SMFS_DO_COW(S2SMI(sb))) {
744 if (!path_name || !name) {
745 CERROR("patch_name and snapshot_name is NULL");
748 dentry = smfs_find_snap_root(sb, path_name);
749 if (IS_ERR(dentry)) {
750 CERROR("can not find snap_shot root by %s\n", path_name);
751 RETURN(PTR_ERR(dentry));
753 snap_info = smfs_find_create_snap_info(sb, dentry);
754 if (IS_ERR(snap_info)) {
755 CERROR("can not find snap_info by %s rc=%lu\n", path_name,
757 GOTO(exit, rc = PTR_ERR(snap_info));
760 rc = snap_add_item(S2SMI(sb), snap_info, name);
765 //EXPORT_SYMBOL(smfs_add_snap_item);
767 * Note: this function should be differnet with snap_do_cow.
768 * In smfs_do_cow, we check the EA for whether do cow for that inode.
769 * In smfs_needs_cow, we check whether we do need to do cow.
771 int smfs_needs_cow(struct inode *inode)
773 struct smfs_inode_info *smi_info = I2SMI(inode);
774 struct snap_inode_info *snap_info = NULL;
779 snap_info = &(smi_info->sm_sninfo);
781 snap_last(inode, &snap);
782 /* decision .... if the snapshot is more recent than the object,
783 * then any change to the object should cause a COW.
785 if (snap_info->sn_gen < snap.sn_gen )
786 index = snap.sn_index;
788 CDEBUG(D_INFO, "snap_needs_cow, ino %lu , get index %d\n",
789 inode->i_ino, index);
792 } /* snap_needs_cow */
794 static int link_cowed_inode(struct inode *inode)
796 struct dentry *cowed_dir = NULL;
797 char fidname[LL_FID_NAMELEN];
798 struct snap_info *snap_info;
799 int fidlen = 0, rc = 0;
800 struct dentry *dchild = NULL;
801 struct dentry *tmp = NULL;
804 snap_info = smfs_find_snap_info(inode);
806 CERROR("can not find snap info for inode %p\n", inode);
810 cowed_dir = snap_info->sni_cowed_dentry;
812 fidlen = ll_fid2str(fidname, inode->i_ino, inode->i_generation);
814 down(&cowed_dir->d_inode->i_sem);
815 dchild = ll_lookup_one_len(fidname, cowed_dir, fidlen);
816 if (IS_ERR(dchild)) {
817 rc = PTR_ERR(dchild);
818 if (rc != -EPERM && rc != -EACCES)
819 CERROR("child lookup error %d\n", rc);
822 if (dchild->d_inode != NULL) {
823 CERROR("re-cowed file %s?\n", dchild->d_name.name);
824 LASSERT(dchild->d_inode == inode);
825 GOTO(out_dput, rc = 0);
827 tmp = pre_smfs_dentry(NULL, inode, cowed_dir);
828 /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG
829 * for linking and return real mode back then -bzzz */
830 mode = inode->i_mode;
831 inode->i_mode = S_IFREG;
832 rc = vfs_link(tmp, cowed_dir->d_inode, dchild);
833 post_smfs_dentry(tmp);
835 CERROR("error linking cowed inode %s to COWED: rc = %d\n",
838 inode->i_mode = mode;
839 if ((mode & S_IFMT) == S_IFDIR) {
840 dchild->d_inode->i_nlink++;
841 cowed_dir->d_inode->i_nlink++;
843 mark_inode_dirty(dchild->d_inode);
847 up(&cowed_dir->d_inode->i_sem);
851 * Make a copy of the data and plug a redirector in between if there
852 * is no redirector yet.
854 int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
856 struct fsfilt_operations *snapops = I2SNAPCOPS(inode);
858 struct inode *cache_ind = NULL;
861 if (!snapops || !snapops->fs_create_indirect)
864 snap_last(inode, &snap);
865 cache_ind = snapops->fs_create_indirect(I2CI(inode), snap.sn_index,
866 snap.sn_gen, I2CI(dparent->d_inode),
868 if(cache_ind && IS_ERR(cache_ind)) {
869 CERROR("Create ind inode %lu index %d gen %d del %d rc%lu\n",
870 inode->i_ino, snap.sn_index, snap.sn_gen, del,
872 RETURN(PTR_ERR(cache_ind));
875 if (!SMFS_DO_INODE_COWED(inode)) {
876 /*insert the inode to cowed inode*/
877 SMFS_SET_INODE_COWED(inode);
878 link_cowed_inode(inode);
882 /*Dir inode will do cow*/
883 int smfs_cow_create(struct inode *dir, struct dentry *dentry,
884 void *data1, void *data2)
887 struct dentry *dparent;
890 if (smfs_needs_cow(dir) != -1) {
891 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
892 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
893 dparent = dentry->d_parent->d_parent;
894 if ((rc = snap_do_cow(dir, dparent, 0))) {
895 CERROR("Do cow error %d\n", rc);
902 int smfs_cow_setattr(struct inode *dir, struct dentry *dentry,
903 void *data1, void *data2)
907 if (smfs_needs_cow(dir) != -1) {
908 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
909 if ((snap_do_cow(dir, dentry->d_parent, 0))) {
910 CERROR("Do cow error\n");
917 int smfs_cow_link(struct inode *dir, struct dentry *dentry,
918 void *data1, void *data2)
921 struct dentry *dparent;
924 if (smfs_needs_cow(dir) != -1) {
925 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
926 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
927 dparent = dentry->d_parent->d_parent;
928 if ((snap_do_cow(dir, dparent, 0))) {
929 CERROR("Do cow error\n");
932 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
933 CERROR("Do cow error\n");
940 int smfs_cow_unlink(struct inode *dir, struct dentry *dentry,
941 void *data1, void *data2)
943 struct dentry *dparent;
947 if (smfs_needs_cow(dir) != -1) {
948 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
949 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
950 dparent = dentry->d_parent->d_parent;
951 if ((snap_do_cow(dir, dparent, 0))) {
952 CERROR("Do cow error\n");
955 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 1))) {
956 CERROR("Do cow error\n");
964 int smfs_cow_rename(struct inode *dir, struct dentry *dentry,
965 void *data1, void *data2)
967 struct inode *new_dir = (struct inode *)data1;
968 struct dentry *new_dentry = (struct dentry *)data2;
969 struct dentry *dparent;
975 if (smfs_needs_cow(dir) != -1) {
976 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", dir->i_ino);
977 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
978 dparent = dentry->d_parent->d_parent;
979 if ((snap_do_cow(dir, dparent, 0))) {
980 CERROR("Do cow error\n");
983 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
984 CERROR("Do cow error\n");
988 if (smfs_needs_cow(new_dir) != -1) {
989 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", new_dir->i_ino);
990 LASSERT(new_dentry->d_parent && new_dentry->d_parent->d_parent);
991 dparent = new_dentry->d_parent->d_parent;
992 if ((new_dir != dir) && (snap_do_cow(new_dir, dparent, 0))){
993 CERROR("Do cow error\n");
996 if (new_dentry->d_inode && new_dentry->d_inode->i_nlink == 1) {
997 if ((snap_do_cow(new_dentry->d_inode,
998 new_dentry->d_parent, 0))) {
999 CERROR("Do cow error\n");
1007 int smfs_cow_write(struct inode *inode, struct dentry *dentry, void *data1,
1010 struct snap_info *snap_info = NULL;
1011 struct snap_table *table;
1012 long blocks[2]={-1,-1};
1013 int index = 0, i, rc = 0;
1019 snap_info = smfs_find_snap_info(inode);
1021 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1024 table = snap_info->sni_table;
1029 count = *(size_t *)data1;
1030 pos = *(loff_t*)data2;
1032 down(&inode->i_sem);
1034 if (smfs_needs_cow(inode) != -1 ) {
1035 CDEBUG(D_INFO, "snap_needs_cow for ino %lu \n",inode->i_ino);
1036 snap_do_cow(inode, dentry->d_parent, 0);
1039 CDEBUG(D_INFO, "write offset %lld count %u \n", pos, count);
1041 if(pos & (PAGE_CACHE_SIZE - 1)){
1042 blocks[0] = pos >> inode->i_sb->s_blocksize_bits;
1045 if((pos + 1) & (PAGE_CACHE_SIZE - 1)){
1046 blocks[1] = pos >> inode->i_sb->s_blocksize_bits;
1049 if (blocks[0] == blocks[1])
1052 for (i = 0; i < 2; i++) {
1054 if (blocks[i] == -1)
1056 /*Find the nearest page in snaptable and copy back it*/
1057 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
1058 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1059 struct inode *cind = NULL;
1062 index = table->sntbl_items[slot].sn_index;
1063 cind = sops->fs_get_indirect(I2CI(inode), NULL, index);
1064 if (!cind) continue;
1066 CDEBUG(D_INFO, "find cache_ino %lu\n", cind->i_ino);
1068 result = sops->fs_copy_block(I2CI(inode), cind,
1078 GOTO(exit, rc = result);
1087 EXPORT_SYMBOL(smfs_cow_write);
1088 /*lookup inode in dotsnap inode */
1089 static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry,
1090 struct snap_info *snap_info)
1092 if (dentry->d_name.len == 1 &&
1093 !strcmp(dentry->d_name.name, ".")) {
1094 d_add(dentry, iget(dir->i_sb, dir->i_ino));
1095 } else if (dentry->d_name.len == 2 &&
1096 !strcmp(dentry->d_name.name, "..")) {
1097 struct inode *inode;
1098 struct dentry *dparent = dentry->d_parent;
1099 if (dparent->d_inode) {
1100 inode = iget(dir->i_sb, dparent->d_inode->i_ino);
1102 if (!is_bad_inode(inode))
1103 d_add(dentry, inode);
1109 /*find the name from the snaptable*/
1110 struct fsfilt_operations *sops = I2SNAPCOPS(dir);
1111 struct snap_table *table;
1112 struct inode *inode;
1114 int i = 0, index = -1;
1116 table = snap_info->sni_table;
1118 for (i = 0; i < table->sntbl_count; i++) {
1119 char *name = table->sntbl_items[i].sn_name;
1120 if ((dentry->d_name.len == strlen(name)) &&
1121 (memcmp(dentry->d_name.name, name,
1122 dentry->d_name.len) == 0)) {
1123 index = table->sntbl_items[i].sn_index;
1128 CERROR("No such %s in this .snap dir \n",
1129 dentry->d_name.name);
1132 cino = sops->fs_get_indirect_ino(S2CSB(dir->i_sb), dir->i_ino,
1134 inode = smfs_get_inode(dir->i_sb, cino, dir, index);
1135 if (!inode || is_bad_inode(inode)) {
1136 CERROR("Can not find cino %lu inode\n", cino);
1139 smfs_init_snap_inode_info(inode, dir, index);
1140 d_add(dentry, inode);
1144 int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1,
1147 struct snap_info *snap_info;
1148 struct snap_dot_info *dot_info;
1149 int rc = 0, index = 0;
1152 snap_info = smfs_find_snap_info(inode);
1154 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1158 dot_info = snap_info->sni_dot_info;
1160 LASSERT(dot_info != NULL);
1161 LASSERT(data1 != NULL);
1163 index = *(int *)data1;
1165 if (smfs_primary_inode(inode) &&
1166 dentry->d_name.len == dot_info->dot_name_len &&
1167 memcmp(dentry->d_name.name, dot_info->dot_name,
1168 strlen(dot_info->dot_name)) == 0) {
1169 struct inode *dot_inode = NULL;
1171 dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode,
1173 smfs_init_snap_inode_info(dot_inode, inode, DOT_SNAP_INDEX);
1174 d_add(dentry, dot_inode);
1178 if (smfs_dotsnap_inode(inode)) {
1179 rc = smfs_dotsnap_lookup(inode, dentry, snap_info);
1185 /*HERE: will replace ino in dentry->d_name according to index*/
1186 struct fsfilt_operations *snapops = I2SNAPOPS(inode);
1187 char *name = (char *)dentry->d_name.name;
1188 unsigned long ino, hash, ind_ino;
1189 int len = sizeof(ind_ino);
1191 ino = simple_strtoul(name, 0, 0);
1193 ind_ino = snapops->fs_get_indirect_ino(inode->i_sb, ino, index);
1195 snprintf(name, strlen(name), "0x%lx", ind_ino);
1197 hash = init_name_hash();
1200 c = *(const unsigned char *)name++;
1201 if (c == '\0') break;
1202 hash = partial_name_hash(c, hash);
1204 dentry->d_name.hash = end_name_hash(hash);
1209 struct inode *smfs_cow_get_ind(struct inode *inode, int index)
1211 long block=(index << PAGE_CACHE_SHIFT) >> inode->i_sb->s_blocksize_bits;
1212 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1213 struct snap_info *snap_info = NULL;
1214 struct snap_table *table = NULL;
1219 snap_info = smfs_find_snap_info(inode);
1221 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1225 table = snap_info->sni_table;
1227 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
1228 struct address_space_operations *aops = inode->i_mapping->a_ops;
1229 struct inode *cache_inode = NULL;
1232 index = table->sntbl_items[slot].sn_index;
1233 cache_inode = sops->fs_get_indirect(I2CI(inode), NULL, index);
1235 if (!cache_inode ) continue;
1237 if (aops->bmap(cache_inode->i_mapping, block))
1238 RETURN(cache_inode);
1244 EXPORT_SYMBOL(smfs_cow_get_ind);
1246 typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry,
1247 void *new_dir, void *new_dentry);
1249 static cow_funcs smfs_cow_pre_funcs[HOOK_MAX + 1] = {
1250 [HOOK_CREATE] smfs_cow_create,
1251 [HOOK_LOOKUP] smfs_cow_lookup,
1252 [HOOK_LINK] smfs_cow_link,
1253 [HOOK_UNLINK] smfs_cow_unlink,
1254 [HOOK_SYMLINK] smfs_cow_create,
1255 [HOOK_MKDIR] smfs_cow_create,
1256 [HOOK_RMDIR] smfs_cow_unlink,
1257 [HOOK_MKNOD] smfs_cow_create,
1258 [HOOK_RENAME] smfs_cow_rename,
1259 [HOOK_SETATTR] smfs_cow_setattr,
1260 [HOOK_WRITE] smfs_cow_write,
1262 int smfs_cow_lookup_post(struct inode *dir, struct dentry *dentry, void *data1,
1265 struct inode *inode = dentry->d_inode;
1266 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1267 int index = I2SNAPI(dir)->sn_index;
1273 struct inode *cache_ind = NULL;
1275 cache_ind = sops->fs_get_indirect(I2CI(inode), NULL, index);
1276 if (cache_ind->i_ino != I2CI(inode)->i_ino) {
1277 struct inode *ind_inode = NULL;
1279 ind_inode = smfs_get_inode(dir->i_sb, cache_ind->i_ino,
1281 /*replace the ind_inode here*/
1282 list_del_init(&dentry->d_alias);
1284 d_instantiate(dentry, ind_inode);
1287 inode = dentry->d_inode;
1289 smfs_init_snap_inode_info(inode, dir, index);
1294 static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = {
1296 [HOOK_LOOKUP] smfs_cow_lookup_post,
1299 [HOOK_SYMLINK] NULL,
1304 [HOOK_SETATTR] NULL,
1308 static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir,
1309 void *new_dentry, int op)
1311 if (smfs_cow_pre_funcs[op]) {
1312 return smfs_cow_pre_funcs[op](dir, dentry, new_dir, new_dentry);
1317 static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir,
1318 void *new_dentry, int op)
1320 if (smfs_cow_post_funcs[op]) {
1321 return smfs_cow_post_funcs[op](dir, dentry, new_dir, new_dentry);