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/string.h>
28 #include <linux/slab.h>
29 #include <linux/stat.h>
30 #include <linux/unistd.h>
31 #include <linux/smp_lock.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_support.h>
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_idl.h>
36 #include <linux/lustre_fsfilt.h>
38 #include <linux/lustre_snap.h>
39 #include <linux/lustre_smfs.h>
41 #include "smfs_internal.h"
42 #define SNAPTABLE_SIZE(size) (sizeof(struct snap_table) + size * sizeof(struct snap))
43 static int smfs_init_snaptabe(struct super_block *sb)
45 struct snap_info *snap_info = S2SNAPI(sb);
46 struct fsfilt_operations *snapops;
47 int rc = 0, size, table_size, vallen;
51 init_MUTEX(&snap_info->sntbl_sema);
52 /*Initialized table */
53 /*get the maxsize of snaptable*/
55 rc = snapops->fs_get_snap_info(sb, NULL, MAX_SNAPTABLE_COUNT,
56 strlen(MAX_SNAPTABLE_COUNT), &size,
59 CERROR("the Max snaptable count should not be zero\n");
63 table_size = SNAPTABLE_SIZE(size);
65 OBD_ALLOC(snap_info->sntbl, table_size);
67 if (!snap_info->sntbl) {
71 /*get snaptable info*/
72 rc = snapops->fs_get_snap_info(sb, NULL, SNAPTABLE_INFO,
73 strlen(SNAPTABLE_INFO),
74 snap_info->sntbl, &table_size);
78 snap_info->sntbl->sntbl_count = 1;
79 CDEBUG(D_INFO, "No snaptable here\n");
82 CERROR("Can not retrive the snaptable from this filesystem\n");
83 OBD_FREE(snap_info->sntbl, table_size);
87 if (le32_to_cpu(snap_info->sntbl->sntbl_magic) != SNAP_TABLE_MAGIC) {
88 CERROR("On disk snaptable is not right \n");
89 OBD_FREE(snap_info->sntbl, table_size);
92 snap_info->sntbl->sntbl_max_count = size;
97 int smfs_cow_init(struct super_block *sb)
99 struct smfs_super_info *smfs_info = S2SMI(sb);
100 struct inode *inode = sb->s_root->d_inode;
103 SMFS_SET_COW(smfs_info);
104 SMFS_SET_INODE_COW(inode);
106 OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
108 if (!smfs_info->smsi_snap_info)
111 /*init snap fsfilt operations*/
112 if (!S2SNAPI(sb)->snap_cache_fsfilt) {
113 char *snap_cache_ftype = NULL;
114 int tmp = strlen(S2SMI(sb)->smsi_cache_ftype) + strlen("_snap");
116 OBD_ALLOC(snap_cache_ftype, tmp + 1);
117 sprintf(snap_cache_ftype, "%s_snap", S2SMI(sb)->smsi_cache_ftype);
118 S2SNAPI(sb)->snap_cache_fsfilt = fsfilt_get_ops(snap_cache_ftype);
119 OBD_FREE(snap_cache_ftype, tmp + 1);
120 if (!S2SNAPI(sb)->snap_cache_fsfilt) {
121 CERROR("Can not get %s fsfilt ops needed by snap\n",
126 if (!S2SNAPI(sb)->snap_fsfilt) {
127 char *snap_ftype = NULL;
128 int tmp = strlen(S2SMI(sb)->smsi_ftype) + strlen("_snap");
130 OBD_ALLOC(snap_ftype, tmp + 1);
131 sprintf(snap_ftype, "%s_snap", S2SMI(sb)->smsi_ftype);
132 S2SNAPI(sb)->snap_fsfilt = fsfilt_get_ops(snap_ftype);
133 OBD_FREE(snap_ftype, tmp + 1);
134 if (!S2SNAPI(sb)->snap_fsfilt) {
135 CERROR("Can not get %s fsfilt ops needed by snap\n",
140 rc = smfs_init_snaptabe(sb);
145 int smfs_cow_cleanup(struct super_block *sb)
147 struct smfs_super_info *smfs_info = S2SMI(sb);
148 struct snap_info *snap_info = S2SNAPI(sb);
149 struct inode *inode = sb->s_root->d_inode;
153 SMFS_CLEAN_COW(smfs_info);
154 SMFS_CLEAN_INODE_COW(inode);
156 if (snap_info->sntbl) {
157 int table_size = SNAPTABLE_SIZE(snap_info->sntbl->sntbl_max_count);
158 OBD_FREE(snap_info->sntbl, table_size);
161 OBD_FREE(snap_info, sizeof(*snap_info));
166 /* latest snap: returns
167 - the index of the latest snapshot before NOW
168 - hence it returns 0 in case all the volume snapshots lie in the future
169 - this is the index where a COW will land (will be created)
171 void snap_last(struct super_block *sb, struct snap *snap)
173 struct snap_info *snap_info = S2SNAPI(sb);
174 struct snap_table *table = snap_info->sntbl;
175 time_t now = CURRENT_TIME;
179 /* start at the highest index in the superblock snaptime array */
180 i = table->sntbl_count - 1;
182 snap->sn_index = table->sntbl_items[i].sn_index;
183 snap->sn_time = table->sntbl_items[i].sn_time;
184 snap->sn_gen = table->sntbl_items[i].sn_gen;
185 CDEBUG(D_INFO, "index: %d, time[i]: %ld, now: %ld\n",
186 snap->sn_index, snap->sn_time, now);
192 * Note: this function should be differnet with snap_do_cow.
193 * In smfs_do_cow, we check the EA for whether do cow for that inode.
194 * In smfs_needs_cow, we check whether we do need to do cow.
196 int smfs_needs_cow(struct inode *inode)
198 struct smfs_inode_info *smi_info = I2SMI(inode);
199 struct snap_inode_info *snap_info = NULL;
204 snap_info = &(smi_info->sm_sninfo);
206 snap_last(inode->i_sb, &snap);
207 /* decision .... if the snapshot is more recent than the object,
208 * then any change to the object should cause a COW.
210 if (snap_info->sn_gen < snap.sn_gen )
211 index = snap.sn_index;
213 CDEBUG(D_INFO, "snap_needs_cow, ino %lu , get index %d\n",
214 inode->i_ino, index);
217 } /* snap_needs_cow */
220 * Make a copy of the data and plug a redirector in between if there
221 * is no redirector yet.
223 int snap_do_cow(struct inode *inode, struct dentry *dparent, int del)
225 struct snap_info *snap_info = S2SNAPI(inode->i_sb);
226 struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
228 struct inode *ind = NULL;
232 if (!snapops || !snapops->fs_create_indirect)
235 snap_last(inode->i_sb, &snap);
236 ind = snapops->fs_create_indirect(inode, snap.sn_index, snap.sn_gen,
237 dparent->d_inode, del);
241 I2SMI(ind)->sm_sninfo.sn_flags = 0;
242 I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen;
248 int smfs_cow_create(struct inode *dir, struct dentry *dentry)
253 if (smfs_needs_cow(dir) != -1) {
254 CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
255 if ((smfs_cow(dir, dentry->d_parent, 0))) {
256 CERROR("Do cow error\n");
263 int smfs_cow_setattr(struct inode *dir, struct dentry *dentry)
271 int smfs_cow_link(struct inode *dir, struct dentry *dentry)
279 int smfs_cow_unlink(struct inode *dir, struct dentry *dentry)
287 int smfs_cow_rename(struct inode *dir, struct dentry *dentry)
295 int smfs_cow_write(struct inode *dir, struct dentry *dentry)
303 typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry);
305 static cow_funcs smfs_cow_funcs[REINT_MAX + 1] = {
306 [REINT_SETATTR] smfs_cow_setattr,
307 [REINT_CREATE] smfs_cow_create,
308 [REINT_LINK] smfs_cow_link,
309 [REINT_UNLINK] smfs_cow_unlink,
310 [REINT_RENAME] smfs_cow_rename,
311 [REINT_WRITE] smfs_cow_write,
314 int smfs_cow(struct inode *dir, struct dentry *dentry, int op)
316 return smfs_cow_funcs[op](dir, dentry);