}
-static void captive_privbcb_flush_unordered(struct private_bcb *privbcb);
+static gboolean captive_privbcb_flush_unordered(struct private_bcb *privbcb);
static void captive_cc_flush_private_bcb_hash_foreach(
PUBLIC_BCB *PublicBcb, /* key */
struct private_bcb *privbcb, /* value */
gboolean *flushedp) /* user_data */
{
+gboolean errbool;
+
g_return_if_fail(validate_Bcb(PublicBcb));
g_return_if_fail(privbcb!=NULL);
g_return_if_fail(PublicBcb==privbcb->PublicBcb);
g_assert(!privbcb->lsn_valid);
*flushedp=TRUE;
- captive_privbcb_flush_unordered(privbcb);
+ errbool=captive_privbcb_flush_unordered(privbcb);
+ g_assert(errbool==TRUE);
}
-static void captive_privbcb_flush_ordered(struct private_bcb *privbcb_req);
+static gboolean captive_privbcb_flush_ordered(struct private_bcb *privbcb_req);
void captive_cc_flush(void)
{
do {
/* Trace it by g_tree first to attempt to keep LSN ordering */
- captive_privbcb_flush_ordered(NULL);
- flushed=FALSE;
+ flushed=captive_privbcb_flush_ordered(NULL);
g_hash_table_foreach(
private_bcb_hash, /* hash_table */
(GHFunc)captive_cc_flush_private_bcb_hash_foreach, /* func */
static void logging_notify_privbcb_flush(struct private_bcb *privbcb);
-static void captive_privbcb_flush_unordered(struct private_bcb *privbcb)
+/* Returns: The block was dirty and it was flushed to disk.
+ */
+static gboolean captive_privbcb_flush_unordered(struct private_bcb *privbcb)
{
MDL *Mdl;
KEVENT Event;
g_assert(privbcb->ref_count>0);
if (!privbcb->dirty)
- return;
+ return FALSE;
privbcb_set(privbcb,PRIVBCB_ITEM_REF_COUNT_DESTRUCTOR,+1);
logging_notify_privbcb_flush(privbcb);
privbcb_set(privbcb,PRIVBCB_ITEM_REF_COUNT_DESTRUCTOR,-1);
if (privbcb->lsn_valid) {
- if (!(last_written_lsn<privbcb->lsn.QuadPart))
- g_error("%s: last_written_lsn=%" G_GINT64_FORMAT " !< privbcb->lsn=%" G_GINT64_FORMAT,G_STRLOC,
+ if (!(last_written_lsn<=privbcb->lsn.QuadPart))
+ g_error("%s: last_written_lsn=%" G_GINT64_FORMAT " !<= privbcb->lsn=%" G_GINT64_FORMAT,G_STRLOC,
last_written_lsn,(gint64)privbcb->lsn.QuadPart);
g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: LSN write: last_written_lsn was %" G_GINT64_FORMAT ", is %" G_GINT64_FORMAT,
G_STRLOC,last_written_lsn,(gint64)privbcb->lsn.QuadPart);
(gulong)IoStatus.Information);
privbcb_set(privbcb,PRIVBCB_ITEM_DIRTY,FALSE);
+ return TRUE;
}
struct captive_privbcb_flush_ordered_param {
/* Use 'privbcb==NULL' to flush all LSNed entries of cache.
* WARNING: Non-LSNed entries will NOT be flushed!
+ * Returns: Anything was really flushed to disk.
*/
-static void captive_privbcb_flush_ordered(struct private_bcb *privbcb_req)
+static gboolean captive_privbcb_flush_ordered(struct private_bcb *privbcb_req)
{
struct private_bcb *privbcb;
struct captive_privbcb_flush_ordered_param captive_privbcb_flush_ordered_param;
+gboolean errbool;
+gboolean r=FALSE;
if ((privbcb=privbcb_req) && !privbcb->dirty)
- return;
+ return FALSE;
if ((privbcb=privbcb_req) && !privbcb->lsn_valid) {
- captive_privbcb_flush_unordered(privbcb);
- return;
+ r=captive_privbcb_flush_unordered(privbcb);
+ g_assert(r==TRUE);
+ return r;
}
private_bcb_lsn_tree_init();
(int)privbcb->leave_func_pending);
if (privbcb->dirty) {
- captive_privbcb_flush_unordered(privbcb);
+ errbool=captive_privbcb_flush_unordered(privbcb);
+ g_assert(errbool==TRUE);
+ r=TRUE;
continue; /* Restart as anything could change by calling W32 hassle. */
}
break;
}
- g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: return",G_STRLOC);
+ g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: return %d",G_STRLOC,(int)r);
+ return r;
}
g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: Bcb=%p,WriteThrough=%d,IoStatus=%p; privbcb->FileObject=%p",G_STRLOC,
Bcb,(gint)WriteThrough,IoStatus,privbcb->FileObject);
+ /* FIXME: Should we really mark it as dirty by this function?
+ * Undocumented by W32.
+ */
+ privbcb_set(privbcb,PRIVBCB_ITEM_DIRTY,TRUE);
+
/* FIXME: Should we really flush the whole 'Bcb'?
* Or maybe just some writes between CcRepinBcb(Bcb) and now? Who knows?
+ * Undocumented by W32.
*/
if (WriteThrough)
captive_privbcb_flush_ordered(privbcb);