gfs2_assert(sdp, bd->bd_ail == ai);
+ if (!bh){
+ list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
+ continue;
+ }
+
if (!buffer_busy(bh)) {
if (!buffer_uptodate(bh)) {
gfs2_log_unlock(sdp);
bd_ail_st_list) {
bh = bd->bd_bh;
+ if (!bh){
+ list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
+ continue;
+ }
+
gfs2_assert(sdp, bd->bd_ail == ai);
if (buffer_busy(bh)) {
list_del(&bd->bd_ail_st_list);
list_del(&bd->bd_ail_gl_list);
atomic_dec(&bd->bd_gl->gl_ail_count);
- brelse(bd->bd_bh);
+ if (bd->bd_bh)
+ brelse(bd->bd_bh);
+ else
+ kmem_cache_free(gfs2_bufdata_cachep, bd);
}
}
return 0; /* don't care */
}
- if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) {
+ if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) &&
+ PageChecked(page)) {
+ ClearPageChecked(page);
error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
if (error)
goto out_ignore;
return error;
}
+/**
+ * gfs2_set_page_dirty - Page dirtying function
+ * @page: The page to dirty
+ *
+ * Returns: 1 if it dirtyed the page, or 0 otherwise
+ */
+
+static int gfs2_set_page_dirty(struct page *page)
+{
+ struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
+
+ if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
+ SetPageChecked(page);
+ return __set_page_dirty_buffers(page);
+}
+
/**
* gfs2_bmap - Block map function
* @mapping: Address space info
if (bd) {
bd->bd_bh = NULL;
bh->b_private = NULL;
+ if (!bd->bd_ail && list_empty(&bd->bd_le.le_list))
+ kmem_cache_free(gfs2_bufdata_cachep, bd);
}
gfs2_log_unlock(sdp);
unsigned int curr_off = 0;
BUG_ON(!PageLocked(page));
+ if (offset == 0)
+ ClearPageChecked(page);
if (!page_has_buffers(page))
return;
.sync_page = block_sync_page,
.prepare_write = gfs2_prepare_write,
.commit_write = gfs2_commit_write,
+ .set_page_dirty = gfs2_set_page_dirty,
.bmap = gfs2_bmap,
.invalidatepage = gfs2_invalidatepage,
.releasepage = gfs2_releasepage,