diff --git a/lustre/include/linux/lustre_smfs.h b/lustre/include/linux/lustre_smfs.h index ac5f5f352483057fb548103f122d36081cb69e46..474095c039845448a099d97f2540c22572a69fd6 100644 --- a/lustre/include/linux/lustre_smfs.h +++ b/lustre/include/linux/lustre_smfs.h @@ -72,7 +72,7 @@ struct mds_kml_pack_info { int mpi_size[4]; int mpi_total_size; }; -typedef int (*smfs_hook_func)(struct inode *inode, struct dentry *dentry, +typedef int (*smfs_hook_func)(struct inode *inode, void *dentry, void *data1, void *data2, int op, void *handle); struct smfs_hook_ops { struct list_head smh_list; diff --git a/lustre/include/linux/lustre_snap.h b/lustre/include/linux/lustre_snap.h index e605da6d4e716c961c9400d9b17aea545e9d93a2..45814686b124da5a7d7a5ac98fa1b94f0a819cd1 100644 --- a/lustre/include/linux/lustre_snap.h +++ b/lustre/include/linux/lustre_snap.h @@ -201,8 +201,7 @@ struct write_extents { }; int smfs_cow(struct inode *dir, struct dentry *dentry, void *data1, void *data2, int op); -int smfs_cow_write(struct inode *inode, struct dentry *dentry, void *data1, - void *data2); +int smfs_cow_write_pre(struct inode *inode, void *de, void *data1, void *data2); struct inode* smfs_cow_get_ind(struct inode *inode, int index); diff --git a/lustre/lvfs/fsfilt_smfs.c b/lustre/lvfs/fsfilt_smfs.c index f986514f60655030943010d194e2c939d75fdfbd..d1573f6a51bc71c5694fd1a16a0bc82e8f20bdf6 100644 --- a/lustre/lvfs/fsfilt_smfs.c +++ b/lustre/lvfs/fsfilt_smfs.c @@ -988,7 +988,7 @@ static int fsfilt_smfs_do_write_cow(struct dentry *de, void *extents, for (i = 0; i < num_extents; i++) { size_t count = w_ext->w_count; loff_t off = w_ext->w_pos; - rc = smfs_cow_write(de->d_inode, de, &count, &off); + rc = smfs_cow_write_pre(de->d_inode, de, &count, &off); if (rc) RETURN(rc); w_ext ++; diff --git a/lustre/smfs/Makefile.in b/lustre/smfs/Makefile.in index d95b3a7a8c44fd522845e375914b3f183ec94ef8..1f8f38727d86b36d351c9f0e81d074afd1b7dd64 100644 --- a/lustre/smfs/Makefile.in +++ b/lustre/smfs/Makefile.in @@ -1,6 +1,6 @@ MODULES := smfs smfs-objs := super.o options.o inode.o cache.o cache_space.o dir.o ioctl.o -smfs-objs += sysctl.o file.o symlink.o smfs_lib.o kml.o journal.o smfs_llog.o +smfs-objs += sysctl.o file.o symlink.o smfs_lib.o kml.o smfs_llog.o smfs-objs += mds_kml.o ost_kml.o @SNAPFS_TRUE@smfs-objs += smfs_cow.o @INCLUDE_RULES@ diff --git a/lustre/smfs/cache_space.c b/lustre/smfs/cache_space.c index 9d3bd964ec97054a014f7628747897975dfcaa57..31fcd5619ba61761601bf2f21b15b281cb6aab86 100644 --- a/lustre/smfs/cache_space.c +++ b/lustre/smfs/cache_space.c @@ -44,7 +44,7 @@ static struct cache_purge_queue smfs_cpq; static struct cache_purge_queue *cpq = &smfs_cpq; #define CACHE_HOOK "cache_hook" -int cache_space_pre_hook(struct inode *inode, struct dentry *dentry, +int cache_space_pre_hook(struct inode *inode, void *dentry, void *data1, void *data2, int op, void *handle) { int rc = 0; @@ -62,14 +62,16 @@ int cache_space_pre_hook(struct inode *inode, struct dentry *dentry, RETURN(rc); } -int cache_space_post_hook(struct inode *inode, struct dentry *dentry, - void *data1, void *data2, int op, void *handle) +int cache_space_post_hook(struct inode *inode, void *de, void *data1, + void *data2, int op, void *handle) { int rc = 0; ENTRY; if (smfs_cache_hook(inode)) { struct inode *new_inode = (struct inode*)data1; - struct dentry *new_dentry = (struct dentry*)data2; + struct dentry *new_dentry = (struct dentry*)data2; + struct dentry *dentry = (struct dentry *)de; + LASSERT(handle != NULL); rc = cache_space_post(op, handle, inode, dentry, new_inode, new_dentry); diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index a9c24342ffb9a6e4f38c9ab5be4f9faa5b4552e7..0bb2586d14f71be41a78dff8c5f43dfafbdb55c3 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -614,9 +614,17 @@ static int smfs_readdir(struct file *filp, void *dirent, filldir_t filldir) sfi = F2SMFI(filp); if (sfi->magic != SMFS_FILE_MAGIC) BUG(); + SMFS_HOOK(dentry->d_inode, filp, dirent, filldir, HOOK_READDIR, NULL, + PRE_HOOK, rc, exit); + if (cache_inode->i_fop->readdir) rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir); + SMFS_HOOK(dentry->d_inode, filp, dirent, filldir, HOOK_READDIR, NULL, + POST_HOOK, rc, exit); +exit: + if (rc > 0) + rc = 0; duplicate_file(filp, sfi->c_file); RETURN(rc); } diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index 59badd4b2f6fce6a483714fed63a05c72f474d00..1c7576fd1781c8ee2a889e53568d0eafd87db57d 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -42,7 +42,10 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque) struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque; struct inode *cache_inode = NULL; - cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); + if (sargs) + cache_inode = iget(S2CSB(inode->i_sb), sargs->s_ino); + else + cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); OBD_ALLOC(I2SMI(inode), sizeof(struct smfs_inode_info)); LASSERT(I2SMI(inode)); @@ -51,13 +54,11 @@ static void smfs_init_inode_info (struct inode *inode, void *opaque) cache_inode->i_ino, atomic_read(&cache_inode->i_count)); post_smfs_inode(inode, cache_inode); sm_set_inode_ops(cache_inode, inode); - if (sargs) { struct inode *dir = sargs->s_inode; - if (dir) I2SMI(inode)->smi_flags = I2SMI(dir)->smi_flags; - } + } } static void smfs_clear_inode_info(struct inode *inode) @@ -130,6 +131,7 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash, unlock_new_inode(inode); CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino, inode->i_generation, inode); + inode->i_ino = hash; } return inode; } @@ -151,12 +153,12 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash, struct inode *smfs_get_inode (struct super_block *sb, ino_t hash, struct inode *dir, int index) { - struct inode *inode = NULL; + struct inode *inode; struct smfs_iget_args sargs; ENTRY; sargs.s_index = index; - sargs.s_inode = inode; + sargs.s_inode = dir; sargs.s_ino = hash; inode = smfs_iget(sb, hash, &sargs); diff --git a/lustre/smfs/journal.c b/lustre/smfs/journal.c deleted file mode 100644 index ab62e7af83be6aaff934b76c9f8e20bb4c98a808..0000000000000000000000000000000000000000 --- a/lustre/smfs/journal.c +++ /dev/null @@ -1,544 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/smfs/journal.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2004 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#define DEBUG_SUBSYSTEM S_SM - -#include <linux/kmod.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <asm/segment.h> -#include <asm/uaccess.h> -#include <linux/obd_class.h> -#include <linux/obd_support.h> -#include <linux/lustre_lib.h> -#include <linux/lustre_idl.h> -#include <linux/lustre_fsfilt.h> -#include <linux/lustre_smfs.h> -#include <linux/lvfs.h> -#include "smfs_internal.h" - -#define KML_BUF_REC_INIT(buffer, pbuf, len) \ -do { \ - pbuf = buffer + sizeof(int); \ - len -= sizeof(int); \ -} while (0) - -#define KML_BUF_REC_END(buffer, length, pbuf) \ -do { \ - int len = length; \ - memcpy(buffer, &len, sizeof(len)); \ - length += sizeof(int); \ - pbuf = buffer + length; \ -} while (0) - -void *smfs_trans_start(struct inode *inode, int op, void *desc_private) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - - CDEBUG(D_INFO, "trans start %p\n", fsfilt->fs_start); - - SMFS_TRANS_OP(inode, op); - - /* There are some problem here. fs_start in fsfilt is used by lustre - * the journal blocks of write rec are not counted in FIXME later */ - if (fsfilt->fs_start) - return fsfilt->fs_start(inode, op, desc_private, 0); - return NULL; -} - -void smfs_trans_commit(struct inode *inode, void *handle, int force_sync) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - - if (!handle) - return; - - CDEBUG(D_INFO, "trans commit %p\n", fsfilt->fs_commit); - - if (fsfilt->fs_commit) - fsfilt->fs_commit(inode->i_sb, inode, handle, force_sync); -} - -/*smfs_path is gotten from intermezzo*/ -static char* smfs_path(struct dentry *dentry, struct dentry *root, char *buffer, - int buflen) -{ - char * end = buffer + buflen; - char * name = buffer; - char * buf_end = buffer + buflen; - char * retval; - - *--end = '\0'; - buflen--; - /* Get '/' right */ - retval = end-1; - *retval = '/'; - - for (;;) { - struct dentry * parent; - int namelen; - - if (dentry == root) - break; - parent = dentry->d_parent; - if (dentry == parent) - break; - namelen = dentry->d_name.len; - buflen -= namelen + 1; - if (buflen < 0) - break; - end -= namelen; - memcpy(end, dentry->d_name.name, namelen); - *--end = '/'; - retval = end; - dentry = parent; - } - - while (end != buf_end) - *name++ = *end++; - *name = '\0'; - return retval; -} - -static int smfs_log_path(struct super_block *sb, - struct dentry *dentry, - char *buffer, - int buffer_len) -{ - struct dentry *root=sb->s_root; - char *p_name = buffer + sizeof(int); - char *name = NULL; - int namelen = 0; - if (dentry) { - name = smfs_path(dentry, root, p_name, buffer_len - sizeof(int)); - namelen = cpu_to_le32(strlen(p_name)); - memcpy(buffer, &namelen, sizeof(int)); - } - namelen += sizeof(int); - RETURN(namelen); -} - -static inline int log_it(char *buffer, void *data, int length) -{ - memcpy(buffer, &length, sizeof(int)); - memcpy(buffer + sizeof(int), data, length); - return (sizeof(int) + length); -} - -static int smfs_pack_rec (char *buffer, struct dentry *dentry, - struct inode *dir, void *data1, - void *data2, int op) -{ - smfs_pack_rec_func pack_func; - int rc; - - pack_func = smfs_get_rec_pack_type(dir->i_sb); - if (!pack_func) { - return (0); - } - rc = pack_func(buffer, dentry, dir, data1, data2, op); - return rc; -} - -int smfs_post_rec_create(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) -{ - struct smfs_super_info *sinfo; - char *buffer = NULL, *pbuf; - int rc = 0, length = 0, buf_len = 0; - - sinfo = S2SMI(dentry->d_inode->i_sb); - if (!sinfo) - RETURN(-EINVAL); - - OBD_ALLOC(buffer, PAGE_SIZE); - if (!buffer) - GOTO(exit, rc = -ENOMEM); - - buf_len = PAGE_SIZE; - KML_BUF_REC_INIT(buffer, pbuf, buf_len); - rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); - if (rc < 0) - GOTO(exit, rc); - length = rc; - KML_BUF_REC_END(buffer, length, pbuf); - - rc = smfs_pack_rec(pbuf, dentry, dir, - data1, data2, REINT_CREATE); - if (rc <= 0) - GOTO(exit, rc); - else - length += rc; - rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); -exit: - if (buffer) - OBD_FREE(buffer, PAGE_SIZE); - - RETURN(rc); -} - -static int smfs_post_rec_link(struct inode *dir, - struct dentry *dentry, - void *data1, - void *data2) -{ - struct smfs_super_info *sinfo; - struct dentry *old_dentry = (struct dentry *)data1; - char *buffer = NULL, *pbuf = NULL; - int rc = 0, length = 0, buf_len = 0; - - sinfo = S2SMI(dir->i_sb); - if (!sinfo) - RETURN(-EINVAL); - OBD_ALLOC(buffer, PAGE_SIZE); - if (!buffer) - GOTO(exit, rc = -ENOMEM); - - buf_len = PAGE_SIZE; - KML_BUF_REC_INIT(buffer, pbuf, buf_len); - rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); - if (rc < 0) - GOTO(exit, rc); - - length = rc; - KML_BUF_REC_END(buffer, length, pbuf); - - rc = smfs_pack_rec(pbuf, dentry, dir, dentry->d_parent, - old_dentry->d_parent, REINT_LINK); - if (rc <= 0) - GOTO(exit, rc); - else - length += rc; - rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); -exit: - if (buffer) - OBD_FREE(buffer, PAGE_SIZE); - - RETURN(rc); -} - -static int smfs_post_rec_unlink(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) -{ - struct smfs_super_info *sinfo; - int mode = *((int*)data1); - char *buffer = NULL, *pbuf = NULL; - int length = 0, rc = 0, buf_len = 0; - - sinfo = S2SMI(dentry->d_inode->i_sb); - if (!sinfo) - RETURN(-EINVAL); - - OBD_ALLOC(buffer, PAGE_SIZE); - if (!buffer) - GOTO(exit, rc = -ENOMEM); - - buf_len = PAGE_SIZE; - KML_BUF_REC_INIT(buffer, pbuf, buf_len); - rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); - if (rc < 0) - GOTO(exit, rc); - - length = rc; - KML_BUF_REC_END(buffer, length, pbuf); - rc = smfs_pack_rec(pbuf, dentry, dir, - &mode, NULL, REINT_UNLINK); - if (rc <= 0) - GOTO(exit, rc); - else - length += rc; - - rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); -exit: - if (buffer) - OBD_FREE(buffer, PAGE_SIZE); - - RETURN(rc); -} - -static int smfs_post_rec_rename(struct inode *dir, - struct dentry *dentry, - void *data1, - void *data2) -{ - struct smfs_super_info *sinfo; - struct inode *new_dir = (struct inode *)data1; - struct dentry *new_dentry = (struct dentry *)data2; - char *buffer = NULL, *pbuf = NULL; - int rc = 0, length = 0, buf_len = 0; - - sinfo = S2SMI(dir->i_sb); - if (!sinfo) - RETURN(-EINVAL); - - OBD_ALLOC(buffer, PAGE_SIZE); - if (!buffer) - GOTO(exit, rc = -ENOMEM); - - buf_len = PAGE_SIZE; - KML_BUF_REC_INIT(buffer, pbuf, buf_len); - rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); - if (rc < 0) - GOTO(exit, rc); - - pbuf += rc; - length += rc; - buf_len -= rc; - /*record new_dentry path*/ - rc = smfs_log_path(dir->i_sb, new_dentry, pbuf, buf_len); - if (rc < 0) - GOTO(exit, rc); - - length += rc; - KML_BUF_REC_END(buffer, length, pbuf); - - rc = smfs_pack_rec(pbuf, dentry, dir, - new_dir, new_dentry, REINT_RENAME); - if (rc <= 0) - GOTO(exit, rc); - length += rc; - - rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); -exit: - if (buffer) - OBD_FREE(buffer, PAGE_SIZE); - RETURN(rc); -} - -static int smfs_insert_extents_ea(struct inode *inode, size_t from, loff_t num) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - int rc = 0; - - if (SMFS_INODE_OVER_WRITE(inode)) - RETURN(rc); - - rc = fsfilt->fs_insert_extents_ea(inode, OFF2BLKS(from, inode), - SIZE2BLKS(num, inode)); - RETURN(rc); -} - -static int smfs_remove_extents_ea(struct inode *inode, size_t from, loff_t num) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - int rc = 0; - - rc = fsfilt->fs_remove_extents_ea(inode, OFF2BLKS(from, inode), - SIZE2BLKS(num, inode)); - - RETURN(rc); -} - -static int smfs_remove_all_extents_ea(struct inode *inode) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - int rc = 0; - - rc = fsfilt->fs_remove_extents_ea(inode, 0, 0xffffffff); - RETURN(rc); -} -static int smfs_init_extents_ea(struct inode *inode) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - int rc = 0; - - rc = fsfilt->fs_init_extents_ea(inode); - - RETURN(rc); -} -static int smfs_set_dirty_flags(struct inode *inode, int flags) -{ - struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; - void *handle; - int rc = 0; - - if (SMFS_INODE_OVER_WRITE(inode)) - RETURN(rc); - /*FIXME later, the blocks needed in journal here will be recalculated*/ - handle = smfs_trans_start(inode, FSFILT_OP_SETATTR, NULL); - if (IS_ERR(handle)) { - CERROR("smfs_set_dirty_flag:no space for transaction\n"); - RETURN(-ENOSPC); - } - if ((!SMFS_INODE_DIRTY_WRITE(inode) && (!SMFS_INODE_OVER_WRITE(inode))) || - ((flags == SMFS_OVER_WRITE) && (SMFS_INODE_DIRTY_WRITE(inode)))) { - rc = fsfilt->fs_set_xattr(inode, handle, REINT_EXTENTS_FLAGS, - &flags, sizeof(int)); - if (rc) - GOTO(out, rc); - } - if (flags == SMFS_OVER_WRITE) - SMFS_SET_INODE_OVER_WRITE(inode); - else - SMFS_SET_INODE_DIRTY_WRITE(inode); -out: - smfs_trans_commit(inode, handle, 0); - RETURN(rc); -} - -int smfs_post_rec_setattr(struct inode *inode, struct dentry *dentry, - void *data1, void *data2) -{ - struct smfs_super_info *sinfo; - struct iattr *attr = (struct iattr *)data1; - char *buffer = NULL, *pbuf; - int rc = 0, length = 0, buf_len = 0; - - sinfo = S2SMI(inode->i_sb); - if (!sinfo) - RETURN(-EINVAL); - - OBD_ALLOC(buffer, PAGE_SIZE); - if (!buffer) - GOTO(exit, rc = -ENOMEM); - - buf_len = PAGE_SIZE; - KML_BUF_REC_INIT(buffer, pbuf, buf_len); - rc = smfs_log_path(inode->i_sb, dentry, pbuf, buf_len); - if (rc < 0) - GOTO(exit, rc); - - length = rc; - KML_BUF_REC_END(buffer, length, pbuf); - - rc = smfs_pack_rec(pbuf, dentry, inode, - data1, data2, REINT_SETATTR); - if (rc <= 0) - GOTO(exit, rc); - else - length += rc; - - rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); - if (!rc) { - if (attr && attr->ia_valid & ATTR_SIZE) { - smfs_remove_extents_ea(inode, attr->ia_size, - 0xffffffff); - if (attr->ia_size == 0) - smfs_set_dirty_flags(inode, SMFS_OVER_WRITE); - else - smfs_set_dirty_flags(inode, SMFS_DIRTY_WRITE); - } - } -exit: - if (buffer) - OBD_FREE(buffer, PAGE_SIZE); - RETURN(rc); -} - -static int all_blocks_present_ea(struct inode *inode) -{ - int rc = 0; - - RETURN(rc); -} -int smfs_post_rec_write(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) -{ - struct smfs_super_info *sinfo; - char *buffer = NULL, *pbuf; - int rc = 0, length = 0, buf_len = 0; - - if (!SMFS_INODE_OVER_WRITE(dentry->d_inode) && - !SMFS_INODE_DIRTY_WRITE(dentry->d_inode)) { - sinfo = S2SMI(dentry->d_inode->i_sb); - if (!sinfo) - RETURN(-EINVAL); - - OBD_ALLOC(buffer, PAGE_SIZE); - if (!buffer) - GOTO(exit, rc = -ENOMEM); - - buf_len = PAGE_SIZE; - KML_BUF_REC_INIT(buffer, pbuf, buf_len); - rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); - - if (rc < 0) - GOTO(exit, rc); - pbuf += rc; - memcpy(buffer, &rc, sizeof(int)); - length = rc + sizeof(int); - - rc = smfs_pack_rec(pbuf, dentry, dir, - data1, data2, REINT_WRITE); - if (rc <= 0) - GOTO(exit, rc); - else - length += rc; - - rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); - if (rc) - GOTO(exit, rc); - rc = smfs_init_extents_ea(dentry->d_inode); - if (rc) - GOTO(exit, rc); - } - if (dentry->d_inode->i_size == 0) { - smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE); - } else { - /*insert extent EA*/ - loff_t off = *((loff_t*)data1); - size_t count = *((size_t*)data2); - - rc = smfs_insert_extents_ea(dentry->d_inode, off, count); - if (rc < 0) - GOTO(exit, rc); - if (all_blocks_present_ea(dentry->d_inode)){ - smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE); - smfs_remove_all_extents_ea(dentry->d_inode); - } else { - smfs_set_dirty_flags(dentry->d_inode, SMFS_DIRTY_WRITE); - } - } -exit: - if (buffer) - OBD_FREE(buffer, PAGE_SIZE); - RETURN(rc); -} - -typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry, - void *data1, void *data2); - -static post_kml_rec smfs_kml_post[HOOK_MAX + 1] = { - [HOOK_CREATE] smfs_post_rec_create, - [HOOK_LOOKUP] NULL, - [HOOK_LINK] smfs_post_rec_link, - [HOOK_UNLINK] smfs_post_rec_unlink, - [HOOK_SYMLINK] smfs_post_rec_create, - [HOOK_MKDIR] smfs_post_rec_create, - [HOOK_RMDIR] smfs_post_rec_unlink, - [HOOK_MKNOD] smfs_post_rec_create, - [HOOK_RENAME] smfs_post_rec_rename, - [HOOK_SETATTR] smfs_post_rec_setattr, - [HOOK_WRITE] smfs_post_rec_write, -}; - -int smfs_post_kml_rec(struct inode *dir, struct dentry *dst_dentry, - void *data1, void *data2, int op) -{ - if (smfs_kml_post[op]) { - return smfs_kml_post[op](dir, dst_dentry, data1, data2); - } - return 0; -} diff --git a/lustre/smfs/kml.c b/lustre/smfs/kml.c index 242c0e280c9659f76f84f785ef18c8f8f6591a4f..226230c4c296aa99ccd186183fc07b85e8642524 100644 --- a/lustre/smfs/kml.c +++ b/lustre/smfs/kml.c @@ -39,7 +39,21 @@ #include <linux/lustre_smfs.h> #include "smfs_internal.h" -smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb) +#define KML_BUF_REC_INIT(buffer, pbuf, len) \ +do { \ + pbuf = buffer + sizeof(int); \ + len -= sizeof(int); \ +} while (0) + +#define KML_BUF_REC_END(buffer, length, pbuf) \ +do { \ + int len = length; \ + memcpy(buffer, &len, sizeof(len)); \ + length += sizeof(int); \ + pbuf = buffer + length; \ +} while (0) + +static smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb) { struct smfs_super_info *smsi = S2SMI(sb); @@ -47,7 +61,11 @@ smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb) return smsi->smsi_pack_rec[index]; } -static int smfs_rec_post_hook(struct inode *inode, struct dentry *dentry, + +static int smfs_post_kml_rec(struct inode *dir, void *de, void *data1, + void *data2, int op); + +static int smfs_rec_post_hook(struct inode *inode, void *dentry, void *data1, void *data2, int op, void *handle) { int rc = 0; @@ -332,3 +350,462 @@ int smfs_process_rec(struct super_block *sb, } RETURN(rc); } + +/*smfs_path is gotten from intermezzo*/ +static char* smfs_path(struct dentry *dentry, struct dentry *root, char *buffer, + int buflen) +{ + char * end = buffer + buflen; + char * name = buffer; + char * buf_end = buffer + buflen; + char * retval; + + *--end = '\0'; + buflen--; + /* Get '/' right */ + retval = end-1; + *retval = '/'; + + for (;;) { + struct dentry * parent; + int namelen; + + if (dentry == root) + break; + parent = dentry->d_parent; + if (dentry == parent) + break; + namelen = dentry->d_name.len; + buflen -= namelen + 1; + if (buflen < 0) + break; + end -= namelen; + memcpy(end, dentry->d_name.name, namelen); + *--end = '/'; + retval = end; + dentry = parent; + } + + while (end != buf_end) + *name++ = *end++; + *name = '\0'; + return retval; +} + +static int smfs_log_path(struct super_block *sb, + struct dentry *dentry, + char *buffer, + int buffer_len) +{ + struct dentry *root=sb->s_root; + char *p_name = buffer + sizeof(int); + char *name = NULL; + int namelen = 0; + if (dentry) { + name = smfs_path(dentry, root, p_name, buffer_len - sizeof(int)); + namelen = cpu_to_le32(strlen(p_name)); + memcpy(buffer, &namelen, sizeof(int)); + } + namelen += sizeof(int); + RETURN(namelen); +} + +static inline int log_it(char *buffer, void *data, int length) +{ + memcpy(buffer, &length, sizeof(int)); + memcpy(buffer + sizeof(int), data, length); + return (sizeof(int) + length); +} + +static int smfs_pack_rec (char *buffer, struct dentry *dentry, + struct inode *dir, void *data1, + void *data2, int op) +{ + smfs_pack_rec_func pack_func; + int rc; + + pack_func = smfs_get_rec_pack_type(dir->i_sb); + if (!pack_func) { + return (0); + } + rc = pack_func(buffer, dentry, dir, data1, data2, op); + return rc; +} + +int smfs_post_rec_create(struct inode *dir, struct dentry *dentry, void *data1, + void *data2) +{ + struct smfs_super_info *sinfo; + char *buffer = NULL, *pbuf; + int rc = 0, length = 0, buf_len = 0; + + sinfo = S2SMI(dentry->d_inode->i_sb); + if (!sinfo) + RETURN(-EINVAL); + + OBD_ALLOC(buffer, PAGE_SIZE); + if (!buffer) + GOTO(exit, rc = -ENOMEM); + + buf_len = PAGE_SIZE; + KML_BUF_REC_INIT(buffer, pbuf, buf_len); + rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); + if (rc < 0) + GOTO(exit, rc); + length = rc; + KML_BUF_REC_END(buffer, length, pbuf); + + rc = smfs_pack_rec(pbuf, dentry, dir, + data1, data2, REINT_CREATE); + if (rc <= 0) + GOTO(exit, rc); + else + length += rc; + rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); +exit: + if (buffer) + OBD_FREE(buffer, PAGE_SIZE); + + RETURN(rc); +} + +static int smfs_post_rec_link(struct inode *dir, struct dentry *dentry, + void *data1, void *data2) +{ + struct smfs_super_info *sinfo; + struct dentry *old_dentry = (struct dentry *)data1; + char *buffer = NULL, *pbuf = NULL; + int rc = 0, length = 0, buf_len = 0; + + sinfo = S2SMI(dir->i_sb); + if (!sinfo) + RETURN(-EINVAL); + OBD_ALLOC(buffer, PAGE_SIZE); + if (!buffer) + GOTO(exit, rc = -ENOMEM); + + buf_len = PAGE_SIZE; + KML_BUF_REC_INIT(buffer, pbuf, buf_len); + rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); + if (rc < 0) + GOTO(exit, rc); + + length = rc; + KML_BUF_REC_END(buffer, length, pbuf); + + rc = smfs_pack_rec(pbuf, dentry, dir, dentry->d_parent, + old_dentry->d_parent, REINT_LINK); + if (rc <= 0) + GOTO(exit, rc); + else + length += rc; + rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); +exit: + if (buffer) + OBD_FREE(buffer, PAGE_SIZE); + + RETURN(rc); +} + +static int smfs_post_rec_unlink(struct inode *dir, struct dentry *dentry, + void *data1, void *data2) +{ + struct smfs_super_info *sinfo; + int mode = *((int*)data1); + char *buffer = NULL, *pbuf = NULL; + int length = 0, rc = 0, buf_len = 0; + + sinfo = S2SMI(dentry->d_inode->i_sb); + if (!sinfo) + RETURN(-EINVAL); + + OBD_ALLOC(buffer, PAGE_SIZE); + if (!buffer) + GOTO(exit, rc = -ENOMEM); + + buf_len = PAGE_SIZE; + KML_BUF_REC_INIT(buffer, pbuf, buf_len); + rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); + if (rc < 0) + GOTO(exit, rc); + + length = rc; + KML_BUF_REC_END(buffer, length, pbuf); + rc = smfs_pack_rec(pbuf, dentry, dir, + &mode, NULL, REINT_UNLINK); + if (rc <= 0) + GOTO(exit, rc); + else + length += rc; + + rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); +exit: + if (buffer) + OBD_FREE(buffer, PAGE_SIZE); + + RETURN(rc); +} + +static int smfs_post_rec_rename(struct inode *dir, struct dentry *dentry, + void *data1, void *data2) +{ + struct smfs_super_info *sinfo; + struct inode *new_dir = (struct inode *)data1; + struct dentry *new_dentry = (struct dentry *)data2; + char *buffer = NULL, *pbuf = NULL; + int rc = 0, length = 0, buf_len = 0; + + sinfo = S2SMI(dir->i_sb); + if (!sinfo) + RETURN(-EINVAL); + + OBD_ALLOC(buffer, PAGE_SIZE); + if (!buffer) + GOTO(exit, rc = -ENOMEM); + + buf_len = PAGE_SIZE; + KML_BUF_REC_INIT(buffer, pbuf, buf_len); + rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); + if (rc < 0) + GOTO(exit, rc); + + pbuf += rc; + length += rc; + buf_len -= rc; + /*record new_dentry path*/ + rc = smfs_log_path(dir->i_sb, new_dentry, pbuf, buf_len); + if (rc < 0) + GOTO(exit, rc); + + length += rc; + KML_BUF_REC_END(buffer, length, pbuf); + + rc = smfs_pack_rec(pbuf, dentry, dir, + new_dir, new_dentry, REINT_RENAME); + if (rc <= 0) + GOTO(exit, rc); + length += rc; + + rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); +exit: + if (buffer) + OBD_FREE(buffer, PAGE_SIZE); + RETURN(rc); +} + +static int smfs_insert_extents_ea(struct inode *inode, size_t from, loff_t num) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + int rc = 0; + + if (SMFS_INODE_OVER_WRITE(inode)) + RETURN(rc); + + rc = fsfilt->fs_insert_extents_ea(inode, OFF2BLKS(from, inode), + SIZE2BLKS(num, inode)); + RETURN(rc); +} + +static int smfs_remove_extents_ea(struct inode *inode, size_t from, loff_t num) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + int rc = 0; + + rc = fsfilt->fs_remove_extents_ea(inode, OFF2BLKS(from, inode), + SIZE2BLKS(num, inode)); + + RETURN(rc); +} + +static int smfs_remove_all_extents_ea(struct inode *inode) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + int rc = 0; + + rc = fsfilt->fs_remove_extents_ea(inode, 0, 0xffffffff); + RETURN(rc); +} +static int smfs_init_extents_ea(struct inode *inode) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + int rc = 0; + + rc = fsfilt->fs_init_extents_ea(inode); + + RETURN(rc); +} +static int smfs_set_dirty_flags(struct inode *inode, int flags) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + void *handle; + int rc = 0; + + if (SMFS_INODE_OVER_WRITE(inode)) + RETURN(rc); + /*FIXME later, the blocks needed in journal here will be recalculated*/ + handle = smfs_trans_start(inode, FSFILT_OP_SETATTR, NULL); + if (IS_ERR(handle)) { + CERROR("smfs_set_dirty_flag:no space for transaction\n"); + RETURN(-ENOSPC); + } + if ((!SMFS_INODE_DIRTY_WRITE(inode) && (!SMFS_INODE_OVER_WRITE(inode))) || + ((flags == SMFS_OVER_WRITE) && (SMFS_INODE_DIRTY_WRITE(inode)))) { + rc = fsfilt->fs_set_xattr(inode, handle, REINT_EXTENTS_FLAGS, + &flags, sizeof(int)); + if (rc) + GOTO(out, rc); + } + if (flags == SMFS_OVER_WRITE) + SMFS_SET_INODE_OVER_WRITE(inode); + else + SMFS_SET_INODE_DIRTY_WRITE(inode); +out: + smfs_trans_commit(inode, handle, 0); + RETURN(rc); +} + +int smfs_post_rec_setattr(struct inode *inode, struct dentry *dentry, + void *data1, void *data2) +{ + struct smfs_super_info *sinfo; + struct iattr *attr = (struct iattr *)data1; + char *buffer = NULL, *pbuf; + int rc = 0, length = 0, buf_len = 0; + + sinfo = S2SMI(inode->i_sb); + if (!sinfo) + RETURN(-EINVAL); + + OBD_ALLOC(buffer, PAGE_SIZE); + if (!buffer) + GOTO(exit, rc = -ENOMEM); + + buf_len = PAGE_SIZE; + KML_BUF_REC_INIT(buffer, pbuf, buf_len); + rc = smfs_log_path(inode->i_sb, dentry, pbuf, buf_len); + if (rc < 0) + GOTO(exit, rc); + + length = rc; + KML_BUF_REC_END(buffer, length, pbuf); + + rc = smfs_pack_rec(pbuf, dentry, inode, + data1, data2, REINT_SETATTR); + if (rc <= 0) + GOTO(exit, rc); + else + length += rc; + + rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); + if (!rc) { + if (attr && attr->ia_valid & ATTR_SIZE) { + smfs_remove_extents_ea(inode, attr->ia_size, + 0xffffffff); + if (attr->ia_size == 0) + smfs_set_dirty_flags(inode, SMFS_OVER_WRITE); + else + smfs_set_dirty_flags(inode, SMFS_DIRTY_WRITE); + } + } +exit: + if (buffer) + OBD_FREE(buffer, PAGE_SIZE); + RETURN(rc); +} + +static int all_blocks_present_ea(struct inode *inode) +{ + int rc = 0; + + RETURN(rc); +} +int smfs_post_rec_write(struct inode *dir, struct dentry *dentry, void *data1, + void *data2) +{ + struct smfs_super_info *sinfo; + char *buffer = NULL, *pbuf; + int rc = 0, length = 0, buf_len = 0; + + if (!SMFS_INODE_OVER_WRITE(dentry->d_inode) && + !SMFS_INODE_DIRTY_WRITE(dentry->d_inode)) { + sinfo = S2SMI(dentry->d_inode->i_sb); + if (!sinfo) + RETURN(-EINVAL); + + OBD_ALLOC(buffer, PAGE_SIZE); + if (!buffer) + GOTO(exit, rc = -ENOMEM); + + buf_len = PAGE_SIZE; + KML_BUF_REC_INIT(buffer, pbuf, buf_len); + rc = smfs_log_path(dir->i_sb, dentry, pbuf, buf_len); + + if (rc < 0) + GOTO(exit, rc); + pbuf += rc; + memcpy(buffer, &rc, sizeof(int)); + length = rc + sizeof(int); + + rc = smfs_pack_rec(pbuf, dentry, dir, + data1, data2, REINT_WRITE); + if (rc <= 0) + GOTO(exit, rc); + else + length += rc; + + rc = smfs_llog_add_rec(sinfo, (void*)buffer, length); + if (rc) + GOTO(exit, rc); + rc = smfs_init_extents_ea(dentry->d_inode); + if (rc) + GOTO(exit, rc); + } + if (dentry->d_inode->i_size == 0) { + smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE); + } else { + /*insert extent EA*/ + loff_t off = *((loff_t*)data1); + size_t count = *((size_t*)data2); + + rc = smfs_insert_extents_ea(dentry->d_inode, off, count); + if (rc < 0) + GOTO(exit, rc); + if (all_blocks_present_ea(dentry->d_inode)){ + smfs_set_dirty_flags(dentry->d_inode, SMFS_OVER_WRITE); + smfs_remove_all_extents_ea(dentry->d_inode); + } else { + smfs_set_dirty_flags(dentry->d_inode, SMFS_DIRTY_WRITE); + } + } +exit: + if (buffer) + OBD_FREE(buffer, PAGE_SIZE); + RETURN(rc); +} + +typedef int (*post_kml_rec)(struct inode *dir, struct dentry *dentry, + void *data1, void *data2); + +static post_kml_rec smfs_kml_post[HOOK_MAX + 1] = { + [HOOK_CREATE] smfs_post_rec_create, + [HOOK_LOOKUP] NULL, + [HOOK_LINK] smfs_post_rec_link, + [HOOK_UNLINK] smfs_post_rec_unlink, + [HOOK_SYMLINK] smfs_post_rec_create, + [HOOK_MKDIR] smfs_post_rec_create, + [HOOK_RMDIR] smfs_post_rec_unlink, + [HOOK_MKNOD] smfs_post_rec_create, + [HOOK_RENAME] smfs_post_rec_rename, + [HOOK_SETATTR] smfs_post_rec_setattr, + [HOOK_WRITE] smfs_post_rec_write, +}; +static int smfs_post_kml_rec(struct inode *dir, void *de, void *data1, + void *data2, int op) +{ + if (smfs_kml_post[op]) { + struct dentry *dentry = (struct dentry *)de; + + return smfs_kml_post[op](dir, dentry, data1, data2); + } + return 0; +} diff --git a/lustre/smfs/mds_kml.c b/lustre/smfs/mds_kml.c index 32d1bb356cd4e8ee43c6457810c9aa303abd5995..8238b4c8cc2b5074852f087896c1930ca2d270a7 100644 --- a/lustre/smfs/mds_kml.c +++ b/lustre/smfs/mds_kml.c @@ -156,7 +156,7 @@ static int mds_rec_create_pack(char *buffer, struct dentry *dentry, dentry->d_inode->i_mode, data1, tgt_len); rec = (struct mds_rec_create *)lustre_msg_buf(msg, 0, 0); - + rec->cr_replayfid = op_data.fid2; rec->cr_flags |= REC_REINT_CREATE; mkpi->mpi_total_size = tmp - (void*)msg; @@ -248,10 +248,9 @@ int mds_rec_pack(char *buffer, struct dentry *dentry, struct inode *dir, return mds_kml_pack[op](buffer, dentry, dir, data1, data2); } -int mds_rec_pack_init(struct super_block *sb) +int mds_rec_pack_init(struct smfs_super_info *smsi) { - struct smfs_super_info *smsi = S2SMI(sb); - + smsi->smsi_pack_rec[PACK_MDS] = mds_rec_pack; return 0; diff --git a/lustre/smfs/ost_kml.c b/lustre/smfs/ost_kml.c index 3e8d81705fda4fc21ff760da71b1b41f5a54b0ee..c334affa02c861e0f27d966975919daeca1bbe66 100644 --- a/lustre/smfs/ost_kml.c +++ b/lustre/smfs/ost_kml.c @@ -183,9 +183,8 @@ int ost_rec_pack(char *buffer, struct dentry *dentry, struct inode *dir, return 0; } -int ost_rec_pack_init(struct super_block *sb) +int ost_rec_pack_init(struct smfs_super_info *smsi) { - struct smfs_super_info *smsi = S2SMI(sb); smsi->smsi_pack_rec[PACK_OST] = ost_rec_pack; diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c index 8505482aa3b378804ebbf1f71bd628833c6ad52b..f02e7a7b9a1c7acc38dfc08b834719a9bc3876d7 100644 --- a/lustre/smfs/smfs_cow.c +++ b/lustre/smfs/smfs_cow.c @@ -313,6 +313,7 @@ static int smfs_init_snap_info(struct smfs_super_info *smb, if (rc < 0) { if (rc == -ENODATA) { snap_table->sntbl_count = 0; + rc = 0; } else { CERROR("Can not retrive the snaptable from this filesystem\n"); GOTO(exit, rc); @@ -351,25 +352,27 @@ static struct snap_info *smfs_create_snap_info(struct smfs_super_info *sinfo, RETURN(ERR_PTR(-ENOMEM)); rc = smfs_init_snap_info(sinfo, snap_info, dentry); if (rc) - GOTO(exit, snap_info = ERR_PTR(rc)); + GOTO(exit, rc); /*set cow flags for the snap root inode*/ I2SMI(dentry->d_inode)->smi_flags |= SM_DO_COW; I2SNAPI(dentry->d_inode)->sn_root_ino = dentry->d_inode->i_ino; exit: - if (rc) + if (rc) { OBD_FREE(snap_info, sizeof(struct snap_info)); + snap_info = ERR_PTR(rc); + } RETURN(snap_info); } -static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, +static int smfs_cow_pre(struct inode *dir, void *dentry, void *new_dir, void *new_dentry, int op); -static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir, +static int smfs_cow_post(struct inode *dir, void *dentry, void *new_dir, void *new_dentry, int op); #define COW_HOOK "cow_hook" -static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry, - void *data1, void *data2, int op, void *handle) +static int smfs_cow_pre_hook(struct inode *inode, void *dentry, void *data1, + void *data2, int op, void *handle) { int rc = 0; ENTRY; @@ -385,8 +388,8 @@ static int smfs_cow_pre_hook(struct inode *inode, struct dentry *dentry, } RETURN(rc); } -static int smfs_cow_post_hook(struct inode *inode, struct dentry *dentry, - void *data1, void *data2, int op, void *handle) +static int smfs_cow_post_hook(struct inode *inode, void *dentry, void *data1, + void *data2, int op, void *handle) { int rc = 0; ENTRY; @@ -880,11 +883,11 @@ int snap_do_cow(struct inode *inode, struct dentry *dparent, int del) RETURN(0); } /*Dir inode will do cow*/ -int smfs_cow_create(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) +int smfs_cow_create_pre(struct inode *dir, void *de, void *data1, void *data2) { - int rc = 0; struct dentry *dparent; + struct dentry *dentry = (struct dentry *)de; + int rc = 0; ENTRY; if (smfs_needs_cow(dir) != -1) { @@ -899,9 +902,9 @@ int smfs_cow_create(struct inode *dir, struct dentry *dentry, RETURN(rc); } -int smfs_cow_setattr(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) +int smfs_cow_setattr_pre(struct inode *dir, void *de, void *data1, void *data2) { + struct dentry *dentry = (struct dentry *)de; int rc = 0; ENTRY; if (smfs_needs_cow(dir) != -1) { @@ -914,11 +917,11 @@ int smfs_cow_setattr(struct inode *dir, struct dentry *dentry, RETURN(rc); } -int smfs_cow_link(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) +int smfs_cow_link_pre(struct inode *dir, void *de, void *data1, void *data2) { - int rc = 0; struct dentry *dparent; + struct dentry *dentry = (struct dentry *)de; + int rc = 0; ENTRY; if (smfs_needs_cow(dir) != -1) { @@ -937,9 +940,9 @@ int smfs_cow_link(struct inode *dir, struct dentry *dentry, RETURN(rc); } -int smfs_cow_unlink(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) +int smfs_cow_unlink_pre(struct inode *dir, void *de, void *data1, void *data2) { + struct dentry *dentry = (struct dentry *)de; struct dentry *dparent; int rc = 0; ENTRY; @@ -961,9 +964,9 @@ int smfs_cow_unlink(struct inode *dir, struct dentry *dentry, RETURN(rc); } -int smfs_cow_rename(struct inode *dir, struct dentry *dentry, - void *data1, void *data2) +int smfs_cow_rename_pre(struct inode *dir, void *de, void *data1, void *data2) { + struct dentry *dentry = (struct dentry*)de; struct inode *new_dir = (struct inode *)data1; struct dentry *new_dentry = (struct dentry *)data2; struct dentry *dparent; @@ -1004,9 +1007,9 @@ int smfs_cow_rename(struct inode *dir, struct dentry *dentry, RETURN(rc); } -int smfs_cow_write(struct inode *inode, struct dentry *dentry, void *data1, - void *data2) +int smfs_cow_write_pre(struct inode *inode, void *de, void *data1, void *data2) { + struct dentry *dentry = (struct dentry*)de; struct snap_info *snap_info = NULL; struct snap_table *table; long blocks[2]={-1,-1}; @@ -1084,7 +1087,7 @@ exit: up(&inode->i_sem); RETURN(rc); } -EXPORT_SYMBOL(smfs_cow_write); +EXPORT_SYMBOL(smfs_cow_write_pre); /*lookup inode in dotsnap inode */ static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry, struct snap_info *snap_info) @@ -1141,12 +1144,13 @@ static int smfs_dotsnap_lookup(struct inode *dir, struct dentry *dentry, } RETURN(0); } -int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1, - void *data2) +int smfs_cow_lookup_pre(struct inode *inode, void *de, void *data1, + void *data2) { + struct dentry *dentry = (struct dentry*)de; struct snap_info *snap_info; struct snap_dot_info *dot_info; - int rc = 0, index = 0; + int rc = 0; ENTRY; snap_info = smfs_find_snap_info(inode); @@ -1157,11 +1161,6 @@ int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1, dot_info = snap_info->sni_dot_info; - LASSERT(dot_info != NULL); - LASSERT(data1 != NULL); - - index = *(int *)data1; - if (smfs_primary_inode(inode) && dentry->d_name.len == dot_info->dot_name_len && memcmp(dentry->d_name.name, dot_info->dot_name, @@ -1174,15 +1173,15 @@ int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1, d_add(dentry, dot_inode); rc = 1; RETURN(rc); - } - if (smfs_dotsnap_inode(inode)) { + } else if (smfs_dotsnap_inode(inode)) { rc = smfs_dotsnap_lookup(inode, dentry, snap_info); if (rc == 0) rc = 1; RETURN(rc); - } - if (index > 0) { - /*HERE: will replace ino in dentry->d_name according to index*/ + } else { + /*HERE: will replace ino in dentry->d_name according to index, + *For iopen, will fix it in integrating snapfs to Lustre*/ +#if 0 struct fsfilt_operations *snapops = I2SNAPOPS(inode); char *name = (char *)dentry->d_name.name; unsigned long ino, hash, ind_ino; @@ -1202,7 +1201,8 @@ int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1, hash = partial_name_hash(c, hash); } dentry->d_name.hash = end_name_hash(hash); - } +#endif + } RETURN(rc); } @@ -1243,25 +1243,90 @@ struct inode *smfs_cow_get_ind(struct inode *inode, int index) } EXPORT_SYMBOL(smfs_cow_get_ind); -typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry, - void *new_dir, void *new_dentry); +static int smfs_cow_readdir_pre(struct inode *dir, void *de, void *data1, + void *data2) +{ + struct file *filp = (struct file*)de; + void *dirent = data1; + filldir_t filldir = (filldir_t)data2; + struct snap_info *snap_info = NULL; + + if (smfs_under_dotsnap_inode(dir)) + RETURN(0); + + snap_info = smfs_find_snap_info(dir); + + if (!snap_info) { + CDEBUG(D_INFO, "can not find snap info for ino %lu\n", + dir->i_ino); + RETURN(-EINVAL); + } + + if (smfs_primary_inode(dir)) { + if (filp->f_pos == 0) { + struct snap_dot_info *dot = snap_info->sni_dot_info; + if (filldir(dirent, dot->dot_name, dot->dot_name_len, + filp->f_pos, -1, 0)) { + CERROR("fill .snap error \n"); + RETURN(-EINVAL); + } + } else { + filp->f_pos -= 1; + } + } else if (smfs_dotsnap_inode(dir)) { + struct snap_table *table = snap_info->sni_table; + int i = 0; + + if (filp->f_pos < 0) + RETURN(-EINVAL); + + if ((filp->f_pos == 0) && filldir(dirent, ".", 1, + filp->f_pos++, + dir->i_ino, 0) < 0) + RETURN(-EIO); + if ((filp->f_pos == 1) && filldir(dirent, "..", 2, + filp->f_pos++, + dir->i_ino, 0) < 0) + RETURN(-EIO); + + for (i = filp->f_pos - 2; i < table->sntbl_count; i++, + filp->f_pos++) { + int slot = table->sntbl_count-i; + + if (filldir(dirent, table->sntbl_items[slot].sn_name, + strlen(table->sntbl_items[slot].sn_name), + filp->f_pos, dir->i_ino, 0)) + break; + + } + RETURN(1); + } + + RETURN(0); +} + + +typedef int (*cow_funcs)(struct inode *dir, void *dentry, void *new_dir, + void *new_dentry); static cow_funcs smfs_cow_pre_funcs[HOOK_MAX + 1] = { - [HOOK_CREATE] smfs_cow_create, - [HOOK_LOOKUP] smfs_cow_lookup, - [HOOK_LINK] smfs_cow_link, - [HOOK_UNLINK] smfs_cow_unlink, - [HOOK_SYMLINK] smfs_cow_create, - [HOOK_MKDIR] smfs_cow_create, - [HOOK_RMDIR] smfs_cow_unlink, - [HOOK_MKNOD] smfs_cow_create, - [HOOK_RENAME] smfs_cow_rename, - [HOOK_SETATTR] smfs_cow_setattr, - [HOOK_WRITE] smfs_cow_write, + [HOOK_CREATE] smfs_cow_create_pre, + [HOOK_LOOKUP] smfs_cow_lookup_pre, + [HOOK_LINK] smfs_cow_link_pre, + [HOOK_UNLINK] smfs_cow_unlink_pre, + [HOOK_SYMLINK] smfs_cow_create_pre, + [HOOK_MKDIR] smfs_cow_create_pre, + [HOOK_RMDIR] smfs_cow_unlink_pre, + [HOOK_MKNOD] smfs_cow_create_pre, + [HOOK_RENAME] smfs_cow_rename_pre, + [HOOK_SETATTR] smfs_cow_setattr_pre, + [HOOK_WRITE] smfs_cow_write_pre, + [HOOK_READDIR] smfs_cow_readdir_pre, }; -int smfs_cow_lookup_post(struct inode *dir, struct dentry *dentry, void *data1, +int smfs_cow_lookup_post(struct inode *dir, void *de, void *data1, void *data2) { + struct dentry *dentry = (struct dentry*)de; struct inode *inode = dentry->d_inode; struct fsfilt_operations *sops = I2SNAPCOPS(inode); int index = I2SNAPI(dir)->sn_index; @@ -1291,6 +1356,18 @@ int smfs_cow_lookup_post(struct inode *dir, struct dentry *dentry, void *data1, RETURN(0); } +static int smfs_cow_readdir_post(struct inode *dir, void *de, void *data1, + void *data2) +{ + struct file *filp = (struct file*)de; + + if (smfs_primary_inode(dir)) { + filp->f_pos += 1; + } + RETURN(0); +} + + static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = { [HOOK_CREATE] NULL, [HOOK_LOOKUP] smfs_cow_lookup_post, @@ -1303,9 +1380,10 @@ static cow_funcs smfs_cow_post_funcs[HOOK_MAX + 1] = { [HOOK_RENAME] NULL, [HOOK_SETATTR] NULL, [HOOK_WRITE] NULL, + [HOOK_READDIR] smfs_cow_readdir_post, }; -static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, +static int smfs_cow_pre(struct inode *dir, void *dentry, void *new_dir, void *new_dentry, int op) { if (smfs_cow_pre_funcs[op]) { @@ -1314,7 +1392,7 @@ static int smfs_cow_pre(struct inode *dir, struct dentry *dentry, void *new_dir, return 0; } -static int smfs_cow_post(struct inode *dir, struct dentry *dentry, void *new_dir, +static int smfs_cow_post(struct inode *dir, void *dentry, void *new_dir, void *new_dentry, int op) { if (smfs_cow_post_funcs[op]) { diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h index fa8dcd0f11876692d2f4b5bf8a1fd314f109fc04..be44d54906e18604dfea9fa878820e9a608d90f7 100644 --- a/lustre/smfs/smfs_internal.h +++ b/lustre/smfs/smfs_internal.h @@ -169,11 +169,8 @@ struct smfs_iget_args { extern struct inode_operations smfs_sym_iops; extern struct file_operations smfs_sym_fops; /*journal.c */ -extern void *smfs_trans_start(struct inode *inode, int op, void *desc_private); -extern void smfs_trans_commit(struct inode *inode, void *handle, - int force_sync); -extern int smfs_post_kml_rec(struct inode *dir, struct dentry *dst_dentry, - void *data1, void *data2, int op); +void *smfs_trans_start(struct inode *inode, int op, void *desc_private); +void smfs_trans_commit(struct inode *inode, void *handle, int force_sync); extern int smfs_post_rec_write(struct inode *dir, struct dentry *dentry, void *data1, void *data2); @@ -190,13 +187,11 @@ extern int smfs_rec_unpack(struct smfs_proc_args *args, char *record, char **pbuf, int *opcode); extern int smfs_process_rec(struct super_block *sb, int count, char *dir, int flags); -extern smfs_pack_rec_func smfs_get_rec_pack_type(struct super_block *sb); - /*mds_kml.c*/ -int mds_rec_pack_init(struct super_block *sb); +int mds_rec_pack_init(struct smfs_super_info *smb); /*ost_kml.c*/ -int ost_rec_pack_init(struct super_block *sb); +int ost_rec_pack_init(struct smfs_super_info *smb); /*smfs_llog.c*/ extern int smfs_llog_setup(struct super_block *sb, struct vfsmount *mnt); @@ -292,7 +287,8 @@ static inline int get_active_entry(struct inode *dir, __u64 *active_entry) #define HOOK_RENAME 9 #define HOOK_SETATTR 10 #define HOOK_WRITE 11 -#define HOOK_MAX 11 +#define HOOK_READDIR 12 +#define HOOK_MAX 12 #define PRE_HOOK 0 #define POST_HOOK 1 diff --git a/lustre/smfs/smfs_lib.c b/lustre/smfs/smfs_lib.c index f0a23b5a7e2b794276239671bca70e3dba8676e2..05d172c5f464e8de5d860d94e46048dfa58e12b4 100644 --- a/lustre/smfs/smfs_lib.c +++ b/lustre/smfs/smfs_lib.c @@ -417,3 +417,31 @@ struct smfs_hook_ops *smfs_unregister_hook_ops(struct smfs_super_info *smb, RETURN(NULL); } +void *smfs_trans_start(struct inode *inode, int op, void *desc_private) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + + CDEBUG(D_INFO, "trans start %p\n", fsfilt->fs_start); + + SMFS_TRANS_OP(inode, op); + + /* There are some problem here. fs_start in fsfilt is used by lustre + * the journal blocks of write rec are not counted in FIXME later */ + if (fsfilt->fs_start) + return fsfilt->fs_start(inode, op, desc_private, 0); + return NULL; +} + +void smfs_trans_commit(struct inode *inode, void *handle, int force_sync) +{ + struct fsfilt_operations *fsfilt = S2SMI(inode->i_sb)->sm_fsfilt; + + if (!handle) + return; + + CDEBUG(D_INFO, "trans commit %p\n", fsfilt->fs_commit); + + if (fsfilt->fs_commit) + fsfilt->fs_commit(inode->i_sb, inode, handle, force_sync); +} +