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/kmod.h>
26 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <linux/obd_class.h>
30 #include <linux/obd_support.h>
31 #include <linux/lustre_lib.h>
32 #include <linux/lustre_idl.h>
33 #include <linux/lustre_fsfilt.h>
34 #include <linux/lustre_smfs.h>
35 #include "smfs_internal.h"
37 /*FIXME there should be more conditions in this check*/
38 int smfs_do_rec(struct inode *inode)
40 struct super_block *sb = inode->i_sb;
41 struct smfs_super_info *smfs_info = S2SMI(sb);
43 if (SMFS_DO_REC(smfs_info) && SMFS_INIT_REC(smfs_info) &&
44 SMFS_DO_INODE_REC(inode))
49 int smfs_rec_init(struct super_block *sb)
51 struct smfs_super_info *smfs_info = S2SMI(sb);
54 SMFS_SET_REC(smfs_info);
59 int smfs_rec_cleanup(struct super_block *sb)
63 SMFS_CLEAN_REC(S2SMI(sb));
67 void reint_rec_free(struct reint_record *reint_rec)
70 if (reint_rec->rec_data1)
71 OBD_FREE(reint_rec->rec_data1,
72 reint_rec->rec1_size + 1);
73 if (reint_rec->rec_data2)
74 OBD_FREE(reint_rec->rec_data2,
75 reint_rec->rec2_size + 1);
77 OBD_FREE(reint_rec, sizeof(struct reint_record));
81 static inline void copy_inode_attr(struct iattr *iattr, struct inode *inode)
83 iattr->ia_mode = inode->i_mode;
84 iattr->ia_uid = inode->i_uid;
85 iattr->ia_gid = inode->i_gid;
86 iattr->ia_atime = inode->i_atime;
87 iattr->ia_ctime = inode->i_ctime;
88 iattr->ia_mtime = inode->i_mtime;
89 iattr->ia_size = inode->i_size;
92 void smfs_rec_pack(struct update_record *rec, struct inode *dst,
95 rec->ur_fsuid = current->fsuid;
96 rec->ur_fsgid = current->fsgid;
97 rec->ur_rdev = dst->i_rdev;
99 copy_inode_attr(&rec->ur_iattr, dst);
106 struct inode *dir = (struct inode *)data;
107 copy_inode_attr(&rec->ur_pattr, dir);
110 case REINT_SETATTR: {
111 struct iattr *attr = (struct iattr *)data;
112 memcpy(&rec->ur_pattr, attr, sizeof(struct iattr));
119 static inline void unpack_attr(struct reint_record *r_rec,
120 struct update_record *u_rec)
122 memcpy(&r_rec->u_rec, u_rec, sizeof(struct update_record));
125 static inline int unpack_rec_data(char **p_buffer, int *size,
126 char *in_data, char *args_data)
133 args_len = strlen(args_data);
135 *size = *((int*)(in_data));
136 rc = *size + sizeof(int);
138 OBD_ALLOC(*p_buffer, *size + args_len + 1);
141 /*First copy reint dir */
143 memcpy(*p_buffer, args_data, args_len);
145 /*then copy the node name */
146 memcpy(*p_buffer + args_len,
147 (in_data + sizeof(int)), *size);
154 int smfs_rec_unpack(struct smfs_proc_args *args, struct reint_record *r_rec,
157 struct update_record *u_rec = (struct update_record *)rec_buf;
158 int rc = 0, length = 0;
160 /*FIXME wangdi, there unpack are so smiliar that
161 *we will put it together later*/
163 if (SMFS_DO_WRITE_KML(args->sr_flags))
164 SET_REC_WRITE_KML_FLAGS(r_rec->u_rec.ur_flags, SMFS_WRITE_KML);
165 unpack_attr(r_rec, u_rec);
166 length += sizeof(struct update_record);
167 rc = unpack_rec_data(&r_rec->rec_data1, &r_rec->rec1_size,
168 (rec_buf + length), args->sr_data);
169 switch (u_rec->ur_opcode) {
172 /*record src path which will be passed to reint and undo*/
173 rc = unpack_rec_data(&r_rec->rec_data2, &r_rec->rec2_size,
174 (rec_buf + length), NULL);
183 if (length < u_rec->ur_len) {
185 if (u_rec->ur_opcode == REINT_CREATE ||
186 u_rec->ur_opcode == REINT_WRITE ||
187 (u_rec->ur_opcode == REINT_UNLINK &&
188 SMFS_DO_DEC_LINK(r_rec->u_rec.ur_flags)))
191 pre_name = args->sr_data;
193 rc = unpack_rec_data(&r_rec->rec_data2,
195 (rec_buf + length), pre_name);
206 int smfs_start_rec(struct super_block *sb)
208 struct dentry *dentry;
209 struct lvfs_run_ctxt saved;
213 if (SMFS_INIT_REC(S2SMI(sb)) ||
214 (!SMFS_DO_REC(S2SMI(sb)) && !SMFS_CACHE_HOOK(S2SMI(sb))))
217 rc = smfs_llog_setup(sb);
221 push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
222 dentry = simple_mkdir(current->fs->pwd, "DELETE", 0777, 1);
223 if (IS_ERR(dentry)) {
224 rc = PTR_ERR(dentry);
225 CERROR("cannot create LOGS directory: rc = %d\n", rc);
226 GOTO(err_exit, rc = -EINVAL);
228 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
229 if (list_empty(&dentry->d_hash))
232 /* FIXME-WANGDI: here should be be something. */
236 SMFS_SET_INIT_REC(S2SMI(sb));
237 S2SMI(sb)->smsi_delete_dir = dentry;
239 pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
242 if (S2SMI(sb)->smsi_ctxt)
243 OBD_FREE(S2SMI(sb)->smsi_ctxt, sizeof(struct lvfs_run_ctxt));
247 int smfs_stop_rec(struct super_block *sb)
252 if (!SMFS_INIT_REC(S2SMI(sb)) ||
253 (!SMFS_DO_REC(S2SMI(sb)) && !SMFS_CACHE_HOOK(S2SMI(sb))))
256 rc = smfs_llog_cleanup(sb);
258 SMFS_CLEAN_INIT_REC(S2SMI(sb));
260 if (S2SMI(sb)->smsi_delete_dir) {
261 l_dput(S2SMI(sb)->smsi_delete_dir);
262 S2SMI(sb)->smsi_delete_dir = NULL;
267 int smfs_process_rec(struct super_block *sb, int count, char *dir, int flags)
269 struct llog_ctxt *ctxt;
270 struct llog_handle *loghandle;
271 struct smfs_proc_args args;
275 if (!SMFS_INIT_REC(S2SMI(sb))) {
276 CWARN("Did not start up rec server \n");
280 memset(&args, 0, sizeof(struct smfs_proc_args));
282 args.sr_count = count;
284 args.sr_flags = flags ;
285 ctxt = S2SMI(sb)->smsi_rec_log;
286 loghandle = ctxt->loc_handle;
289 if (SMFS_DO_REINT_REC(flags)) {
290 struct llog_gen_rec *lgr;
292 /*For reint rec, we need insert
293 *a gen rec to identify the end
295 OBD_ALLOC(lgr, sizeof(*lgr));
298 lgr->lgr_hdr.lrh_len = lgr->lgr_tail.lrt_len =
300 lgr->lgr_hdr.lrh_type = LLOG_GEN_REC;
301 lgr->lgr_gen = ctxt->loc_gen;
302 rc = llog_add(ctxt, &lgr->lgr_hdr, NULL, NULL, 1, NULL);
303 OBD_FREE(lgr, sizeof(*lgr));
308 SET_REC_COUNT_FLAGS(args.sr_flags, SMFS_REC_ALL);
311 if (SMFS_DO_REINT_REC(flags))
312 rc = llog_cat_process(loghandle, ctxt->loc_proc_cb,
315 rc = llog_cat_reverse_process(loghandle,
318 if (rc == LLOG_PROC_BREAK)