From 2988bc1adfe31b41de0dbee2ebff4a49b193e6e2 Mon Sep 17 00:00:00 2001 From: pschwan Date: Sat, 5 Jul 2003 22:46:51 +0000 Subject: [PATCH] land b_merge on b_devel. Includes b_mount and b_orphan, which includes: - orphans are moved into the PENDING directory for possible recovery - replayed opens now open by fid for orphan/rename safety (1042) - last close of an orphan inode generates a transno (683) - avoid CERROR in normal ll_setattr_raw() error case (1500) Added code which is currently disabled: - dentry pinning from b_mount for cwd and mountpoints (1020) - logging code for orphans (and many other things) --- lustre/cobd/cache_obd.c | 41 ++++++++++----------- lustre/include/linux/lustre_fsfilt.h | 70 ++++++++++++++++++++++++++---------- lustre/obdclass/fsfilt_ext3.c | 38 ++++++++++++++------ lustre/obdclass/fsfilt_reiserfs.c | 13 ++++--- 4 files changed, 104 insertions(+), 58 deletions(-) diff --git a/lustre/cobd/cache_obd.c b/lustre/cobd/cache_obd.c index 5efb545..807d9a3 100644 --- a/lustre/cobd/cache_obd.c +++ b/lustre/cobd/cache_obd.c @@ -82,24 +82,23 @@ cobd_setup (struct obd_device *dev, obd_count len, void *buf) return (0); fail_0: - obd_disconnect (&cobd->cobd_target, 0 ); + obd_disconnect(&cobd->cobd_target, 0); return (rc); } -static int -cobd_cleanup (struct obd_device *dev, int force, int failover) +static int cobd_cleanup(struct obd_device *dev, int flags) { struct cache_obd *cobd = &dev->u.cobd; int rc; - if (!list_empty (&dev->obd_exports)) + if (!list_empty(&dev->obd_exports)) return (-EBUSY); - rc = obd_disconnect (&cobd->cobd_cache, failover); + rc = obd_disconnect(&cobd->cobd_cache, flags); if (rc != 0) CERROR ("error %d disconnecting cache\n", rc); - rc = obd_disconnect (&cobd->cobd_target, failover); + rc = obd_disconnect(&cobd->cobd_target, flags); if (rc != 0) CERROR ("error %d disconnecting target\n", rc); @@ -116,10 +115,9 @@ cobd_connect (struct lustre_handle *conn, struct obd_device *obd, return (rc); } -static int -cobd_disconnect (struct lustre_handle *conn, int failover) +static int cobd_disconnect(struct lustre_handle *conn, int flags) { - int rc = class_disconnect (conn, failover); + int rc = class_disconnect(conn, flags); CERROR ("rc %d\n", rc); return (rc); @@ -210,8 +208,7 @@ cobd_close(struct lustre_handle *conn, struct obdo *oa, static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *obdo, int objcount, struct obd_ioobj *obj, int niocount, struct niobuf_remote *nb, - struct niobuf_local *res, void **desc_private, - struct obd_trans_info *oti) + struct niobuf_local *res, struct obd_trans_info *oti) { struct obd_export *cobd_exp; int rc; @@ -224,15 +221,16 @@ static int cobd_preprw(int cmd, struct obd_export *exp, struct obdo *obdo, cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target); rc = obd_preprw(cmd, cobd_exp, obdo, objcount, obj, niocount, nb, res, - desc_private, oti); + oti); class_export_put(cobd_exp); + return rc; } static int cobd_commitrw(int cmd, struct obd_export *exp, int objcount, struct obd_ioobj *obj, int niocount, struct niobuf_local *local, - void *desc_private, struct obd_trans_info *oti) + struct obd_trans_info *oti) { struct obd_export *cobd_exp; int rc; @@ -244,16 +242,14 @@ static int cobd_commitrw(int cmd, struct obd_export *exp, return -EOPNOTSUPP; cobd_exp = class_conn2export(&exp->exp_obd->u.cobd.cobd_target); - rc = obd_commitrw(cmd, cobd_exp, objcount, obj, niocount, local, - desc_private, oti); + rc = obd_commitrw(cmd, cobd_exp, objcount, obj, niocount, local, oti); class_export_put(cobd_exp); return rc; } -static inline int -cobd_brw(int cmd, struct lustre_handle *conn, - struct lov_stripe_md *lsm, obd_count oa_bufs, - struct brw_page *pga, struct obd_trans_info *oti) +static int cobd_brw(int cmd, struct lustre_handle *conn, + struct lov_stripe_md *lsm, obd_count oa_bufs, + struct brw_page *pga, struct obd_trans_info *oti) { struct obd_device *obd = class_conn2obd(conn); struct cache_obd *cobd; @@ -271,9 +267,8 @@ cobd_brw(int cmd, struct lustre_handle *conn, lsm, oa_bufs, pga, oti)); } -static int -cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, - void *karg, void *uarg) +static int cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, + void *karg, void *uarg) { struct obd_device *obd = class_conn2obd(conn); struct cache_obd *cobd; @@ -286,7 +281,7 @@ cobd_iocontrol(unsigned int cmd, struct lustre_handle *conn, int len, /* intercept? */ cobd = &obd->u.cobd; - return (obd_iocontrol (cmd, &cobd->cobd_target, len, karg, uarg)); + return (obd_iocontrol(cmd, &cobd->cobd_target, len, karg, uarg)); } static struct obd_ops cobd_ops = { diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index fc00fe1..bc342e4 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -30,7 +30,8 @@ #include #include -typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd, int error); +typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd, + void *data, int error); struct fsfilt_objinfo { struct dentry *fso_dentry; @@ -41,9 +42,10 @@ struct fsfilt_operations { struct list_head fs_list; struct module *fs_owner; char *fs_type; - void *(* fs_start)(struct inode *inode, int op); + void *(* fs_start)(struct inode *inode, int op, void *desc_private); void *(* fs_brw_start)(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb); + int niocount, struct niobuf_remote *nb, + void *desc_private); int (* fs_commit)(struct inode *inode, void *handle,int force_sync); int (* fs_setattr)(struct dentry *dentry, void *handle, struct iattr *iattr, int do_trunc); @@ -54,7 +56,8 @@ struct fsfilt_operations { loff_t *offset); int (* fs_journal_data)(struct file *file); int (* fs_set_last_rcvd)(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func); + void *handle, fsfilt_cb_t cb_func, + void *cb_data); int (* fs_statfs)(struct super_block *sb, struct obd_statfs *osfs); int (* fs_sync)(struct super_block *sb); int (* fs_prep_san_write)(struct inode *inode, long *blocks, @@ -63,7 +66,7 @@ struct fsfilt_operations { extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops); extern void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops); -extern struct fsfilt_operations *fsfilt_get_ops(char *type); +extern struct fsfilt_operations *fsfilt_get_ops(const char *type); extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops); #define FSFILT_OP_UNLINK 1 @@ -75,26 +78,54 @@ extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops); #define FSFILT_OP_MKNOD 7 #define FSFILT_OP_SETATTR 8 #define FSFILT_OP_LINK 9 +#define FSFILT_OP_CREATE_LOG 10 +#define FSFILT_OP_UNLINK_LOG 11 -static inline void *fsfilt_start(struct obd_device *obd, - struct inode *inode, int op) +static inline void *fsfilt_start(struct obd_device *obd, struct inode *inode, + int op, struct obd_trans_info *oti) { unsigned long now = jiffies; - void *handle = obd->obd_fsops->fs_start(inode, op); - CDEBUG(D_HA, "started handle %p\n", handle); - if (time_after(jiffies, now + 15*HZ)) + void *parent_handle = oti ? oti->oti_handle : NULL; + void *handle = obd->obd_fsops->fs_start(inode, op, parent_handle); + CDEBUG(D_HA, "started handle %p (%p)\n", handle, parent_handle); + + if (oti != NULL) { + if (parent_handle == NULL) { + oti->oti_handle = handle; + } else if (handle != parent_handle) { + CERROR("mismatch: parent %p, handle %p, oti %p\n", + parent_handle, handle, oti->oti_handle); + LBUG(); + } + } + if (time_after(jiffies, now + 15 * HZ)) CERROR("long journal start time %lus\n", (jiffies - now) / HZ); return handle; } static inline void *fsfilt_brw_start(struct obd_device *obd, int objcount, struct fsfilt_objinfo *fso, int niocount, - struct niobuf_remote *nb) + struct niobuf_remote *nb, + struct obd_trans_info *oti) { unsigned long now = jiffies; - void *handle = obd->obd_fsops->fs_brw_start(objcount, fso, niocount,nb); - CDEBUG(D_HA, "started handle %p\n", handle); - if (time_after(jiffies, now + 15*HZ)) + void *parent_handle = oti ? oti->oti_handle : NULL; + void *handle; + + handle = obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb, + parent_handle); + CDEBUG(D_HA, "started handle %p (%p)\n", handle, parent_handle); + + if (oti != NULL) { + if (parent_handle == NULL) { + oti->oti_handle = handle; + } else if (handle != parent_handle) { + CERROR("mismatch: parent %p, handle %p, oti %p\n", + parent_handle, handle, oti->oti_handle); + LBUG(); + } + } + if (time_after(jiffies, now + 15 * HZ)) CERROR("long journal start time %lus\n", (jiffies - now) / HZ); return handle; } @@ -105,7 +136,7 @@ static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode, unsigned long now = jiffies; int rc = obd->obd_fsops->fs_commit(inode, handle, force_sync); CDEBUG(D_HA, "committing handle %p\n", handle); - if (time_after(jiffies, now + 15*HZ)) + if (time_after(jiffies, now + 15 * HZ)) CERROR("long journal start time %lus\n", (jiffies - now) / HZ); return rc; } @@ -116,9 +147,8 @@ static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry, unsigned long now = jiffies; int rc; rc = obd->obd_fsops->fs_setattr(dentry, handle, iattr, do_trunc); - if (time_after(jiffies, now + 15*HZ)) + if (time_after(jiffies, now + 15 * HZ)) CERROR("long setattr time %lus\n", (jiffies - now) / HZ); - return rc; } @@ -147,9 +177,11 @@ static inline int fsfilt_journal_data(struct obd_device *obd, struct file *file) } static inline int fsfilt_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) + void *handle, fsfilt_cb_t cb_func, + void *cb_data) { - return obd->obd_fsops->fs_set_last_rcvd(obd, last_rcvd,handle,cb_func); + return obd->obd_fsops->fs_set_last_rcvd(obd, last_rcvd, handle, + cb_func, cb_data); } static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *fs, diff --git a/lustre/obdclass/fsfilt_ext3.c b/lustre/obdclass/fsfilt_ext3.c index 5f6322f..2488c70 100644 --- a/lustre/obdclass/fsfilt_ext3.c +++ b/lustre/obdclass/fsfilt_ext3.c @@ -43,10 +43,11 @@ static kmem_cache_t *fcb_cache; static atomic_t fcb_cache_count = ATOMIC_INIT(0); struct fsfilt_cb_data { - struct journal_callback cb_jcb; /* data private to jbd */ + struct journal_callback cb_jcb; /* jbd private data - MUST BE FIRST */ fsfilt_cb_t cb_func; /* MDS/OBD completion function */ struct obd_device *cb_obd; /* MDS/OBD completion device */ __u64 cb_last_rcvd; /* MDS/OST last committed operation */ + void *cb_data; /* MDS/OST completion function data */ }; #define EXT3_XATTR_INDEX_LUSTRE 5 @@ -58,13 +59,24 @@ struct fsfilt_cb_data { * the inode (which we will be changing anyways as part of this * transaction). */ -static void *fsfilt_ext3_start(struct inode *inode, int op) +static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private) { /* For updates to the last recieved file */ int nblocks = EXT3_DATA_TRANS_BLOCKS; void *handle; switch(op) { + case FSFILT_OP_CREATE_LOG: + nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS; + op = FSFILT_OP_CREATE; + break; + case FSFILT_OP_UNLINK_LOG: + nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS; + op = FSFILT_OP_UNLINK; + break; + } + + switch(op) { case FSFILT_OP_RMDIR: case FSFILT_OP_UNLINK: nblocks += EXT3_DELETE_TRANS_BLOCKS; @@ -95,7 +107,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op) LBUG(); } - LASSERT(!current->journal_info); + LASSERT(current->journal_info == desc_private); lock_kernel(); handle = journal_start(EXT3_JOURNAL(inode), nblocks); unlock_kernel(); @@ -185,14 +197,15 @@ static int fsfilt_ext3_credits_needed(int objcount, struct fsfilt_objinfo *fso) * the pages have been written. */ static void *fsfilt_ext3_brw_start(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb) + int niocount, struct niobuf_remote *nb, + void *desc_private) { journal_t *journal; handle_t *handle; int needed; ENTRY; - LASSERT(!current->journal_info); + LASSERT(current->journal_info == desc_private); journal = EXT3_SB(fso->fso_dentry->d_inode->i_sb)->s_journal; needed = fsfilt_ext3_credits_needed(objcount, fso); @@ -218,6 +231,8 @@ static void *fsfilt_ext3_brw_start(int objcount, struct fsfilt_objinfo *fso, if (IS_ERR(handle)) CERROR("can't get handle for %d credits: rc = %ld\n", needed, PTR_ERR(handle)); + else + LASSERT(handle->h_buffer_credits >= needed); RETURN(handle); } @@ -286,8 +301,8 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle, * it will fit, because putting it in an EA currently kills the MDS * performance. We'll fix this with "fast EAs" in the future. */ - if (lmm_size <= sizeof(EXT3_I(inode)->i_data) - - sizeof(EXT3_I(inode)->i_data[0])) { + if (inode->i_blocks == 0 && lmm_size <= sizeof(EXT3_I(inode)->i_data) - + sizeof(EXT3_I(inode)->i_data[0])) { /* XXX old_size is debugging only */ int old_size = EXT3_I(inode)->i_data[0]; if (old_size != 0) { @@ -319,7 +334,7 @@ static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, int lmm_size) { int rc; - if (EXT3_I(inode)->i_data[0]) { + if (inode->i_blocks == 0 && EXT3_I(inode)->i_data[0]) { int size = le32_to_cpu(EXT3_I(inode)->i_data[0]); LASSERT(size < sizeof(EXT3_I(inode)->i_data)); if (lmm) { @@ -411,14 +426,15 @@ static void fsfilt_ext3_cb_func(struct journal_callback *jcb, int error) { struct fsfilt_cb_data *fcb = (struct fsfilt_cb_data *)jcb; - fcb->cb_func(fcb->cb_obd, fcb->cb_last_rcvd, error); + fcb->cb_func(fcb->cb_obd, fcb->cb_last_rcvd, fcb->cb_data, error); OBD_SLAB_FREE(fcb, fcb_cache, sizeof *fcb); atomic_dec(&fcb_cache_count); } static int fsfilt_ext3_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) + void *handle, fsfilt_cb_t cb_func, + void *cb_data) { struct fsfilt_cb_data *fcb; @@ -430,10 +446,10 @@ static int fsfilt_ext3_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, fcb->cb_func = cb_func; fcb->cb_obd = obd; fcb->cb_last_rcvd = last_rcvd; + fcb->cb_data = cb_data; CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd); lock_kernel(); - /* Note that an "incompatible pointer" warning here is OK for now */ journal_callback_set(handle, fsfilt_ext3_cb_func, (struct journal_callback *)fcb); unlock_kernel(); diff --git a/lustre/obdclass/fsfilt_reiserfs.c b/lustre/obdclass/fsfilt_reiserfs.c index ccefb92..836f4f1 100644 --- a/lustre/obdclass/fsfilt_reiserfs.c +++ b/lustre/obdclass/fsfilt_reiserfs.c @@ -48,13 +48,15 @@ #include #include -static void *fsfilt_reiserfs_start(struct inode *inode, int op) +static void *fsfilt_reiserfs_start(struct inode *inode, int op, + void *desc_private) { return (void *)0xf00f00be; } static void *fsfilt_reiserfs_brw_start(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb) + int niocount, struct niobuf_remote *nb, + void *desc_private) { return (void *)0xf00f00be; } @@ -131,8 +133,9 @@ static ssize_t fsfilt_reiserfs_readpage(struct file *file, char *buf, size_t cou return file->f_op->read(file, buf, count, offset); } -static int fsfilt_reiserfs_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) +static int fsfilt_reiserfs_set_last_rcvd(struct obd_device *obd, + __u64 last_rcvd, void *handle, + fsfilt_cb_t cb_func, void *cb_data) { static long next = 0; @@ -141,7 +144,7 @@ static int fsfilt_reiserfs_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd next = jiffies + 300 * HZ; } - cb_func(obd, last_rcvd, 0); + cb_func(obd, last_rcvd, cb_data, 0); return 0; } -- 1.8.3.1