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);
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);
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;
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;
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;
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;
/* 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 = {
#include <linux/obd.h>
#include <linux/fs.h>
-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;
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);
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,
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
#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;
}
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;
}
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;
}
}
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,
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
* 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;
LBUG();
}
- LASSERT(!current->journal_info);
+ LASSERT(current->journal_info == desc_private);
lock_kernel();
handle = journal_start(EXT3_JOURNAL(inode), nblocks);
unlock_kernel();
* 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);
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);
}
* 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) {
{
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) {
{
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;
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();
#include <linux/obd_class.h>
#include <linux/module.h>
-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;
}
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;
next = jiffies + 300 * HZ;
}
- cb_func(obd, last_rcvd, 0);
+ cb_func(obd, last_rcvd, cb_data, 0);
return 0;
}