#include <linux/slab.h>
/*
- * Unlink a buffer from a transaction.
+ * Unlink a buffer from a transaction.
*
* Called with j_list_lock held.
*/
}
/*
- * Clean up a transaction's checkpoint list.
+ * Clean up a transaction's checkpoint list.
*
* We wait for any pending IO to complete and make sure any clean
- * buffers are removed from the transaction.
+ * buffers are removed from the transaction.
*
* Return 1 if we performed any actions which might have destroyed the
* checkpoint. (journal_remove_checkpoint() deletes the transaction when
} else {
jbd_unlock_bh_state(bh);
}
- jh = next_jh;
} while (jh != last_jh);
return ret;
int i;
spin_unlock(&journal->j_list_lock);
- ll_rw_block(WRITE, *batch_count, bhs);
+ ll_rw_block(SWRITE, *batch_count, bhs);
spin_lock(&journal->j_list_lock);
for (i = 0; i < *batch_count; i++) {
struct buffer_head *bh = bhs[i];
*
* However, we _do_ take into account the amount requested so that once
* the IO has been queued, we can return as soon as enough of it has
- * completed to disk.
+ * completed to disk.
*
* The journal should be locked before calling this function.
*/
break;
}
retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
+ if (cond_resched_lock(&journal->j_list_lock)) {
+ retry = 1;
+ break;
+ }
} while (jh != last_jh && !retry);
- if (batch_count)
+ if (batch_count) {
__flush_batch(journal, bhs, &batch_count);
+ retry = 1;
+ }
/*
* If someone cleaned up this transaction while we slept, we're
/*
* We have walked the whole transaction list without
* finding anything to write to disk. We had better be
- * able to make some progress or we are in trouble.
+ * able to make some progress or we are in trouble.
*/
cleanup_ret = __cleanup_transaction(journal, transaction);
J_ASSERT(drop_count != 0 || cleanup_ret != 0);
/* Use trylock because of the ranknig */
if (jbd_trylock_bh_state(jh2bh(jh)))
ret += __try_to_free_cp_buf(jh);
+ /*
+ * This function only frees up some memory
+ * if possible so we dont have an obligation
+ * to finish processing. Bail out if preemption
+ * requested:
+ */
+ if (need_resched())
+ goto out;
} while (jh != last_jh);
}
} while (transaction != last_transaction);
* transaction need to be maintained on the transaction's checkpoint
* list until they have been rewritten, at which point this function is
* called to remove the buffer from the existing transaction's
- * checkpoint list.
+ * checkpoint list.
*
* This function is called with the journal locked.
* This function is called with j_list_lock held.