int (* fs_read_record)(struct file *, void *, int size, loff_t *);
int (* fs_setup)(struct obd_device *, struct super_block *);
- int (* fs_post_setup)(struct obd_device *obd, struct vfsmount *mnt);
+ int (* fs_post_setup)(struct obd_device *obd, struct vfsmount *mnt,
+ struct dentry *dentry);
int (* fs_post_cleanup)(struct obd_device *obd, struct vfsmount *mnt);
int (* fs_get_reint_log_ctxt)(struct super_block *sb,
struct llog_ctxt **ctxt);
int (* fs_set_indirect)(struct inode *pri, int index,
ino_t ind_ino, ino_t parent_ino);
int (* fs_snap_feature)(struct super_block *sb, int feature, int op);
- int (* fs_set_snap_info)(struct super_block *sb, struct inode *inode,
- void* key, __u32 keylen, void *val,
- __u32 *vallen);
- int (* fs_get_snap_info)(struct super_block *sb, struct inode *inode,
- void* key, __u32 keylen, void *val,
- __u32 *vallen);
+ int (* fs_set_snap_info)(struct inode *inode, void* key, __u32 keylen,
+ void *val, __u32 *vallen);
+ int (* fs_get_snap_info)(struct inode *inode, void* key, __u32 keylen,
+ void *val, __u32 *vallen);
int (* fs_set_snap_item)(struct super_block *sb, char *name);
};
}
static inline int
-fsfilt_post_setup(struct obd_device *obd)
+fsfilt_post_setup(struct obd_device *obd, struct dentry *de)
{
if (obd->obd_fsops->fs_post_setup)
return obd->obd_fsops->fs_post_setup(obd,
- obd->obd_lvfs_ctxt.pwdmnt);
+ obd->obd_lvfs_ctxt.pwdmnt, de);
return 0;
}
extern void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r);
+#define CLONE_INFO_MAGIC 0x0218
struct clonefs_info {
+ int clone_magic;
int clone_index;
int clone_flags;
};
struct snap_info {
struct fsfilt_operations *snap_fsfilt;
- struct fsfilt_operations *snap_cache_fsfilt;
+ struct fsfilt_operations *snap_cache_fsfilt;
+ struct dentry *snap_root;
struct semaphore sntbl_sema;
spinlock_t sntbl_lock;
struct snap_table *sntbl;
RETURN(0);
if (sbi->ll_mdc_exp) {
- struct obd_import *climp = class_exp2cliimp(sbi->ll_mdc_exp);
- struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+ struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp);
+ struct client_obd *cl_obd = &obd->u.cli;
OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
if (!cl_obd->cl_clone_info)
RETURN(-ENOMEM);
SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index);
SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS);
+ cl_obd->cl_clone_info->cl_clone_info->clone_magic =
+ cpu_to_le32(CLONE_INFO_MAGI);
}
if (sbi->ll_osc_exp) {
- struct obd_import *climp = class_exp2cliimp(sbi->ll_osc_exp);
- struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+ struct obd_device *obd = class_exp2obd(sbi->ll_osc_exp);
+ struct client_obd *cl_obd = &obd->u.cli;
OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
if (!cl_obd->cl_clone_info)
RETURN(-ENOMEM);
SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index);
SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS);
+ cl_obd->cl_clone_info->cl_clone_info->clone_magic =
+ cpu_to_le32(CLONE_INFO_MAGI);
}
RETURN(0);
}
ENTRY;
if (sbi->ll_mdc_exp) {
- struct obd_import *climp = class_exp2cliimp(sbi->ll_mdc_exp);
- struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+ struct obd_device *obd = class_exp2obd(sbi->ll_mdc_exp);
+ struct client_obd *cl_obd = &obd->u.cli;
if (!cl_obd->cl_clone_info)
RETURN(0);
}
if (sbi->ll_osc_exp) {
- struct obd_import *climp = class_exp2cliimp(sbi->ll_osc_exp);
- struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+ struct obd_device *obd = class_exp2obd(sbi->ll_osc_exp);
+ struct client_obd *cl_obd = &obd->u.cli;
if (!cl_obd->cl_clone_info)
RETURN(0);
RETURN(rc);
}
-static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt)
+static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
+ struct dentry *root_dentry)
{
struct super_block *sb = NULL;
int rc = 0;
if (SMFS_DO_REC(S2SMI(sb)))
rc = smfs_start_rec(sb, mnt);
#if CONFIG_SNAPFS
- if (SMFS_DO_COW(S2SMI(sb)))
- rc = smfs_start_cow(sb);
+ if (SMFS_DO_COW(S2SMI(sb))) {
+ S2SNAPI(sb)->snap_root = root_dentry;
+ rc = smfs_start_cow(sb);
+ }
#endif
if (rc)
GOTO(exit, rc);
struct inode* parent,
int del)
{
- struct inode *ind;
+ struct inode *ind = NULL;
handle_t *handle = NULL;
int err = 0;
int has_orphan = 0;
if( pri == pri->i_sb->u.ext3_sb.s_journal_inode ){
CERROR("TRY TO COW JOUNRAL\n");
- RETURN(NULL);
+ RETURN(ERR_PTR(-EINVAL));
}
CDEBUG(D_INODE, "creating indirect inode for %lu at index %d, %s pri\n",
pri->i_ino, index, del ? "deleting" : "preserve");
ind = fsfilt_ext3_get_indirect(pri, NULL, index);
handle = ext3_journal_start(pri, SNAP_CREATEIND_TRANS_BLOCKS);
- if( !handle )
- RETURN(NULL);
+ if( !handle ) {
+ CERROR("handle not NULL\n");
+ RETURN(ERR_PTR(-EINVAL));
+ }
/* XXX ? We should pass an err argument to get_indirect and precisely
* detect the errors, for some errors, we should exit right away.
*/
if (ind && !IS_ERR(ind)) {
CDEBUG(D_INODE, "existing indirect ino %lu for %lu: index %d\n",
ind->i_ino, pri->i_ino, index);
+
GOTO(exit, err=0);
- }
- /* XXX: check this, ext3_new_inode, the first arg should be "dir" */
+ }
+
+ /* XXX: check this, ext3_new_inode, the first arg should be "dir" */
ind = ext3_new_inode(handle, pri, (int)pri->i_mode, 0);
if (IS_ERR(ind))
GOTO(exit, err);
}
iput(ind);
ext3_journal_stop(handle, pri);
- if (err)
- CERROR("exiting with error %d\n", err);
- RETURN(NULL);
+
+ RETURN(ERR_PTR(err));
}
static int fsfilt_ext3_snap_feature (struct super_block *sb, int feature, int op) {
}
}
-static int fsfilt_ext3_get_snap_info(struct super_block *sb,struct inode *inode,
- void *key, __u32 keylen, void *val,
+static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key,
+ __u32 keylen, void *val,
__u32 *vallen)
{
int rc = 0;
RETURN(rc);
} else if (keylen >= strlen(SNAPTABLE_INFO)
&& strcmp(key, SNAPTABLE_INFO) == 0) {
- rc = ext3_xattr_get(sb->s_root->d_inode, EXT3_SNAP_INDEX,
+ rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX,
EXT3_SNAPTABLE_EA, val, *vallen);
RETURN(rc);
} else if (keylen >= strlen(SNAP_GENERATION)
RETURN(-EINVAL);
}
-static int fsfilt_ext3_set_snap_info(struct super_block *sb,struct inode *inode,
- void *key, __u32 keylen, void *val,
+static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key,
+ __u32 keylen, void *val,
__u32 *vallen)
{
int rc = 0;
if (keylen >= strlen(SNAPTABLE_INFO)
&& strcmp(key, SNAPTABLE_INFO) == 0) {
- struct inode *root_inode = sb->s_root->d_inode;
handle_t *handle;
- handle = ext3_journal_start(root_inode, EXT3_XATTR_TRANS_BLOCKS);
+ handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
if( !handle )
RETURN(-EINVAL);
- rc = ext3_xattr_set(handle, root_inode, EXT3_SNAP_INDEX,
+ rc = ext3_xattr_set(handle, inode, EXT3_SNAP_INDEX,
EXT3_SNAPTABLE_EA, val, *vallen, 0);
- ext3_journal_stop(handle,root_inode);
+ ext3_journal_stop(handle, inode);
RETURN(rc);
} else if (keylen >= strlen(SNAP_GENERATION)
RETURN(rc);
}
-static int fsfilt_smfs_set_snap_info(struct super_block *sb,struct inode *inode,
+static int fsfilt_smfs_set_snap_info(struct inode *inode,
void* key, __u32 keylen, void *val,
__u32 *vallen)
{
- struct super_block *csb = NULL;
- struct inode *cache_inode = NULL;
- struct fsfilt_operations *snap_fsfilt = NULL;
- int rc = -EIO;
-
- if (sb) {
- csb = S2CSB(sb);
- snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt;
- } else if (inode) {
- cache_inode = I2CI(inode);
- snap_fsfilt = I2SNAPCOPS(inode);
- }
+ struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
+ struct inode *cache_inode = NULL;
+ int rc = -EIO;
+
if (snap_fsfilt == NULL)
RETURN(rc);
+ cache_inode = I2CI(inode);
+ if (!cache_inode)
+ RETURN(rc);
+
+ pre_smfs_inode(inode, cache_inode);
+
if (snap_fsfilt->fs_set_snap_info)
- rc = snap_fsfilt->fs_set_snap_info(csb, cache_inode, key,
+ rc = snap_fsfilt->fs_set_snap_info(cache_inode, key,
keylen, val, vallen);
-
+ post_smfs_inode(inode, cache_inode);
+
RETURN(rc);
}
-static int fsfilt_smfs_get_snap_info(struct super_block *sb, struct inode *inode,
- void *key, __u32 keylen, void *val,
- __u32 *vallen)
+static int fsfilt_smfs_get_snap_info(struct inode *inode, void *key,
+ __u32 keylen, void *val, __u32 *vallen)
{
- struct super_block *csb = NULL;
- struct inode *cache_inode = NULL;
- struct fsfilt_operations *snap_fsfilt = NULL;
+ struct fsfilt_operations *snap_fsfilt = I2SNAPCOPS(inode);
+ struct inode *cache_inode = NULL;
int rc = -EIO;
- if (sb) {
- csb = S2CSB(sb);
- snap_fsfilt = S2SNAPI(sb)->snap_cache_fsfilt;
- } else if (inode) {
- cache_inode = I2CI(inode);
- snap_fsfilt = I2SNAPCOPS(inode);
- }
-
if (snap_fsfilt == NULL)
RETURN(rc);
-
+
+ cache_inode = I2CI(inode);
+ if (!cache_inode)
+ RETURN(rc);
+
if (snap_fsfilt->fs_get_snap_info)
- rc = snap_fsfilt->fs_get_snap_info(csb, cache_inode, key,
+ rc = snap_fsfilt->fs_get_snap_info(cache_inode, key,
keylen, val, vallen);
-
+
RETURN(rc);
}
struct fsfilt_operations fsfilt_smfs_snap_ops = {
}
#if CONFIG_SNAPFS
-int mdc_set_clone_info(struct obd_import *climp, struct lustre_msg *msg,
+int mdc_set_clone_info(struct obd_export *exp, struct lustre_msg *msg,
int offset)
{
- struct client_obd *cli_obd = &climp->imp_obd->u.cli;
+ struct client_obd *cli_obd = &exp->exp_obd->u.cli;
struct clonefs_info *cl_info;
ENTRY;
-
- cl_info = (struct clonefs_info *)lustre_msg_buf(msg, offset,
- sizeof (*cl_info));
- memcpy(cl_info, cli_obd->cl_clone_info, sizeof(*cl_info));
+
+ if (cli_obd->cl_clone_info) {
+ cl_info = (struct clonefs_info *)lustre_msg_buf(msg, offset,
+ sizeof (*cl_info));
+ memcpy(cl_info, cli_obd->cl_clone_info, sizeof(*cl_info));
+ }
RETURN(0);
}
#endif
/* pack the intended request */
mdc_getattr_pack(req->rq_reqmsg, valid, 2, it->it_flags, data);
#if CONFIG_SNAPFS
- mdc_set_clone_info(class_exp2cliimp(exp), req->rq_reqmsg, 4);
+ mdc_set_clone_info(exp, req->rq_reqmsg, 4);
#endif
/* get ready for the reply */
reply_buffers = 3;
req->rq_replen = lustre_msg_size(3, repsize);
} else if (it->it_op == IT_READDIR) {
policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
-#if CONFIG_SNAPFS
- size[1] = sizeof(struct clonefs_info);
- req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 2,
- size, NULL);
-#else
req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 1,
size, NULL);
-#endif
if (!req)
RETURN(-ENOMEM);
-#if CONFIG_SNAPFS
- mdc_set_clone_info(class_exp2cliimp(exp), req->rq_reqmsg, 1);
-#endif
/* get ready for the reply */
reply_buffers = 1;
req->rq_replen = lustre_msg_size(1, repsize);
struct dentry *de = mds_fid2dentry(mds, &mds->mds_rootfid, NULL);
int rc = 0;
- rc = fsfilt_post_setup(obd);
+ rc = fsfilt_post_setup(obd, de);
if (rc)
GOTO(out, rc);
int rc = 0, j = 0;
struct llog_ctxt *ctxt = NULL;
- rc = fsfilt_post_setup(obd);
+ rc = fsfilt_post_setup(obd, filter->fo_dentry_O);
if (rc)
RETURN(rc);
if (!cache_dir && cache_dir->i_op->lookup)
GOTO(exit, rc = ERR_PTR(-ENOENT));
- SMFS_PRE_COW(dir, dentry, NULL, NULL, SNAP_LOOKUP, "lookup", rc, exit);
+ SMFS_PRE_COW(dir, dentry, NULL, NULL, SNAP_LOOKUP, "lookup", rc2, exit);
/* perform lookup in backing fs. */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
if (rc && IS_ERR(rc))
GOTO(exit, rc);
-
+
if ((cache_inode = rc ? rc->d_inode : cache_dentry->d_inode)) {
if (IS_ERR(cache_inode)) {
dentry->d_inode = cache_inode;
struct snap_info *snap_info = S2SNAPI(sb);
struct snap_table *snap_table = NULL;
struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
+ struct dentry *d_root = snap_info->snap_root;
int rc = 0, size, table_size, vallen, i;
ENTRY;
/*Initialized table */
/*get the maxsize of snaptable*/
vallen = sizeof(int);
- rc = snapops->fs_get_snap_info(sb, NULL, MAX_SNAPTABLE_COUNT,
+ rc = snapops->fs_get_snap_info(d_root->d_inode, MAX_SNAPTABLE_COUNT,
strlen(MAX_SNAPTABLE_COUNT), &size,
&vallen);
if (size == 0) {
snap_table->sntbl_items[i].sn_index = -1;
}
/*get snaptable info*/
- rc = snapops->fs_get_snap_info(sb, NULL, SNAPTABLE_INFO,
+ rc = snapops->fs_get_snap_info(d_root->d_inode, SNAPTABLE_INFO,
strlen(SNAPTABLE_INFO),
snap_table, &table_size);
if (rc < 0) {
}
int smfs_start_cow(struct super_block *sb)
{
- struct smfs_super_info *smfs_info = S2SMI(sb);
int rc = 0;
ENTRY;
- OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
-
- if (!smfs_info->smsi_snap_info)
- RETURN(-ENOMEM);
/*init snap fsfilt operations*/
if (!S2SNAPI(sb)->snap_cache_fsfilt) {
table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
OBD_FREE(snap_info->sntbl, table_size);
}
- if (snap_info)
- OBD_FREE(snap_info, sizeof(*snap_info));
RETURN(rc);
}
SMFS_SET_COW(smfs_info);
+ OBD_ALLOC(smfs_info->smsi_snap_info, sizeof(struct snap_info));
+
+ if (!smfs_info->smsi_snap_info)
+ RETURN(-ENOMEM);
+
RETURN(rc);
}
int smfs_cow_cleanup(struct super_block *sb)
{
+
+ struct snap_info *snap_info = S2SNAPI(sb);
+
ENTRY;
SMFS_CLEAN_COW(S2SMI(sb));
+ if (snap_info)
+ OBD_FREE(snap_info, sizeof(*snap_info));
RETURN(0);
}
sni_info->sn_flags = flags;
vallen = sizeof(sni_info->sn_gen);
- rc = snapops->fs_get_snap_info(NULL, inode, SNAP_GENERATION,
+ rc = snapops->fs_get_snap_info(inode, SNAP_GENERATION,
strlen(SNAP_GENERATION),
&sni_info->sn_gen, &vallen);
}
struct snap_info *snap_info = S2SNAPI(sb);
struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
struct snap_table *snap_table = snap_info->sntbl;
+ struct dentry *d_root = snap_info->snap_root;
struct snap *snap_item;
int table_size, count = 0, index = 0, rc = 0;
/* Wrote the whole snap_table to disk */
table_size = SNAPTABLE_SIZE(snap_table->sntbl_max_count);
- rc = snapops->fs_set_snap_info(sb, NULL, SNAPTABLE_INFO,
+ rc = snapops->fs_set_snap_info(d_root->d_inode, SNAPTABLE_INFO,
strlen(SNAPTABLE_INFO),
snap_table, &table_size);
if (rc) {
snap_last(inode->i_sb, &snap);
ind = snapops->fs_create_indirect(inode, snap.sn_index, snap.sn_gen,
dparent->d_inode, del);
- if(!ind)
- RETURN(-EINVAL);
- if (!SMFS_DO_INODE_COWED(inode)) {
- /*insert the inode to cowed inode*/
- SMFS_SET_INODE_COWED(inode);
- link_cowed_inode(inode);
+ if(ind && IS_ERR(ind)) {
+ CERROR("Create ind inode %lu index %d gen %d del %d\n rc%d\n",
+ inode->i_ino, snap.sn_index, snap.sn_gen, del,
+ PTR_ERR(ind));
+ RETURN(PTR_ERR(ind));
+ }
+ if (ind) {
+ if (!SMFS_DO_INODE_COWED(inode)) {
+ /*insert the inode to cowed inode*/
+ SMFS_SET_INODE_COWED(inode);
+ link_cowed_inode(inode);
+ }
+
+ I2SMI(ind)->sm_sninfo.sn_flags = 0;
+ I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen;
+
+ iput(ind);
}
-
- I2SMI(ind)->sm_sninfo.sn_flags = 0;
- I2SMI(ind)->sm_sninfo.sn_gen = snap.sn_gen;
-
- iput(ind);
RETURN(0);
}
/*Dir inode will do cow*/
CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
LASSERT(dentry->d_parent && dentry->d_parent->d_parent);
dparent = dentry->d_parent->d_parent;
- if ((snap_do_cow(dir, dparent, 0))) {
- CERROR("Do cow error\n");
+ if ((rc = snap_do_cow(dir, dparent, 0))) {
+ CERROR("Do cow error %d\n", rc);
RETURN(-EINVAL);
}
}