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;
};
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);
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 ++;
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@
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;
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);
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);
}
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));
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)
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;
}
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);
+++ /dev/null
-/* -*- 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;
-}
#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);
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;
}
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;
+}
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;
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;
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;
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);
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;
}
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;
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) {
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) {
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) {
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;
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;
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};
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)
}
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);
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,
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;
hash = partial_name_hash(c, hash);
}
dentry->d_name.hash = end_name_hash(hash);
- }
+#endif
+ }
RETURN(rc);
}
}
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;
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,
[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]) {
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]) {
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);
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);
#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
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);
+}
+