1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre filesystem abstraction routines
7 * Copyright (C) 2004 Cluster File Systems, Inc.
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 # define EXPORT_SYMTAB
28 #define DEBUG_SUBSYSTEM S_SM
30 #include <linux/kmod.h>
31 #include <linux/init.h>
33 #include <linux/slab.h>
34 #include <linux/obd_class.h>
35 #include <linux/obd_support.h>
36 #include <linux/lustre_lib.h>
37 #include <linux/lustre_idl.h>
38 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
40 #include "smfs_internal.h"
43 #define KML_BUF_REC_INIT(buffer, pbuf, len) \
45 pbuf = buffer + sizeof(int); \
49 #define KML_BUF_REC_END(buffer, length, pbuf) \
52 memcpy(buffer, &len, sizeof(len)); \
53 length += sizeof(int); \
54 pbuf = buffer + length; \
57 static int smfs_llog_process_rec_cb(struct llog_handle *handle,
58 struct llog_rec_hdr *rec, void *data)
61 struct smfs_proc_args *args = (struct smfs_proc_args *)data;
62 struct lvfs_run_ctxt saved;
65 if (!(le32_to_cpu(handle->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)) {
66 CERROR("log is not plain\n");
70 if (le32_to_cpu(rec->lrh_type) == LLOG_GEN_REC) {
71 struct llog_cookie cookie;
73 cookie.lgc_lgl = handle->lgh_id;
74 cookie.lgc_index = le32_to_cpu(rec->lrh_index);
76 llog_cancel(handle->lgh_ctxt, 1, &cookie, 0, NULL);
77 RETURN(LLOG_PROC_BREAK);
80 if (le32_to_cpu(rec->lrh_type) != SMFS_UPDATE_REC)
83 rec_buf = (char*) (rec + 1);
85 if (!S2SMI(args->sr_sb)->smsi_ctxt)
86 GOTO(exit, rc = -ENODEV);
88 push_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
90 /*FIXME later should first unpack the rec,
91 * then call lvfs_reint or lvfs_undo
92 * kml rec format has changed lvfs_reint lvfs_undo should
93 * be rewrite FIXME later*/
94 if (SMFS_DO_REINT_REC(args->sr_flags))
95 rc = lvfs_reint(args->sr_sb, rec_buf);
97 rc = lvfs_undo(args->sr_sb, rec_buf);
99 if (!rc && !SMFS_DO_REC_ALL(args->sr_flags)) {
101 if (args->sr_count == 0)
102 rc = LLOG_PROC_BREAK;
104 pop_ctxt(&saved, S2SMI(args->sr_sb)->smsi_ctxt, NULL);
109 /* not used curently */
110 static smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb)
113 struct smfs_super_info *smsi = S2SMI(sb);
115 idx = GET_REC_PACK_TYPE_INDEX(smsi->smsi_flags);
116 return smsi->smsi_pack_rec[idx];
121 copy_inode_attr(struct iattr *iattr, struct inode *inode)
123 iattr->ia_mode = inode->i_mode;
124 iattr->ia_uid = inode->i_uid;
125 iattr->ia_gid = inode->i_gid;
126 iattr->ia_atime = inode->i_atime;
127 iattr->ia_ctime = inode->i_ctime;
128 iattr->ia_mtime = inode->i_mtime;
129 iattr->ia_size = inode->i_size;
133 static inline int unpack_rec_data(char **p_buffer, int *size,
134 char *in_data, char *args_data)
141 args_len = strlen(args_data);
143 *size = *((int*)(in_data));
144 rc = *size + sizeof(int);
146 OBD_ALLOC(*p_buffer, *size + args_len + 1);
150 /* first copy reint dir. */
152 memcpy(*p_buffer, args_data, args_len);
154 /* then copy the node name. */
155 memcpy(*p_buffer + args_len,
156 (in_data + sizeof(int)), *size);
164 int smfs_rec_unpack(struct smfs_proc_args *args, char *record,
165 char **pbuf, int *opcode)
167 //int offset = *(int *)(record);
168 //char *tmp = record + offset + sizeof(int);
170 *opcode = *(int *)record;
171 *pbuf = record + sizeof(*opcode);
174 EXPORT_SYMBOL(smfs_rec_unpack); /* cmobd/cm_reint.c */
176 int smfs_write_extents(struct inode *dir, struct dentry *dentry,
177 unsigned long from, unsigned long num)
179 //smfs_post_rec_write(dir, dentry, &from, &num);
183 int smfs_rec_precreate(struct dentry *dentry, int *num, struct obdo *oa)
185 return smfs_post_rec_create(dentry->d_inode, dentry, num, oa);
188 int smfs_process_rec(struct super_block *sb,
189 int count, char *dir, int flags)
191 struct llog_ctxt *ctxt;
192 struct llog_handle *loghandle;
193 struct smfs_proc_args args;
197 if (!SMFS_INIT_REC(S2SMI(sb))) {
198 CWARN("Did not start up rec server \n");
202 memset(&args, 0, sizeof(struct smfs_proc_args));
204 args.sr_count = count;
206 args.sr_flags = flags ;
207 ctxt = S2SMI(sb)->smsi_kml_log;
208 loghandle = ctxt->loc_handle;
211 if (SMFS_DO_REINT_REC(flags)) {
212 struct llog_gen_rec *lgr;
214 /* for reint rec, we need insert a gen rec to identify
215 * the end of the rec.*/
216 OBD_ALLOC(lgr, sizeof(*lgr));
219 lgr->lgr_hdr.lrh_len = lgr->lgr_tail.lrt_len = sizeof(*lgr);
220 lgr->lgr_hdr.lrh_type = LLOG_GEN_REC;
221 lgr->lgr_gen = ctxt->loc_gen;
222 rc = llog_add(ctxt, &lgr->lgr_hdr, NULL, NULL, 1,
224 OBD_FREE(lgr, sizeof(*lgr));
229 SET_REC_COUNT_FLAGS(args.sr_flags, SMFS_REC_ALL);
232 if (SMFS_DO_REINT_REC(flags))
233 rc = llog_cat_process(loghandle, ctxt->llog_proc_cb,
236 rc = llog_cat_reverse_process(loghandle,
239 if (rc == LLOG_PROC_BREAK)
245 /* smfs_path is gotten from intermezzo */
246 static char *smfs_path(struct dentry *dentry, struct dentry *root, char *buffer,
249 char * end = buffer + buflen;
250 char * name = buffer;
251 char * buf_end = buffer + buflen;
261 struct dentry * parent;
266 parent = dentry->d_parent;
267 if (dentry == parent)
269 namelen = dentry->d_name.len;
270 buflen -= namelen + 1;
274 memcpy(end, dentry->d_name.name, namelen);
280 while (end != buf_end)
286 static int smfs_log_path(struct super_block *sb,
287 struct dentry *dentry,
291 struct dentry *root=sb->s_root;
292 char *p_name = buffer + sizeof(int);
298 name = smfs_path(dentry, root, p_name, buffer_len - sizeof(int));
299 namelen = cpu_to_le32(strlen(p_name));
300 memcpy(buffer, &namelen, sizeof(int));
302 namelen += sizeof(int);
306 static int smfs_pack_rec (char *buffer, struct dentry *dentry,
307 struct inode *dir, void *data1,
310 smfs_pack_rec_func pack_func;
312 pack_func = smfs_get_rec_pack_type(dir->i_sb);
315 return pack_func(buffer, dentry, dir, data1, data2, op);
318 static int smfs_insert_extents_ea(struct inode *inode, size_t from, loff_t num)
320 struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
324 if (SMFS_INODE_OVER_WRITE(inode))
327 rc = fsfilt->fs_insert_extents_ea(inode, OFF2BLKS(from, inode),
328 SIZE2BLKS(num, inode));
332 static int smfs_remove_extents_ea(struct inode *inode, size_t from, loff_t num)
334 struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
338 rc = fsfilt->fs_remove_extents_ea(inode, OFF2BLKS(from, inode),
339 SIZE2BLKS(num, inode));
344 static int smfs_remove_all_extents_ea(struct inode *inode)
346 struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
350 rc = fsfilt->fs_remove_extents_ea(inode, 0, 0xffffffff);
354 static int smfs_init_extents_ea(struct inode *inode)
356 struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
360 rc = fsfilt->fs_init_extents_ea(inode);
365 static int smfs_set_dirty_flags(struct inode *inode, int flags)
367 struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt;
372 if (SMFS_INODE_OVER_WRITE(inode))
374 /*FIXME later, the blocks needed in journal here will be recalculated*/
375 handle = smfs_trans_start(inode, FSFILT_OP_SETATTR);
376 if (IS_ERR(handle)) {
377 CERROR("smfs_set_dirty_flag:no space for transaction\n");
380 if ((!SMFS_INODE_DIRTY_WRITE(inode) && (!SMFS_INODE_OVER_WRITE(inode))) ||
381 ((flags == SMFS_OVER_WRITE) && (SMFS_INODE_DIRTY_WRITE(inode)))) {
382 rc = fsfilt->fs_set_xattr(inode, handle, REINT_EXTENTS_FLAGS,
383 &flags, sizeof(int));
387 if (flags == SMFS_OVER_WRITE)
388 SMFS_SET_INODE_OVER_WRITE(inode);
390 SMFS_SET_INODE_DIRTY_WRITE(inode);
392 smfs_trans_commit(inode, handle, 0);
396 static int all_blocks_present_ea(struct inode *inode)
406 static int kml_pack_path (char **buf, struct dentry * dentry)
409 int length = 0, rc = 0;
411 OBD_ALLOC(*buf, PAGE_SIZE);
416 KML_BUF_REC_INIT(*buf, pbuf, length);
417 rc = smfs_log_path(dentry->d_sb, dentry, pbuf, length);
423 KML_BUF_REC_END(*buf, length, pbuf);
429 static int kml_create(struct inode *inode, void *arg,
430 struct kml_priv *priv)
432 struct hook_msg * msg = arg;
433 //return smfs_post_rec_create(inode, msg->dentry, NULL, NULL);
434 struct smfs_super_info *smb = S2SMI(inode->i_sb);
436 int rc = 0, length = 0;
439 OBD_ALLOC(buffer, PAGE_SIZE);
444 rc = kml_pack_path(&buffer, msg->dentry);
449 pbuf = buffer + length;
451 rc = priv->pack_fn(REINT_CREATE, buffer, msg->dentry, inode,
457 rc = smfs_llog_add_rec(smb, (void*)buffer, length);
460 OBD_FREE(buffer, PAGE_SIZE);
465 static int kml_link(struct inode *inode, void *arg, struct kml_priv *priv)
467 struct hook_link_msg *msg = arg;
468 int rc = 0, length = 0;
472 OBD_ALLOC(buffer, PAGE_SIZE);
474 GOTO(exit, rc = -ENOMEM);
476 rc = priv->pack_fn(REINT_LINK, buffer, msg->dentry, inode,
477 msg->dentry, msg->new_dentry);
482 rc = smfs_llog_add_rec(S2SMI(inode->i_sb), (void *)buffer, length);
485 OBD_FREE(buffer, PAGE_SIZE);
490 static int kml_unlink(struct inode * inode, void *arg, struct kml_priv * priv)
492 struct hook_unlink_msg * msg = arg;
494 int length = 0, rc = 0;
497 OBD_ALLOC(buffer, PAGE_SIZE);
499 GOTO(exit, rc = -ENOMEM);
501 rc = priv->pack_fn(REINT_UNLINK, buffer, msg->dentry, inode,
507 rc = smfs_llog_add_rec(S2SMI(inode->i_sb), (void*)buffer, length);
510 OBD_FREE(buffer, PAGE_SIZE);
515 static int kml_symlink(struct inode *inode, void *arg, struct kml_priv *priv)
517 struct smfs_super_info *smb = S2SMI(inode->i_sb);
518 struct hook_symlink_msg *msg = arg;
519 int rc = 0, length = 0;
523 OBD_ALLOC(buffer, PAGE_SIZE);
525 GOTO(exit, rc = -ENOMEM);
527 rc = priv->pack_fn(REINT_CREATE, buffer, msg->dentry, inode,
528 msg->symname, &msg->tgt_len);
533 rc = smfs_llog_add_rec(smb, (void*)buffer, length);
536 OBD_FREE(buffer, PAGE_SIZE);
541 static int kml_rename(struct inode *inode, void *arg, struct kml_priv *priv)
543 struct hook_rename_msg *msg = arg;
544 int rc = 0, length = 0;
548 OBD_ALLOC(buffer, PAGE_SIZE);
550 GOTO(exit, rc = -ENOMEM);
552 rc = priv->pack_fn(REINT_RENAME, buffer, msg->dentry, inode,
553 msg->new_dir, msg->new_dentry);
558 rc = smfs_llog_add_rec(S2SMI(inode->i_sb), (void*)buffer, length);
561 OBD_FREE(buffer, PAGE_SIZE);
565 static int kml_setattr(struct inode *inode, void *arg, struct kml_priv *priv)
567 struct hook_attr_msg *msg = arg;
568 int rc = 0, length = 0;
572 OBD_ALLOC(buffer, PAGE_SIZE);
574 GOTO(exit, rc = -ENOMEM);
576 rc = priv->pack_fn(REINT_SETATTR, buffer, msg->dentry, inode,
582 rc = smfs_llog_add_rec(S2SMI(inode->i_sb), (void *)buffer, length);
585 if (attr && attr->ia_valid & ATTR_SIZE) {
586 smfs_remove_extents_ea(inode, attr->ia_size,
588 if (attr->ia_size == 0)
589 smfs_set_dirty_flags(inode, SMFS_OVER_WRITE);
591 smfs_set_dirty_flags(inode, SMFS_DIRTY_WRITE);
597 OBD_FREE(buffer, PAGE_SIZE);
601 static int kml_setxattr(struct inode *inode, void *arg, struct kml_priv *priv)
603 struct hook_xattr_msg *msg = arg;
604 struct kml_buffer kbuf;
605 int rc = 0, length = 0;
609 OBD_ALLOC(buffer, PAGE_SIZE);
611 GOTO(exit, rc = -ENOMEM);
613 kbuf.buf = msg->buffer;
614 kbuf.buf_size = msg->buffer_size;
616 rc = priv->pack_fn(REINT_SETXATTR, buffer, NULL, inode,
622 rc = smfs_llog_add_rec(S2SMI(inode->i_sb), (void *)buffer, length);
625 if (attr && attr->ia_valid & ATTR_SIZE) {
626 smfs_remove_extents_ea(inode, attr->ia_size,
628 if (attr->ia_size == 0)
629 smfs_set_dirty_flags(inode, SMFS_OVER_WRITE);
631 smfs_set_dirty_flags(inode, SMFS_DIRTY_WRITE);
637 OBD_FREE(buffer, PAGE_SIZE);
642 static int kml_write(struct inode * inode, void *arg, struct kml_priv * priv)
644 struct hook_write_msg * msg = arg;
645 //return smfs_post_rec_write(inode, msg->dentry, &msg->count, &msg->pos);
646 struct smfs_super_info *sinfo;
647 char *buffer = NULL, *pbuf;
648 int rc = 0, length = 0, buf_len = 0;
651 if (!SMFS_INODE_OVER_WRITE(dentry->d_inode) &&
652 !SMFS_INODE_DIRTY_WRITE(dentry->d_inode)) {
653 sinfo = S2SMI(dentry->d_inode->i_sb);
657 OBD_ALLOC(buffer, PAGE_SIZE);
659 GOTO(exit, rc = -ENOMEM);
662 KML_BUF_REC_INIT(buffer, pbuf, buf_len);
663 rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len);
668 memcpy(buffer, &rc, sizeof(int));
669 length = rc + sizeof(int);
671 rc = smfs_pack_rec(pbuf, dentry, dir,
672 data1, data2, REINT_WRITE);
678 rc = smfs_llog_add_rec(sinfo, (void*)buffer, length);
681 rc = smfs_init_extents_ea(dentry->d_inode);
685 if (dentry->d_inode->i_size == 0) {
686 smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE);
689 loff_t off = *((loff_t*)data1);
690 size_t count = *((size_t*)data2);
692 rc = smfs_insert_extents_ea(dentry->d_inode, off, count);
695 if (all_blocks_present_ea(dentry->d_inode)){
696 smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE);
697 smfs_remove_all_extents_ea(dentry->d_inode);
699 smfs_set_dirty_flags(dentry->d_inode, SMFS_DIRTY_WRITE);
704 OBD_FREE(buffer, PAGE_SIZE);
709 typedef int (*post_kml_op)(struct inode *inode, void *msg,
710 struct kml_priv *priv);
712 static post_kml_op smfs_kml_post[HOOK_MAX] = {
713 [HOOK_CREATE] kml_create,
715 [HOOK_LINK] kml_link,
716 [HOOK_UNLINK] kml_unlink,
717 [HOOK_SYMLINK] kml_symlink,
718 [HOOK_MKDIR] kml_create,
719 [HOOK_RMDIR] kml_unlink,
720 [HOOK_MKNOD] kml_create,
721 [HOOK_RENAME] kml_rename,
722 [HOOK_SETATTR] kml_setattr,
725 [HOOK_F_SETXATTR] kml_setxattr,
728 static int smfs_kml_post_op(hook_op code, struct inode * inode,
729 void * msg, int ret, void * priv)
735 //check if inode has flag for KML
736 if (!SMFS_IS(I2SMI(inode)->smi_flags, SMFS_PLG_KML))
739 //KML don't handle failed ops
743 if (smfs_kml_post[code]) {
744 CDEBUG(D_INODE,"KML: inode %lu, code: %u\n",
746 rc = smfs_kml_post[code](inode, msg, priv);
753 static int smfs_trans_kml (struct super_block *sb, void *arg,
754 struct kml_priv * priv)
759 /* FIXME-MIKE: pass fs opcode and see if kml can participate or not one
760 * record in log per operation size = 1 */
765 static int smfs_start_kml(struct super_block *sb, void *arg,
766 struct kml_priv *kml_p)
768 struct smfs_super_info *smb = S2SMI(sb);
769 struct llog_ctxt **ctxt = &smb->smsi_kml_log;
770 struct obd_device *obd = arg;
774 /* is plugin already activated */
775 if (SMFS_IS(smb->plg_flags, SMFS_PLG_KML))
778 if (obd && obd->obd_type && obd->obd_type->typ_name) {
779 if (!strcmp(obd->obd_type->typ_name, OBD_MDS_DEVICENAME)) {
780 kml_p->pack_fn = mds_rec_pack;
781 } else if (!strcmp(obd->obd_type->typ_name, OBD_FILTER_DEVICENAME)) {
782 kml_p->pack_fn = ost_rec_pack;
784 CWARN("unexpected device type: %s\n", obd->obd_type->typ_name);
788 LASSERT(kml_p->pack_fn != NULL);
790 /* this will do OBD_ALLOC() for ctxt */
791 rc = llog_catalog_setup(ctxt, KML_LOG_NAME, smb->smsi_exp,
792 smb->smsi_ctxt, smb->sm_fsfilt,
793 smb->smsi_logs_dir, smb->smsi_objects_dir);
795 CERROR("failed to initialize kml log list catalog %d\n", rc);
799 /* connect KML ctxt to obd */
800 if (obd && smb->smsi_kml_log) {
801 smb->smsi_kml_log->loc_idx = LLOG_REINT_ORIG_CTXT;
802 smb->smsi_kml_log->loc_obd = obd;
803 smb->smsi_kml_log->loc_llogs = &obd->obd_llogs;
804 obd->obd_llogs.llog_ctxt[LLOG_REINT_ORIG_CTXT] = smb->smsi_kml_log;
807 SMFS_SET(smb->plg_flags, SMFS_PLG_KML);
811 int smfs_stop_kml(struct super_block *sb, void *arg,
812 struct kml_priv * kml_p)
814 struct smfs_super_info * smb = S2SMI(sb);
815 struct llog_ctxt *ctxt = smb->smsi_kml_log;
816 struct obd_device * obd = ctxt->loc_obd;
819 if (!SMFS_IS(smb->plg_flags, SMFS_PLG_KML))
822 SMFS_CLEAR(smb->plg_flags, SMFS_PLG_KML);
824 llog_catalog_cleanup(ctxt);
825 obd->obd_llogs.llog_ctxt[LLOG_REINT_ORIG_CTXT] = NULL;
826 OBD_FREE(ctxt, sizeof(*ctxt));
831 typedef int (*kml_helper)(struct super_block * sb, void *msg, struct kml_priv *);
832 static kml_helper smfs_kml_helpers[PLG_HELPER_MAX] = {
833 [PLG_START] smfs_start_kml,
834 [PLG_STOP] smfs_stop_kml,
835 [PLG_TRANS_SIZE] smfs_trans_kml,
836 [PLG_TEST_INODE] NULL,
837 [PLG_SET_INODE] NULL,
840 static int smfs_kml_help_op(int code, struct super_block * sb,
841 void * arg, void * priv)
845 if (smfs_kml_helpers[code])
846 rc = smfs_kml_helpers[code](sb, arg, (struct kml_priv *) priv);
850 static int smfs_exit_kml(struct super_block *sb, void * arg)
852 struct smfs_plugin * plg = NULL;
853 struct kml_priv * priv = arg;
856 plg = smfs_deregister_plugin(sb, SMFS_PLG_KML);
858 OBD_FREE(plg, sizeof(*plg));
860 CERROR("Cannot find KLM plugin while unregistering\n");
863 OBD_FREE(priv, sizeof(*priv));
869 int smfs_init_kml(struct super_block *sb)
872 struct kml_priv * priv = NULL;
873 struct smfs_plugin * plg = NULL;
876 OBD_ALLOC(plg, sizeof(*plg));
882 plg->plg_type = SMFS_PLG_KML;
883 plg->plg_pre_op = NULL;
884 plg->plg_post_op = smfs_kml_post_op;
885 plg->plg_helper = smfs_kml_help_op;
886 plg->plg_exit = smfs_exit_kml;
888 OBD_ALLOC(priv, sizeof(*priv));
894 plg->plg_private = priv;
896 rc = smfs_register_plugin(sb, plg);
901 OBD_FREE(priv, sizeof(*priv));
904 OBD_FREE(plg, sizeof(*plg));