void (* fs_delete_inode)(struct inode *inode);
void (* cl_delete_inode)(struct inode *inode);
int (* fs_journal_data)(struct inode *inode, struct file *file);
+ int (* fs_set_last_rcvd)(struct mds_obd *mds, void *handle);
};
#define MDS_FSOP_UNLINK 1
return mds->mds_fsops->fs_readpage(file, buf, count, offset);
}
+static inline int mds_fs_set_last_rcvd(struct mds_obd *mds, void *handle)
+{
+ return mds->mds_fsops->fs_set_last_rcvd(mds, handle);
+}
+
static inline ssize_t mds_fs_journal_data(struct mds_obd *mds,
struct inode *inode,
struct file *file)
struct address_space_operations *mds_aops;
struct mds_fs_operations *mds_fsops;
struct file *mds_rcvd_filp;
+ __u64 mds_last_committed;
__u64 mds_last_rcvd;
__u64 mds_mount_count;
struct ll_fid mds_rootfid;
struct mds_fs_operations mds_ext2_fs_ops;
-void mds_ext2_delete_inode(struct inode *inode)
+static void mds_ext2_delete_inode(struct inode *inode)
{
if (S_ISREG(inode->i_mode))
mds_ext2_set_objid(inode, NULL, 0);
mds_ext2_fs_ops.cl_delete_inode(inode);
}
-int mds_ext2_journal_data(struct inode *inode, struct file *filp)
+static int mds_ext2_set_last_rcvd(struct mds_obd *mds, void *handle)
+{
+ /* Bail for ext2 - can't tell when it is on disk anyways, sync? */
+ mds->mds_last_committed = mds->mds_last_rcvd;
+
+ return 0;
+}
+
+static int mds_ext2_journal_data(struct inode *inode, struct file *filp)
{
return 0;
}
fs_delete_inode:mds_ext2_delete_inode,
cl_delete_inode:clear_inode,
fs_journal_data:mds_ext2_journal_data,
+ fs_set_last_rcvd:mds_ext2_set_last_rcvd,
};
struct mds_fs_operations mds_ext3_fs_ops;
-void mds_ext3_delete_inode(struct inode *inode)
+static void mds_ext3_delete_inode(struct inode *inode)
{
- void *handle;
-
if (S_ISREG(inode->i_mode)) {
- handle = mds_ext3_start(inode, MDS_FSOP_UNLINK);
+ void *handle = mds_ext3_start(inode, MDS_FSOP_UNLINK);
if (IS_ERR(handle)) {
CERROR("unable to start transaction");
mds_ext3_fs_ops.cl_delete_inode(inode);
}
-int mds_ext3_journal_data(struct inode *inode, struct file *filp)
+struct mds_cb_data {
+ struct journal_callback cb_jcb;
+ struct mds_obd *cb_mds;
+ __u64 cb_last_rcvd;
+};
+
+static void mds_ext3_callback_func(void *cb_data)
+{
+ struct mds_cb_data *mcb = cb_data;
+
+ CDEBUG(D_EXT2, "got callback for last_rcvd: %Ld\n", mcb->cb_last_rcvd);
+ if (mcb->cb_last_rcvd > mcb->cb_mds->mds_last_committed)
+ mcb->cb_mds->mds_last_committed = mcb->cb_last_rcvd;
+
+ OBD_FREE(mcb, sizeof(*mcb));
+}
+
+static int mds_ext3_set_last_rcvd(struct mds_obd *mds, void *handle)
+{
+ struct mds_cb_data *mcb;
+
+ OBD_ALLOC(mcb, sizeof(*mcb));
+ if (!mcb)
+ RETURN(-ENOMEM);
+
+ mcb->cb_mds = mds;
+ mcb->cb_last_rcvd = mds->mds_last_rcvd;
+
+#ifdef HAVE_JOURNAL_CALLBACK
+ CDEBUG(D_EXT2, "set callback for last_rcvd: %Ld\n",
+ (unsigned long long)mcb->cb_last_rcvd);
+ journal_callback_set(handle, mds_ext3_callback_func, mcb);
+#else
+ {
+ static long next = 0;
+
+ if (time_after(jiffies, next)) {
+ CERROR("no journal callback kernel patch, faking it...\n");
+ next = jiffies + 300 * HZ;
+ }
+ }
+ mds_ext3_callback_func(mcb);
+#endif
+
+ return 0;
+}
+
+static int mds_ext3_journal_data(struct inode *inode, struct file *filp)
{
EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
fs_delete_inode:mds_ext3_delete_inode,
cl_delete_inode:clear_inode,
fs_journal_data:mds_ext3_journal_data,
+ fs_set_last_rcvd:mds_ext3_set_last_rcvd,
};
#include <linux/lustre_mds.h>
#include <linux/obd_class.h>
-int mds_update_last_rcvd(struct mds_obd *mds, struct ptlrpc_request *req)
+int mds_update_last_rcvd(struct mds_obd *mds, void *handle,
+ struct ptlrpc_request *req)
{
/* get from req->rq_connection-> or req->rq_client */
struct mds_client_info mci_data, *mci = &mci_data;
mci->mci_mcd->mcd_last_rcvd = cpu_to_le64(mds->mds_last_rcvd);
mci->mci_mcd->mcd_mount_count = cpu_to_le64(mds->mds_mount_count);
mci->mci_mcd->mcd_xid = cpu_to_le32(req->rq_connection->c_xid_in);
+
+ mds_fs_set_last_rcvd(mds, handle);
rc = lustre_fwrite(mds->mds_rcvd_filp, (char *)mci->mci_mcd,
sizeof(*mci->mci_mcd), &off);
CDEBUG(D_INODE, "wrote trans #%Ld for client '%s' at %Ld: rc = %d\n",
rc = mds_fs_setattr(mds, de, handle, &rec->ur_iattr);
if (!rc)
- rc = mds_update_last_rcvd(mds, req);
+ rc = mds_update_last_rcvd(mds, handle, req);
EXIT;
}
if (!rc)
- rc = mds_update_last_rcvd(mds, req);
+ rc = mds_update_last_rcvd(mds, handle, req);
out_create_commit:
/* FIXME: keep rc intact */
}
if (!rc)
- rc = mds_update_last_rcvd(mds, req);
+ rc = mds_update_last_rcvd(mds, handle, req);
/* FIXME: keep rc intact */
rc = mds_fs_commit(mds, dir, handle);
rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild);
if (!rc)
- rc = mds_update_last_rcvd(mds, req);
+ rc = mds_update_last_rcvd(mds, handle, req);
/* FIXME: keep rc intact */
rc = mds_fs_commit(mds, de_tgt_dir->d_inode, handle);
rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new);
if (!rc)
- rc = mds_update_last_rcvd(mds, req);
+ rc = mds_update_last_rcvd(mds, handle, req);
/* FIXME: keep rc intact */
rc = mds_fs_commit(mds, de_tgtdir->d_inode, handle);