Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87e99511 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro
Browse files

kill BH_Ordered flag



Instead of abusing a buffer_head flag just add a variant of
sync_dirty_buffer which allows passing the exact type of write
flag required.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent dad5eb6d
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -2911,13 +2911,6 @@ int submit_bh(int rw, struct buffer_head * bh)
	BUG_ON(buffer_delay(bh));
	BUG_ON(buffer_unwritten(bh));

	/*
	 * Mask in barrier bit for a write (could be either a WRITE or a
	 * WRITE_SYNC
	 */
	if (buffer_ordered(bh) && (rw & WRITE))
		rw |= WRITE_BARRIER;

	/*
	 * Only clear out a write error when rewriting
	 */
@@ -3021,7 +3014,7 @@ EXPORT_SYMBOL(ll_rw_block);
 * and then start new I/O and then wait upon it.  The caller must have a ref on
 * the buffer_head.
 */
int sync_dirty_buffer(struct buffer_head *bh)
int __sync_dirty_buffer(struct buffer_head *bh, int rw)
{
	int ret = 0;

@@ -3030,7 +3023,7 @@ int sync_dirty_buffer(struct buffer_head *bh)
	if (test_clear_buffer_dirty(bh)) {
		get_bh(bh);
		bh->b_end_io = end_buffer_write_sync;
		ret = submit_bh(WRITE_SYNC, bh);
		ret = submit_bh(rw, bh);
		wait_on_buffer(bh);
		if (buffer_eopnotsupp(bh)) {
			clear_buffer_eopnotsupp(bh);
@@ -3043,6 +3036,12 @@ int sync_dirty_buffer(struct buffer_head *bh)
	}
	return ret;
}
EXPORT_SYMBOL(__sync_dirty_buffer);

int sync_dirty_buffer(struct buffer_head *bh)
{
	return __sync_dirty_buffer(bh, WRITE_SYNC);
}
EXPORT_SYMBOL(sync_dirty_buffer);

/*
+25 −24
Original line number Diff line number Diff line
@@ -119,7 +119,6 @@ static int journal_write_commit_record(journal_t *journal,
	struct buffer_head *bh;
	journal_header_t *header;
	int ret;
	int barrier_done = 0;

	if (is_journal_aborted(journal))
		return 0;
@@ -137,19 +136,17 @@ static int journal_write_commit_record(journal_t *journal,

	JBUFFER_TRACE(descriptor, "write commit block");
	set_buffer_dirty(bh);

	if (journal->j_flags & JFS_BARRIER) {
		set_buffer_ordered(bh);
		barrier_done = 1;
	}
	ret = sync_dirty_buffer(bh);
	if (barrier_done)
		clear_buffer_ordered(bh);
	/* is it possible for another commit to fail at roughly
		ret = __sync_dirty_buffer(bh, WRITE_SYNC | WRITE_BARRIER);

		/*
		 * Is it possible for another commit to fail at roughly
		 * the same time as this one?  If so, we don't want to
		 * trust the barrier flag in the super, but instead want
		 * to remember if we sent a barrier request
		 */
	if (ret == -EOPNOTSUPP && barrier_done) {
		if (ret == -EOPNOTSUPP) {
			char b[BDEVNAME_SIZE];

			printk(KERN_WARNING
@@ -165,6 +162,10 @@ static int journal_write_commit_record(journal_t *journal,
			set_buffer_dirty(bh);
			ret = sync_dirty_buffer(bh);
		}
	} else {
		ret = sync_dirty_buffer(bh);
	}

	put_bh(bh);		/* One for getblk() */
	journal_put_journal_head(descriptor);

+15 −24
Original line number Diff line number Diff line
@@ -101,7 +101,6 @@ static int journal_submit_commit_record(journal_t *journal,
	struct commit_header *tmp;
	struct buffer_head *bh;
	int ret;
	int barrier_done = 0;
	struct timespec now = current_kernel_time();

	if (is_journal_aborted(journal))
@@ -136,19 +135,8 @@ static int journal_submit_commit_record(journal_t *journal,
	if (journal->j_flags & JBD2_BARRIER &&
	    !JBD2_HAS_INCOMPAT_FEATURE(journal,
				       JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
		set_buffer_ordered(bh);
		barrier_done = 1;
	}
	ret = submit_bh(WRITE_SYNC_PLUG, bh);
	if (barrier_done)
		clear_buffer_ordered(bh);

	/* is it possible for another commit to fail at roughly
	 * the same time as this one?  If so, we don't want to
	 * trust the barrier flag in the super, but instead want
	 * to remember if we sent a barrier request
	 */
	if (ret == -EOPNOTSUPP && barrier_done) {
		ret = submit_bh(WRITE_SYNC_PLUG | WRITE_BARRIER, bh);
		if (ret == -EOPNOTSUPP) {
			printk(KERN_WARNING
			       "JBD2: Disabling barriers on %s, "
			       "not supported by device\n", journal->j_devname);
@@ -162,6 +150,9 @@ static int journal_submit_commit_record(journal_t *journal,
			clear_buffer_dirty(bh);
			ret = submit_bh(WRITE_SYNC_PLUG, bh);
		}
	} else {
		ret = submit_bh(WRITE_SYNC_PLUG, bh);
	}
	*cbh = bh;
	return ret;
}
+14 −14
Original line number Diff line number Diff line
@@ -175,24 +175,24 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
{
	struct the_nilfs *nilfs = sbi->s_nilfs;
	int err;
	int barrier_done = 0;

	if (nilfs_test_opt(sbi, BARRIER)) {
		set_buffer_ordered(nilfs->ns_sbh[0]);
		barrier_done = 1;
	}
 retry:
	set_buffer_dirty(nilfs->ns_sbh[0]);
	err = sync_dirty_buffer(nilfs->ns_sbh[0]);
	if (err == -EOPNOTSUPP && barrier_done) {

	if (nilfs_test_opt(sbi, BARRIER)) {
		err = __sync_dirty_buffer(nilfs->ns_sbh[0],
					  WRITE_SYNC | WRITE_BARRIER);
		if (err == -EOPNOTSUPP) {
			nilfs_warning(sbi->s_super, __func__,
				      "barrier-based sync failed. "
				      "disabling barriers\n");
			nilfs_clear_opt(sbi, BARRIER);
		barrier_done = 0;
		clear_buffer_ordered(nilfs->ns_sbh[0]);
			goto retry;
		}
	} else {
		err = sync_dirty_buffer(nilfs->ns_sbh[0]);
	}

	if (unlikely(err)) {
		printk(KERN_ERR
		       "NILFS: unable to write superblock (err=%d)\n", err);
+1 −2
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ enum bh_state_bits {
	BH_Delay,	/* Buffer is not yet allocated on disk */
	BH_Boundary,	/* Block is followed by a discontiguity */
	BH_Write_EIO,	/* I/O error on write */
	BH_Ordered,	/* ordered write */
	BH_Eopnotsupp,	/* operation not supported (barrier) */
	BH_Unwritten,	/* Buffer is allocated on disk but not written */
	BH_Quiet,	/* Buffer Error Prinks to be quiet */
@@ -125,7 +124,6 @@ BUFFER_FNS(Async_Write, async_write)
BUFFER_FNS(Delay, delay)
BUFFER_FNS(Boundary, boundary)
BUFFER_FNS(Write_EIO, write_io_error)
BUFFER_FNS(Ordered, ordered)
BUFFER_FNS(Eopnotsupp, eopnotsupp)
BUFFER_FNS(Unwritten, unwritten)

@@ -183,6 +181,7 @@ void unlock_buffer(struct buffer_head *bh);
void __lock_buffer(struct buffer_head *bh);
void ll_rw_block(int, int, struct buffer_head * bh[]);
int sync_dirty_buffer(struct buffer_head *bh);
int __sync_dirty_buffer(struct buffer_head *bh, int rw);
int submit_bh(int, struct buffer_head *);
void write_boundary_block(struct block_device *bdev,
			sector_t bblock, unsigned blocksize);