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 sprintf(snap_cache_ftype, "%s_snap", smfs_info->smsi_cache_ftype);
71 snap_sinfo->snap_cache_fsfilt = fsfilt_get_ops(snap_cache_ftype);
72 OBD_FREE(snap_cache_ftype, tmp + 1);
73 if (!snap_sinfo->snap_cache_fsfilt) {
74 CERROR("Can not get %s fsfilt ops needed by snap\n",
76 GOTO(exit, rc = -EINVAL);
79 if (!snap_sinfo->snap_fsfilt) {
80 char *snap_ftype = NULL;
81 int tmp = strlen(smfs_info->smsi_ftype) + strlen("_snap");
83 OBD_ALLOC(snap_ftype, tmp + 1);
84 sprintf(snap_ftype, "%s_snap", smfs_info->smsi_ftype);
85 snap_sinfo->snap_fsfilt = fsfilt_get_ops(snap_ftype);
86 OBD_FREE(snap_ftype, tmp + 1);
87 if (!snap_sinfo->snap_fsfilt) {
88 CERROR("Can not get %s fsfilt ops needed by snap\n",
90 GOTO(exit, rc = -EINVAL);
93 INIT_LIST_HEAD(&snap_sinfo->snap_list);
95 if (rc && smfs_info->smsi_snap_info)
96 OBD_FREE(snap_sinfo, sizeof(struct snap_super_info));
99 /*FIXME-wangdi Should remove it when integrated it with lustre*/
100 static struct dentry *smfs_simple_mkdir(struct dentry *dir, char *name,
103 struct dentry *dchild;
106 dchild = ll_lookup_one_len(name, dir, strlen(name));
108 GOTO(out_up, dchild);
110 if (dchild->d_inode) {
111 int old_mode = dchild->d_inode->i_mode;
112 if (!S_ISDIR(old_mode))
113 GOTO(out_err, err = -ENOTDIR);
115 /* Fixup directory permissions if necessary */
116 if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
117 CWARN("fixing permissions on %s from %o to %o\n",
118 name, old_mode, mode);
119 dchild->d_inode->i_mode = (mode & S_IALLUGO) |
120 (old_mode & ~S_IALLUGO);
121 mark_inode_dirty(dchild->d_inode);
123 GOTO(out_up, dchild);
125 err = vfs_mkdir(dir->d_inode, dchild, mode);
131 dchild = ERR_PTR(err);
136 static struct snap_info *smfs_find_snap_info(struct inode *inode)
138 struct snap_inode_info *snap_iinfo = I2SNAPI(inode);
139 struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
140 struct snap_info *snap_info = NULL, *tmp;
143 list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list,
145 if (snap_info->sni_root_ino == snap_iinfo->sn_root_ino)
152 static int smfs_dotsnap_dir_size(struct inode *inode)
154 struct snap_super_info *snap_sinfo = S2SNAPI(inode->i_sb);
155 struct fsfilt_operations *snapops = snap_sinfo->snap_cache_fsfilt;
156 int size = 0, dir_size = 0, blocks, i = 0;
157 struct snap_table *snap_table = NULL;
158 struct snap_info *snap_info = NULL;
161 snap_info = smfs_find_snap_info(inode);
164 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
167 snap_table = snap_info->sni_table;
168 for (i = 0; i < snap_table->sntbl_count; i++) {
169 char *name = snap_table->sntbl_items[i].sn_name;
170 size += snapops->fs_dir_ent_size(name);
172 /*FIXME this is only for ext3 dir format, may need fix for other FS*/
173 blocks = (size + inode->i_sb->s_blocksize - 1) >>
174 inode->i_sb->s_blocksize_bits;
176 dir_size = blocks * inode->i_sb->s_blocksize;
182 static int smfs_init_snap_inode_info(struct inode *inode, struct inode *dir, int index)
191 I2SNAPI(inode)->sn_flags = I2SNAPI(dir)->sn_flags;
192 I2SNAPI(inode)->sn_gen = I2SNAPI(dir)->sn_gen;
193 I2SNAPI(inode)->sn_root_ino = I2SNAPI(dir)->sn_root_ino;
194 I2SNAPI(inode)->sn_index = I2SNAPI(inode)->sn_index;
196 I2SNAPI(inode)->sn_flags = 0;
197 I2SNAPI(inode)->sn_gen = 0;
200 I2SNAPI(inode)->sn_index = index;
202 if (smfs_dotsnap_inode(inode)) {
203 struct snap_info *snap_info;
205 snap_info = smfs_find_snap_info(inode);
209 /*init dot_snap inode info*/
210 // inode->i_size = (loff_t)smfs_dotsnap_dir_size(inode);
211 inode->i_size = snap_info->sni_table->sntbl_count;
212 inode->i_nlink = snap_info->sni_table->sntbl_count + 2;
215 } else if (SMFS_DO_COW(S2SMI(inode->i_sb)) &&
216 (I2SMI(inode)->smi_flags & SM_DO_COW) &&
217 smfs_primary_inode(inode)) {
218 struct snap_inode_info *sni_info = I2SNAPI(inode);
219 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
222 vallen = sizeof(sni_info->sn_gen);
224 rc = sops->fs_get_snap_info(I2CI(inode), SNAP_GENERATION,
225 strlen(SNAP_GENERATION),
226 &sni_info->sn_gen, &vallen);
231 #define COWED_NAME_LEN (7 + 8 + 1)
232 static int smfs_init_cowed_dir(struct snap_info *snap_info, struct inode* inode)
234 struct dentry *dentry = NULL;
235 char name[COWED_NAME_LEN];
239 sprintf(name, ".cowed_%08x", (__u32)inode->i_ino);
240 /*FIXME-WANGDI: will use simple_mkdir, when integrating snap to lustre*/
241 dentry = smfs_simple_mkdir(inode->i_sb->s_root, name, 0777, 1);
242 if (IS_ERR(dentry)) {
243 rc = PTR_ERR(dentry);
244 CERROR("create cowed directory: rc = %d\n", rc);
247 snap_info->sni_cowed_dentry = dentry;
248 /*cleanup cowed inode attr for cowed dir*/
249 SMFS_CLEAN_INODE_COWED(dentry->d_inode);
253 static int smfs_init_dotinfo(struct snap_info *snap_info)
255 struct snap_dot_info *dot_info = NULL;
259 if (snap_info->sni_dot_info)
262 OBD_ALLOC(snap_info->sni_dot_info, sizeof(struct snap_dot_info));
264 if (!snap_info->sni_dot_info)
267 dot_info = snap_info->sni_dot_info;
269 OBD_ALLOC(dot_info->dot_name, strlen(DOT_SNAP_NAME) + 1);
271 if (!dot_info->dot_name) {
272 OBD_FREE(snap_info->sni_dot_info, sizeof(struct snap_dot_info));
275 memcpy(dot_info->dot_name, DOT_SNAP_NAME, strlen(DOT_SNAP_NAME));
277 dot_info->dot_name_len = strlen(DOT_SNAP_NAME);
278 dot_info->dot_snap_enable = 1;
283 static int smfs_init_snap_info(struct smfs_super_info *smb,
284 struct snap_info *snap_info, struct inode *inode)
286 struct snap_table *snap_table = NULL;
287 struct fsfilt_operations *snapcops;
288 int rc = 0, size, table_size, vallen, i;
292 snapcops = smb->smsi_snap_info->snap_cache_fsfilt;
293 /*Initialized table */
294 /*get the maxsize of snaptable*/
295 vallen = sizeof(int);
296 rc = snapcops->fs_get_snap_info(I2CI(inode), MAX_SNAPTABLE_COUNT,
297 strlen(MAX_SNAPTABLE_COUNT), &size,
300 CERROR("the Max snaptable count should not be zero\n");
303 table_size = SNAPTABLE_SIZE(size);
305 OBD_ALLOC(snap_info->sni_table, table_size);
307 if (!snap_info->sni_table) {
311 snap_table = snap_info->sni_table;
313 snap_table->sntbl_magic = cpu_to_le32((__u32)SNAPTABLE_MAGIC);
314 snap_table->sntbl_max_count = size;
315 /*init sn_index to -1*/
316 for (i = 0; i < snap_table->sntbl_max_count; i++)
317 snap_table->sntbl_items[i].sn_index = -1;
318 /*get snaptable info*/
319 rc = snapcops->fs_get_snap_info(I2CI(inode), SNAPTABLE_INFO,
320 strlen(SNAPTABLE_INFO),
321 snap_table, &table_size);
323 if (rc == -ENODATA) {
324 snap_table->sntbl_count = 0;
327 CERROR("Can not retrive the snaptable from this filesystem\n");
331 if (le32_to_cpu(snap_table->sntbl_magic) != SNAPTABLE_MAGIC) {
332 CERROR("On disk snaptable is not right \n");
333 GOTO(exit, rc = -EIO);
336 init_MUTEX(&snap_info->sni_sema);
337 snap_info->sni_root_ino = inode->i_ino;
338 rc = smfs_init_cowed_dir(snap_info, inode);
340 CERROR("Init cowed dir error rc=%d\n", rc);
343 rc = smfs_init_dotinfo(snap_info);
345 if (rc && snap_table)
346 OBD_FREE(snap_table, table_size);
350 static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo,
353 struct snap_info *snap_info = NULL;
357 OBD_ALLOC(snap_info, sizeof(struct snap_info));
359 RETURN(ERR_PTR(-ENOMEM));
360 rc = smfs_init_snap_info(sinfo, snap_info, inode);
364 /*set cow flags for the snap root inode*/
365 I2SMI(inode)->smi_flags |= SM_DO_COW;
366 I2SNAPI(inode)->sn_root_ino = inode->i_ino;
369 OBD_FREE(snap_info, sizeof(struct snap_info));
370 snap_info = ERR_PTR(rc);
375 static int smfs_cow_pre(struct inode *dir, void *dentry, void *new_dir,
376 void *new_dentry, int op);
378 static int smfs_cow_post(struct inode *dir, void *dentry, void *new_dir,
379 void *new_dentry, int op);
380 #define COW_HOOK "cow_hook"
381 static int smfs_cow_pre_hook(struct inode *inode, void *dentry, void *data1,
382 void *data2, int op, void *handle)
387 if (smfs_do_cow(inode)) {
388 /*FIXME:WANGDI, get index from the dentry*/
391 smfs_get_dentry_name_index(dentry, &name, index);
392 smfs_free_dentry_name(&name);
394 rc = smfs_cow_pre(inode, dentry, data1, data2, op);
398 static int smfs_cow_post_hook(struct inode *inode, void *dentry, void *data1,
399 void *data2, int op, void *handle)
404 if (smfs_do_cow(inode)) {
405 rc = smfs_cow_post(inode, dentry, data1, data2, op);
410 int smfs_cow_cleanup(struct smfs_super_info *smb)
412 struct snap_super_info *snap_sinfo = smb->smsi_snap_info;
413 struct list_head *snap_list = &snap_sinfo->snap_list;
414 struct smfs_hook_ops *cow_hops;
418 while (!list_empty(snap_list)) {
419 struct snap_info *snap_info;
421 snap_info = list_entry(snap_list->next, struct snap_info,
423 rc = smfs_cleanup_snap_info(snap_info);
425 CERROR("cleanup snap_info error rc=%d\n", rc);
426 list_del(&snap_info->sni_list);
427 OBD_FREE(snap_info, sizeof(struct snap_info));
430 if (snap_sinfo->snap_fsfilt)
431 fsfilt_put_ops(snap_sinfo->snap_fsfilt);
432 if (snap_sinfo->snap_cache_fsfilt)
433 fsfilt_put_ops(snap_sinfo->snap_cache_fsfilt);
435 cow_hops = smfs_unregister_hook_ops(smb, COW_HOOK);
436 smfs_free_hook_ops(cow_hops);
440 OBD_FREE(snap_sinfo, sizeof(struct snap_super_info));
444 int smfs_cow_init(struct super_block *sb)
446 struct smfs_super_info *smfs_info = S2SMI(sb);
447 struct smfs_hook_ops *cow_hops = NULL;
448 struct fsfilt_operations *sops;
449 struct inode *root_inode = smfs_info->smsi_sb->s_root->d_inode;
450 int snap_count = 0, rc = 0, vallen;
454 SMFS_SET_COW(smfs_info);
456 cow_hops = smfs_alloc_hook_ops(COW_HOOK, smfs_cow_pre_hook,
462 rc = smfs_register_hook_ops(smfs_info, cow_hops);
464 smfs_free_hook_ops(cow_hops);
468 rc = smfs_init_snap_super_info(smfs_info);
469 if (rc && cow_hops) {
470 smfs_unregister_hook_ops(smfs_info, cow_hops->smh_name);
471 smfs_free_hook_ops(cow_hops);
474 sops = smfs_info->smsi_snap_info->snap_cache_fsfilt;
476 vallen = sizeof(int);
477 rc = sops->fs_get_snap_info(root_inode, SNAP_COUNT, strlen(SNAP_COUNT),
478 &snap_count, &vallen);
482 if (snap_count > 0) {
483 int snap_root_size = snap_count * sizeof(ino_t);
487 OBD_ALLOC(snap_root, snap_root_size);
490 GOTO(exit, rc = -ENOMEM);
492 rc = sops->fs_get_snap_info(root_inode, SNAP_ROOT_INO,
493 strlen(SNAP_ROOT_INO), snap_root,
496 OBD_FREE(snap_root, sizeof(int) * snap_count);
499 for (i = 0; i < snap_count; i++) {
500 ino_t root_ino = le32_to_cpu(snap_root[i]);
501 struct snap_info *snap_info;
503 root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
504 smfs_init_snap_inode_info(root_inode, NULL, 0);
505 snap_info = smfs_create_snap_info(S2SMI(sb), root_inode);
507 if (IS_ERR(snap_info)) {
508 OBD_FREE(snap_root, sizeof(int) * snap_count);
509 GOTO(exit, rc = PTR_ERR(snap_info));
511 list_add(&snap_info->sni_list,
512 &(S2SNAPI(sb)->snap_list));
515 smfs_info->smsi_snap_info->snap_count = snap_count;
518 smfs_cow_cleanup(smfs_info);
522 static int smfs_cleanup_dotinfo(struct snap_info *snap_info)
524 struct snap_dot_info *dot_info = NULL;
528 if (!snap_info->sni_dot_info)
531 dot_info = snap_info->sni_dot_info;
533 if (dot_info->dot_name) {
534 OBD_FREE(dot_info->dot_name, dot_info->dot_name_len + 1);
537 OBD_FREE(dot_info, sizeof(struct snap_dot_info));
542 int smfs_cleanup_snap_info(struct snap_info *snap_info)
544 struct snap_table *snap_table = snap_info->sni_table;
545 int rc = 0, table_size;
548 l_dput(snap_info->sni_cowed_dentry);
549 //d_unalloc(snap_info->sni_cowed_dentry);
551 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
552 OBD_FREE(snap_info->sni_table, table_size);
554 smfs_cleanup_dotinfo(snap_info);
558 int smfs_snap_test_inode(struct inode *inode, void *args)
560 struct smfs_iget_args *sargs = (struct smfs_iget_args*)args;
565 dir = sargs->s_inode;
567 if (sargs->s_index > 0) {
568 if (I2SNAPI(inode)->sn_index != sargs->s_index)
571 if (dir && I2SNAPI(inode)->sn_index != I2SNAPI(dir)->sn_index)
576 /* latest snap: returns
577 - the index of the latest snapshot before NOW
578 - hence it returns 0 in case all the volume snapshots lie in the future
579 - this is the index where a COW will land (will be created)
581 void snap_last(struct inode *inode, struct snap *snap)
583 time_t now = LTIME_S(CURRENT_TIME);
584 struct snap_table *snap_table;
585 struct snap_info *snap_info;
590 snap_info = smfs_find_snap_info(inode);
592 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
596 snap_table = snap_info->sni_table;
597 /* start at the highest index in the superblock snaptime array */
598 if (snap_table->sntbl_count == 0) {
599 memset(snap, 0, sizeof(struct snap));
601 i = snap_table->sntbl_count - 1;
602 snap->sn_index = snap_table->sntbl_items[i].sn_index;
603 snap->sn_time = snap_table->sntbl_items[i].sn_time;
604 snap->sn_gen = snap_table->sntbl_items[i].sn_gen;
606 CDEBUG(D_INFO, "index: %d, time[i]: %ld, now: %ld\n",
607 snap->sn_index, snap->sn_time, now);
612 static inline int get_index_of_item(struct snap_table *table, char *name)
614 int count = table->sntbl_count;
618 for (i = 0; i < table->sntbl_max_count; i++) {
619 if (!strcmp(name, table->sntbl_items[i].sn_name)) {
620 CERROR("Duplicate name %s in snaptable\n", name);
625 for (i = 1; i <= table->sntbl_max_count; i++) {
627 for (j = 0; j < (count + 1); j++) {
628 if (table->sntbl_items[j].sn_index == i) {
636 CERROR("snaptable Full\n");
640 static struct dentry *smfs_find_snap_root(struct super_block *sb,
643 struct dentry *dentry = NULL;
647 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
648 if (path_init(path_name, LOOKUP_FOLLOW, &nd)) {
649 int error = path_walk(path_name, &nd);
658 if (path_lookup(path_name, LOOKUP_FOLLOW, &nd))
661 dentry = dget(nd.dentry);
666 static int snap_add_item(struct smfs_super_info *smb,
667 struct snap_info *snap_info,
670 struct fsfilt_operations *snapops;
671 struct snap_table *snap_table = snap_info->sni_table;
672 struct inode *root_inode = NULL;
673 int table_size, count = 0, index = 0, rc = 0;
674 struct snap *snap_item;
677 count = snap_table->sntbl_count;
678 root_inode = iget(smb->smsi_sb, snap_info->sni_root_ino);
679 if (!root_inode || is_bad_inode(root_inode))
681 /* XXX Is down this sema necessary*/
682 down_interruptible(&snap_info->sni_sema);
683 snap_item = &snap_table->sntbl_items[count];
684 snapops = smb->smsi_snap_info->snap_cache_fsfilt;
685 /*add item in snap_table set generation*/
686 snap_item->sn_time = LTIME_S(CURRENT_TIME);
687 /* find table index */
688 index = get_index_of_item(snap_table, name);
690 GOTO(exit, rc = index);
692 snap_item->sn_index = index;
693 snap_item->sn_flags = 0;
694 snap_item->sn_gen = snap_table->sntbl_generation + 1;
695 memcpy(snap_item->sn_name, name, SNAP_MAX_NAMELEN);
696 /* Wrote the whole snap_table to disk */
697 table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
699 snap_table->sntbl_count++;
700 snap_table->sntbl_generation++;
701 rc = snapops->fs_set_snap_info(root_inode, SNAPTABLE_INFO,
702 strlen(SNAPTABLE_INFO),
703 snap_table, &table_size);
705 snap_table->sntbl_count--;
706 snap_table->sntbl_generation--;
707 CERROR("Set snaptable error rc=%d\n", rc);
711 up(&snap_info->sni_sema);
717 static struct snap_info * smfs_find_create_snap_info(struct super_block *sb,
720 struct snap_super_info *snap_sinfo = S2SNAPI(sb);
721 struct fsfilt_operations *sops = snap_sinfo->snap_cache_fsfilt;
722 struct snap_info *snap_info, *tmp;
723 ino_t *snap_root = NULL;
724 int rino_size, snap_count_size, rc = 0;
727 list_for_each_entry_safe(snap_info, tmp, &snap_sinfo->snap_list,
729 if (snap_info->sni_root_ino == inode->i_ino) {
734 CDEBUG(D_INFO, "create a new snap info root ino %lu\n", inode->i_ino);
736 snap_info = smfs_create_snap_info(S2SMI(sb), inode);
738 if (IS_ERR(snap_info))
741 snap_sinfo->snap_count++;
743 rino_size = snap_sinfo->snap_count * sizeof(ino_t);
745 OBD_ALLOC(snap_root, rino_size);
748 GOTO(exit, rc = -ENOMEM);
750 rc = sops->fs_get_snap_info(I2CI(inode), SNAP_ROOT_INO,
751 strlen(SNAP_ROOT_INO), snap_root,
754 if (rc == -ENODATA) {
760 snap_root[snap_sinfo->snap_count - 1] = inode->i_ino;
762 snap_count_size = sizeof(int);
763 rc = sops->fs_set_snap_info(I2CI(inode), SNAP_COUNT, strlen(SNAP_COUNT),
764 &snap_sinfo->snap_count, &snap_count_size);
768 rc = sops->fs_set_snap_info(I2CI(inode), SNAP_ROOT_INO,
769 strlen(SNAP_ROOT_INO), snap_root,
775 list_add(&snap_info->sni_list, &snap_sinfo->snap_list);
778 smfs_cleanup_snap_info(snap_info);
779 OBD_FREE(snap_info, sizeof(struct snap_info));
782 OBD_FREE(snap_root, rino_size);
786 int smfs_add_snap_item(struct super_block *sb, char *path_name, char *name)
788 struct dentry *dentry = NULL;
789 struct snap_info *snap_info;
793 if (!SMFS_DO_COW(S2SMI(sb))) {
797 if (!path_name || !name) {
798 CERROR("patch_name and snapshot_name is NULL");
801 dentry = smfs_find_snap_root(sb, path_name);
802 if (IS_ERR(dentry)) {
803 CERROR("can not find snap_shot root by %s\n", path_name);
804 RETURN(PTR_ERR(dentry));
806 snap_info = smfs_find_create_snap_info(sb, dentry->d_inode);
807 if (IS_ERR(snap_info)) {
808 CERROR("can not find snap_info by %s rc=%lu\n", path_name,
810 GOTO(exit, rc = PTR_ERR(snap_info));
813 rc = snap_add_item(S2SMI(sb), snap_info, name);
818 //EXPORT_SYMBOL(smfs_add_snap_item);
820 * Note: this function should be differnet with snap_do_cow.
821 * In smfs_do_cow, we check the EA for whether do cow for that inode.
822 * In smfs_needs_cow, we check whether we do need to do cow.
824 int smfs_needs_cow(struct inode *inode)
826 struct smfs_inode_info *smi_info = I2SMI(inode);
827 struct snap_inode_info *snap_info = NULL;
832 snap_info = &(smi_info->sm_sninfo);
834 snap_last(inode, &snap);
835 /* decision .... if the snapshot is more recent than the object,
836 * then any change to the object should cause a COW.
838 if (snap_info->sn_gen < snap.sn_gen )
839 index = snap.sn_index;
841 CDEBUG(D_INFO, "snap_needs_cow, ino %lu , get index %d\n",
842 inode->i_ino, index);
845 } /* snap_needs_cow */
847 static int link_cowed_inode(struct inode *inode)
849 struct dentry *cowed_dir = NULL;
850 char idname[LL_ID_NAMELEN];
851 struct snap_info *snap_info;
852 int idlen = 0, rc = 0;
853 struct dentry *dchild = NULL;
854 struct dentry *tmp = NULL;
857 snap_info = smfs_find_snap_info(inode);
859 CERROR("can not find snap info for inode %p\n", inode);
863 cowed_dir = snap_info->sni_cowed_dentry;
865 down(&cowed_dir->d_inode->i_sem);
867 idlen = ll_id2str(idname, inode->i_ino, inode->i_generation);
868 dchild = lookup_one_len(idname, cowed_dir, idlen);
869 if (IS_ERR(dchild)) {
870 rc = PTR_ERR(dchild);
871 if (rc != -EPERM && rc != -EACCES)
872 CERROR("child lookup error %d\n", rc);
875 if (dchild->d_inode != NULL) {
876 CERROR("re-cowed file %s?\n", dchild->d_name.name);
877 LASSERT(dchild->d_inode == inode);
878 GOTO(out_dput, rc = 0);
880 tmp = pre_smfs_dentry(NULL, inode, cowed_dir);
881 /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG
882 * for linking and return real mode back then -bzzz */
883 mode = inode->i_mode;
884 inode->i_mode = S_IFREG;
886 rc = cowed_dir->d_inode->i_op->link(tmp, cowed_dir->d_inode, dchild);
888 post_smfs_dentry(tmp);
890 CERROR("error linking cowed inode %s to COWED: rc = %d\n",
893 inode->i_mode = mode;
894 if ((mode & S_IFMT) == S_IFDIR) {
895 dchild->d_inode->i_nlink++;
896 cowed_dir->d_inode->i_nlink++;
897 mark_inode_dirty(cowed_dir->d_inode);
898 mark_inode_dirty(dchild->d_inode);
901 up(&cowed_dir->d_inode->i_sem);
907 * Make a copy of the data and plug a redirector in between if there
908 * is no redirector yet.
910 int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
912 struct fsfilt_operations *snapops = I2SNAPCOPS(inode);
914 struct inode *cache_ind = NULL;
917 if (!snapops || !snapops->fs_create_indirect)
920 snap_last(inode, &snap);
921 cache_ind = snapops->fs_create_indirect(I2CI(inode), snap.sn_index,
922 snap.sn_gen, I2CI(dparent->d_inode),
924 if(cache_ind && IS_ERR(cache_ind)) {
925 CERROR("Create ind inode %lu index %d gen %d del %d rc%lu\n",
926 inode->i_ino, snap.sn_index, snap.sn_gen, del,
928 RETURN(PTR_ERR(cache_ind));
932 if (!SMFS_DO_INODE_COWED(inode)) {
933 /*insert the inode to cowed inode*/
934 SMFS_SET_INODE_COWED(inode);
935 link_cowed_inode(inode);
940 /*Dir inode will do cow*/
941 int smfs_cow_create_pre(struct inode *dir, void *de, void *data1, void *data2)
943 struct dentry *dparent;
944 struct dentry *dentry = (struct dentry *)de;
948 if (smfs_needs_cow(dir) != -1) {
949 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
950 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
951 dparent = dentry->d_parent->d_parent;
952 if ((rc = snap_do_cow(dir, dparent, 0))) {
953 CERROR("Do cow error %d\n", rc);
960 int smfs_cow_setattr_pre(struct inode *dir, void *de, void *data1, void *data2)
962 struct dentry *dentry = (struct dentry *)de;
965 if (smfs_needs_cow(dir) != -1) {
966 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
967 if ((snap_do_cow(dir, dentry->d_parent, 0))) {
968 CERROR("Do cow error\n");
975 int smfs_cow_link_pre(struct inode *dir, void *de, void *data1, void *data2)
977 struct dentry *dparent;
978 struct dentry *dentry = (struct dentry *)de;
982 if (smfs_needs_cow(dir) != -1) {
983 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
984 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
985 dparent = dentry->d_parent->d_parent;
986 if ((snap_do_cow(dir, dparent, 0))) {
987 CERROR("Do cow error\n");
990 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
991 CERROR("Do cow error\n");
998 int smfs_cow_unlink_pre(struct inode *dir, void *de, void *data1, void *data2)
1000 struct dentry *dentry = (struct dentry *)de;
1001 struct dentry *dparent;
1005 if (smfs_needs_cow(dir) != -1) {
1006 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
1007 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
1008 dparent = dentry->d_parent->d_parent;
1009 if ((snap_do_cow(dir, dparent, 0))) {
1010 CERROR("Do cow error\n");
1013 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 1))) {
1014 CERROR("Do cow error\n");
1022 int smfs_cow_rename_pre(struct inode *dir, void *de, void *data1, void *data2)
1024 struct dentry *dentry = (struct dentry*)de;
1025 struct inode *new_dir = (struct inode *)data1;
1026 struct dentry *new_dentry = (struct dentry *)data2;
1027 struct dentry *dparent;
1032 LASSERT(new_dentry);
1033 if (smfs_needs_cow(dir) != -1) {
1034 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", dir->i_ino);
1035 LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
1036 dparent = dentry->d_parent->d_parent;
1037 if ((snap_do_cow(dir, dparent, 0))) {
1038 CERROR("Do cow error\n");
1041 if ((snap_do_cow(dentry->d_inode, dentry->d_parent, 0))) {
1042 CERROR("Do cow error\n");
1046 if (smfs_needs_cow(new_dir) != -1) {
1047 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n", new_dir->i_ino);
1048 LASSERT(new_dentry->d_parent && new_dentry->d_parent->d_parent);
1049 dparent = new_dentry->d_parent->d_parent;
1050 if ((new_dir != dir) && (snap_do_cow(new_dir, dparent, 0))){
1051 CERROR("Do cow error\n");
1054 if (new_dentry->d_inode && new_dentry->d_inode->i_nlink == 1) {
1055 if ((snap_do_cow(new_dentry->d_inode,
1056 new_dentry->d_parent, 0))) {
1057 CERROR("Do cow error\n");
1065 int smfs_cow_write_pre(struct inode *inode, void *de, void *data1, void *data2)
1067 struct dentry *dentry = (struct dentry*)de;
1068 struct snap_info *snap_info = NULL;
1069 struct snap_table *table;
1070 long blocks[2]={-1,-1};
1071 int index = 0, i, rc = 0;
1077 snap_info = smfs_find_snap_info(inode);
1079 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1082 table = snap_info->sni_table;
1087 count = *(size_t *)data1;
1088 pos = *(loff_t*)data2;
1090 down(&inode->i_sem);
1092 if (smfs_needs_cow(inode) != -1 ) {
1093 CDEBUG(D_INFO, "snap_needs_cow for ino %lu \n",inode->i_ino);
1094 snap_do_cow(inode, dentry->d_parent, 0);
1097 CDEBUG(D_INFO, "write offset %lld count %u \n", pos, count);
1099 if(pos & (PAGE_CACHE_SIZE - 1)){
1100 blocks[0] = pos >> inode->i_sb->s_blocksize_bits;
1103 if((pos + 1) & (PAGE_CACHE_SIZE - 1)){
1104 blocks[1] = pos >> inode->i_sb->s_blocksize_bits;
1107 if (blocks[0] == blocks[1])
1110 for (i = 0; i < 2; i++) {
1112 if (blocks[i] == -1)
1114 /*Find the nearest page in snaptable and copy back it*/
1115 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
1116 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1117 struct inode *cind = NULL;
1120 index = table->sntbl_items[slot].sn_index;
1121 cind = sops->fs_get_indirect(I2CI(inode), NULL, index);
1122 if (!cind) continue;
1124 CDEBUG(D_INFO, "find cache_ino %lu\n", cind->i_ino);
1126 result = sops->fs_copy_block(I2CI(inode), cind,
1136 GOTO(exit, rc = result);
1145 EXPORT_SYMBOL(smfs_cow_write_pre);
1146 /*lookup inode in dotsnap inode */
1147 static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry,
1148 struct snap_info *snap_info)
1150 if (dentry->d_name.len == 1 &&
1151 !strcmp(dentry->d_name.name, ".")) {
1152 d_add(dentry, iget(dir->i_sb, dir->i_ino));
1153 } else if (dentry->d_name.len == 2 &&
1154 !strcmp(dentry->d_name.name, "..")) {
1155 struct inode *inode;
1156 struct dentry *dparent = dentry->d_parent;
1157 if (dparent->d_inode) {
1158 inode = iget(dir->i_sb, dparent->d_inode->i_ino);
1160 if (!is_bad_inode(inode))
1161 d_add(dentry, inode);
1167 /*find the name from the snaptable*/
1168 struct fsfilt_operations *sops = I2SNAPCOPS(dir);
1169 struct snap_table *table;
1170 struct inode *inode;
1172 int i = 0, index = -1;
1174 table = snap_info->sni_table;
1176 for (i = 0; i < table->sntbl_count; i++) {
1177 char *name = table->sntbl_items[i].sn_name;
1178 if ((dentry->d_name.len == strlen(name)) &&
1179 (memcmp(dentry->d_name.name, name,
1180 dentry->d_name.len) == 0)) {
1181 index = table->sntbl_items[i].sn_index;
1186 CERROR("No such %s in this .snap dir \n",
1187 dentry->d_name.name);
1190 cino = sops->fs_get_indirect_ino(S2CSB(dir->i_sb), dir->i_ino,
1194 inode = smfs_get_inode(dir->i_sb, cino, dir, index);
1195 if (!inode || is_bad_inode(inode)) {
1196 CERROR("Can not find cino %lu inode\n", cino);
1199 smfs_init_snap_inode_info(inode, dir, index);
1200 d_add(dentry, inode);
1204 int smfs_cow_lookup_pre(struct inode *inode, void *de, void *data1,
1207 struct dentry *dentry = (struct dentry*)de;
1208 struct snap_info *snap_info;
1209 struct snap_dot_info *dot_info;
1213 snap_info = smfs_find_snap_info(inode);
1215 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1219 dot_info = snap_info->sni_dot_info;
1221 if (smfs_primary_inode(inode) &&
1222 dentry->d_name.len == dot_info->dot_name_len &&
1223 memcmp(dentry->d_name.name, dot_info->dot_name,
1224 strlen(dot_info->dot_name)) == 0) {
1225 struct inode *dot_inode = NULL;
1227 dot_inode = smfs_get_inode(inode->i_sb, inode->i_ino, inode,
1229 smfs_init_snap_inode_info(dot_inode, inode, DOT_SNAP_INDEX);
1230 d_add(dentry, dot_inode);
1233 } else if (smfs_dotsnap_inode(inode)) {
1234 rc = smfs_dotsnap_lookup(inode, dentry, snap_info);
1239 /*HERE: will replace ino in dentry->d_name according to index,
1240 *For iopen, will fix it in integrating snapfs to Lustre*/
1242 struct fsfilt_operations *snapops = I2SNAPOPS(inode);
1243 char *name = (char *)dentry->d_name.name;
1244 unsigned long ino, hash, ind_ino;
1245 int len = sizeof(ind_ino);
1247 ino = simple_strtoul(name, 0, 0);
1249 ind_ino = snapops->fs_get_indirect_ino(inode->i_sb, ino, index);
1251 snprintf(name, strlen(name), "0x%lx", ind_ino);
1253 hash = init_name_hash();
1256 c = *(const unsigned char *)name++;
1257 if (c == '\0') break;
1258 hash = partial_name_hash(c, hash);
1260 dentry->d_name.hash = end_name_hash(hash);
1266 struct inode *smfs_cow_get_ind(struct inode *inode, int index)
1268 long block=(index << PAGE_CACHE_SHIFT) >> inode->i_sb->s_blocksize_bits;
1269 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1270 struct snap_info *snap_info = NULL;
1271 struct snap_table *table = NULL;
1276 snap_info = smfs_find_snap_info(inode);
1278 CDEBUG(D_INFO, "can not find snap info for inode %p\n", inode);
1282 table = snap_info->sni_table;
1284 for (slot = table->sntbl_count - 1; slot >= 0; slot--) {
1285 struct address_space_operations *aops = inode->i_mapping->a_ops;
1286 struct inode *cache_inode = NULL;
1289 index = table->sntbl_items[slot].sn_index;
1290 cache_inode = sops->fs_get_indirect(I2CI(inode), NULL, index);
1292 if (!cache_inode ) continue;
1294 if (aops->bmap(cache_inode->i_mapping, block))
1295 RETURN(cache_inode);
1301 EXPORT_SYMBOL(smfs_cow_get_ind);
1303 static int smfs_cow_readdir_pre(struct inode *dir, void *de, void *data1,
1306 struct file *filp = (struct file*)de;
1307 void *dirent = data1;
1308 filldir_t filldir = (filldir_t)data2;
1309 struct snap_info *snap_info = NULL;
1311 if (smfs_under_dotsnap_inode(dir))
1314 snap_info = smfs_find_snap_info(dir);
1317 CDEBUG(D_INFO, "can not find snap info for ino %lu\n",
1322 if (smfs_primary_inode(dir)) {
1323 if (filp->f_pos == 0) {
1324 struct snap_dot_info *dot = snap_info->sni_dot_info;
1325 if (filldir(dirent, dot->dot_name, dot->dot_name_len,
1326 filp->f_pos, -1, 0)) {
1327 CERROR("fill .snap error \n");
1333 } else if (smfs_dotsnap_inode(dir)) {
1334 struct snap_table *table = snap_info->sni_table;
1337 if (filp->f_pos < 0)
1340 if ((filp->f_pos == 0) && filldir(dirent, ".", 1,
1344 if ((filp->f_pos == 1) && filldir(dirent, "..", 2,
1349 for (i = filp->f_pos - 2; i < table->sntbl_count; i++,
1351 int slot = table->sntbl_count - i - 1;
1353 if (filldir(dirent, table->sntbl_items[slot].sn_name,
1354 strlen(table->sntbl_items[slot].sn_name),
1355 filp->f_pos, dir->i_ino, 0))
1366 typedef int (*cow_funcs)(struct inode *dir, void *dentry, void *new_dir,
1369 static cow_funcs smfs_cow_pre_funcs[HOOK_MAX + 1] = {
1370 [HOOK_CREATE] smfs_cow_create_pre,
1371 [HOOK_LOOKUP] smfs_cow_lookup_pre,
1372 [HOOK_LINK] smfs_cow_link_pre,
1373 [HOOK_UNLINK] smfs_cow_unlink_pre,
1374 [HOOK_SYMLINK] smfs_cow_create_pre,
1375 [HOOK_MKDIR] smfs_cow_create_pre,
1376 [HOOK_RMDIR] smfs_cow_unlink_pre,
1377 [HOOK_MKNOD] smfs_cow_create_pre,
1378 [HOOK_RENAME] smfs_cow_rename_pre,
1379 [HOOK_SETATTR] smfs_cow_setattr_pre,
1380 [HOOK_WRITE] smfs_cow_write_pre,
1381 [HOOK_READDIR] smfs_cow_readdir_pre,
1384 static int smfs_revalidate_dotsnap_dentry(struct dentry *dentry,
1385 struct inode *dir, int index)
1387 struct inode *inode = dentry->d_inode;
1393 if (index > 0 && index != DOT_SNAP_INDEX) {
1394 struct fsfilt_operations *sops = I2SNAPCOPS(inode);
1395 struct inode *cache_ind = NULL;
1397 cache_ind = sops->fs_get_indirect(I2CI(inode), NULL, index);
1400 struct inode *ind_inode = NULL;
1402 LASSERT(cache_ind->i_ino != I2CI(inode)->i_ino);
1404 ind_inode = smfs_get_inode(inode->i_sb, cache_ind->i_ino,
1406 list_del_init(&dentry->d_alias);
1408 d_instantiate(dentry, ind_inode);
1415 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1417 smfs_revalidate_nd(struct dentry *de, struct nameidata *nd)
1419 struct inode *inode = de->d_inode;
1425 if (smfs_under_dotsnap_inode(inode)) {
1426 struct inode *dir = de->d_parent->d_inode;
1427 int index = I2SNAPI(inode)->sn_index;
1429 smfs_revalidate_dotsnap_dentry(de, dir, index);
1430 smfs_init_snap_inode_info(de->d_inode, dir, index);
1437 smfs_revalidate_it(struct dentry *de, int flags,
1438 struct nameidata *nd,
1439 struct lookup_intent *it)
1441 struct inode *inode = de->d_inode;
1447 if (smfs_under_dotsnap_inode(inode)) {
1448 struct inode *dir = de->d_parent->d_inode;
1449 int index = I2SNAPI(inode)->sn_index;
1451 smfs_revalidate_dotsnap_dentry(de, dir, index);
1452 smfs_init_snap_inode_info(de->d_inode, dir, index);
1459 static int smfs_delete_dentry(struct dentry *dentry)
1461 dentry->d_op = NULL;
1465 struct dentry_operations smfs_cow_dops = {
1466 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1467 .d_revalidate = smfs_revalidate_nd,
1469 .d_revalidate_it = smfs_revalidate_it,
1471 .d_delete = smfs_delete_dentry,
1474 int smfs_cow_lookup_post(struct inode *dir, void *de, void *data1,
1477 struct dentry *dentry = (struct dentry*)de;
1478 struct inode *inode = dentry->d_inode;
1481 if (inode && smfs_under_dotsnap_inode(inode)) {
1482 int index = I2SNAPI(dir)->sn_index;
1484 smfs_revalidate_dotsnap_dentry(dentry, dir, index);
1485 smfs_init_snap_inode_info(inode, dir, index);
1487 dentry->d_op = &smfs_cow_dops;
1491 static int smfs_cow_readdir_post(struct inode *dir, void *de, void *data1,
1494 struct file *filp = (struct file*)de;
1496 if (smfs_primary_inode(dir)) {
1503 static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = {
1505 [HOOK_LOOKUP] smfs_cow_lookup_post,
1508 [HOOK_SYMLINK] NULL,
1513 [HOOK_SETATTR] NULL,
1515 [HOOK_READDIR] smfs_cow_readdir_post,
1518 static int smfs_cow_pre(struct inode *dir, void *dentry, void *new_dir,
1519 void *new_dentry, int op)
1521 if (smfs_cow_pre_funcs[op]) {
1522 return smfs_cow_pre_funcs[op](dir, dentry, new_dir, new_dentry);
1527 static int smfs_cow_post(struct inode *dir, void *dentry, void *new_dir,
1528 void *new_dentry, int op)
1530 if (smfs_cow_post_funcs[op]) {
1531 return smfs_cow_post_funcs[op](dir, dentry, new_dir, new_dentry);