remove SWRITE* I/O types
PATCH 2/2 remove SWRITE* I/O types
These flags aren't real I/O types, but tell ll_rw_block to always lock the buffer instead of giving up on a failed trylock.
Instead add a new write_dirty_buffer helper that implements this semantic and use it from the existing SWRITE* callers. Note that the ll_rw_block code had a bug where it didn't promote WRITE_SYNC_PLUG properly, which this patch fixes.
In the ufs code clean up the helper that used to call ll_rw_block to mirror sync_dirty_buffer, which is the function it implements for compound buffers.
Signed-off-by Christoph Hellwig <[email protected]>
fs/ufs/balloc.c +8 -16
@@ -114,10 +114,8 @@ void ufs_free_fragments(struct inode *inubh_mark_buffer_dirty (USPI_UBH (uspi));ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi)); sb->s_dirt =1 ;unlock_super (sb);
@@ -207,10 +205,8 @@ do_more:ubh_mark_buffer_dirty (USPI_UBH (uspi));ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi));if (overflow) { fragment += count;
@@ -558,10 +554,8 @@ static u64 ufs_add_fragments(struct inodubh_mark_buffer_dirty (USPI_UBH (uspi));ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi)); sb->s_dirt =1 ;UFSD ("EXIT, fragment %llu\n" , (unsigned long long )fragment);
@@ -680,10 +674,8 @@ cg_found: succed:ubh_mark_buffer_dirty (USPI_UBH (uspi));ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi)); sb->s_dirt =1 ; result += cgno * uspi->s_fpg;
fs/ufs/ialloc.c +6 -12
@@ -113,10 +113,8 @@ void ufs_free_inode (struct inode * inodubh_mark_buffer_dirty (USPI_UBH (uspi));ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi)); sb->s_dirt =1 ;unlock_super (sb);
@@ -156,10 +154,8 @@ static void ufs2_init_inodes_chunk(strucfs32_add (sb, &ucg->cg_u.cg_u2.cg_initediblk, uspi->s_inopb);ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi));UFSD ("EXIT\n" ); }
@@ -290,10 +286,8 @@ cg_found: }ubh_mark_buffer_dirty (USPI_UBH (uspi));ubh_mark_buffer_dirty (UCPI_UBH (ucpi)); -if (sb->s_flags &MS_SYNCHRONOUS ) { -ubh_ll_rw_block (SWRITE ,UCPI_UBH (ucpi)); -ubh_wait_on_buffer (UCPI_UBH (ucpi)); - } +if (sb->s_flags &MS_SYNCHRONOUS ) +ubh_sync_block (UCPI_UBH (ucpi)); sb->s_dirt =1 ; inode->i_ino = cg * uspi->s_ipg + bit;
fs/ufs/truncate.c +6 -12
@@ -243,10 +243,8 @@ static int ufs_trunc_indirect(struct inoubh_bforget (ind_ubh); ind_ubh =NULL ; } -if (IS_SYNC (inode) && ind_ubh &&ubh_buffer_dirty (ind_ubh)) { -ubh_ll_rw_block (SWRITE , ind_ubh); -ubh_wait_on_buffer (ind_ubh); - } +if (IS_SYNC (inode) && ind_ubh &&ubh_buffer_dirty (ind_ubh)) +ubh_sync_block (ind_ubh);ubh_brelse (ind_ubh);UFSD ("EXIT: ino %lu\n" , inode->i_ino);
@@ -307,10 +305,8 @@ static int ufs_trunc_dindirect(struct inubh_bforget (dind_bh); dind_bh =NULL ; } -if (IS_SYNC (inode) && dind_bh &&ubh_buffer_dirty (dind_bh)) { -ubh_ll_rw_block (SWRITE , dind_bh); -ubh_wait_on_buffer (dind_bh); - } +if (IS_SYNC (inode) && dind_bh &&ubh_buffer_dirty (dind_bh)) +ubh_sync_block (dind_bh);ubh_brelse (dind_bh);UFSD ("EXIT: ino %lu\n" , inode->i_ino);
@@ -367,10 +363,8 @@ static int ufs_trunc_tindirect(struct inubh_bforget (tind_bh); tind_bh =NULL ; } -if (IS_SYNC (inode) && tind_bh &&ubh_buffer_dirty (tind_bh)) { -ubh_ll_rw_block (SWRITE , tind_bh); -ubh_wait_on_buffer (tind_bh); - } +if (IS_SYNC (inode) && tind_bh &&ubh_buffer_dirty (tind_bh)) +ubh_sync_block (tind_bh);ubh_brelse (tind_bh);UFSD ("EXIT: ino %lu\n" , inode->i_ino);
fs/ufs/util.c +8 -12
@@ -113,21 +113,17 @@ void ubh_mark_buffer_uptodate (struct uf } } -void ubh_ll_rw_block (int rw,struct ufs_buffer_head *ubh) +void ubh_sync_block (struct ufs_buffer_head *ubh) { -if (!ubh) -return ; +if (ubh) { +unsigned i; -ll_rw_block (rw, ubh->count, ubh->bh); -} +for (i =0 ; i < ubh->count; i++) +write_dirty_buffer (ubh->bh[i],WRITE ); -void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) -{ -unsigned i; -if (!ubh) -return ; -for ( i =0 ; i < ubh->count; i++ ) -wait_on_buffer (ubh->bh[i]); +for (i =0 ; i < ubh->count; i++) +wait_on_buffer (ubh->bh[i]); + } }void ubh_bforget (struct ufs_buffer_head * ubh)
fs/ufs/util.h +1 -2
@@ -269,8 +269,7 @@ extern void ubh_brelse (struct ufs_buffeextern void ubh_brelse_uspi (struct ufs_sb_private_info *);extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *);extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *,int ); -extern void ubh_ll_rw_block (int ,struct ufs_buffer_head *); -extern void ubh_wait_on_buffer (struct ufs_buffer_head *); +extern void ubh_sync_block (struct ufs_buffer_head *);extern void ubh_bforget (struct ufs_buffer_head *);extern int ubh_buffer_dirty (struct ufs_buffer_head *);#define ubh_ubhcpymem (mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size)
fs/buffer.c +29 -23
88 lines not on this page · raw message
fs/fat/misc.c +3 -1
@@ -250,7 +250,9 @@ int fat_sync_bhs(struct buffer_head **bh {int i, err =0 ; -ll_rw_block (SWRITE , nr_bhs, bhs); +for (i =0 ; i < nr_bhs; i++) +write_dirty_buffer (bhs[i],WRITE ); +for (i =0 ; i < nr_bhs; i++) {wait_on_buffer (bhs[i]);if (buffer_eopnotsupp (bhs[i])) {
fs/reiserfs/journal.c +1 -1
@@ -2312,7 +2312,7 @@ static int journal_read_transaction(stru/* flush out the real blocks */ for (i =0 ; i <get_desc_trans_len (desc); i++) {set_buffer_dirty (real_blocks[i]); -ll_rw_block (SWRITE ,1 , real_blocks + i); +write_dirty_buffer (real_blocks[i],WRITE ); }for (i =0 ; i <get_desc_trans_len (desc); i++) {wait_on_buffer (real_blocks[i]);
fs/jbd/checkpoint.c +3 -1
@@ -254,7 +254,9 @@ __flush_batch(journal_t *journal, struct {int i; -ll_rw_block (SWRITE , *batch_count, bhs); +for (i =0 ; i < *batch_count; i++) +write_dirty_buffer (bhs[i],WRITE ); +for (i =0 ; i < *batch_count; i++) {struct buffer_head *bh = bhs[i];clear_buffer_jwrite (bh);
fs/jbd/journal.c +1 -1
@@ -1024,7 +1024,7 @@ void journal_update_superblock(journal_tif (wait)sync_dirty_buffer (bh);else -ll_rw_block (SWRITE ,1 , &bh); +write_dirty_buffer (bh,WRITE ); out:/* If we have just flushed the log (by marking s_start==0), then
fs/jbd/revoke.c +1 -1
@@ -617,7 +617,7 @@ static void flush_descriptor(journal_t *set_buffer_jwrite (bh);BUFFER_TRACE (bh,"write" );set_buffer_dirty (bh); - ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh); + write_dirty_buffer(bh, write_op); }#endif
fs/jbd2/checkpoint.c +3 -1
@@ -255,7 +255,9 @@ __flush_batch(journal_t *journal, int *b {int i; -ll_rw_block (SWRITE , *batch_count, journal->j_chkpt_bhs); +for (i =0 ; i < *batch_count; i++) +write_dirty_buffer (journal->j_chkpt_bhs[i],WRITE ); +for (i =0 ; i < *batch_count; i++) {struct buffer_head *bh = journal->j_chkpt_bhs[i];clear_buffer_jwrite (bh);
fs/jbd2/journal.c +1 -1
@@ -1124,7 +1124,7 @@ void jbd2_journal_update_superblock(jourset_buffer_uptodate (bh); } }else -ll_rw_block (SWRITE ,1 , &bh); +write_dirty_buffer (bh,WRITE ); out:/* If we have just flushed the log (by marking s_start==0), then
fs/jbd2/revoke.c +1 -1
@@ -625,7 +625,7 @@ static void flush_descriptor(journal_t *set_buffer_jwrite (bh);BUFFER_TRACE (bh,"write" );set_buffer_dirty (bh); - ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh); + write_dirty_buffer(bh, write_op); }#endif
include/linux/fs.h +0 -9
@@ -125,9 +125,6 @@ struct inodes_stat_t {* block layer could (in theory) choose to ignore this * request if it runs into resource problems. * WRITE A normal async write. Device will be plugged. -* SWRITE Like WRITE, but a special case for ll_rw_block() that -* tells it to lock the buffer first. Normally a buffer -* must be locked before doing IO. * WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down * the hint that someone will be waiting on this IO * shortly. The device must still be unplugged explicitly,
@@ -138,9 +135,6 @@ struct inodes_stat_t {* immediately after submission. The write equivalent * of READ_SYNC. * WRITE_ODIRECT_PLUG Special case write for O_DIRECT only. -* SWRITE_SYNC -* SWRITE_SYNC_PLUG Like WRITE_SYNC/WRITE_SYNC_PLUG, but locks the buffer. -* See SWRITE. * WRITE_BARRIER Like WRITE_SYNC, but tells the block layer that all * previously submitted writes must be safely on storage * before this one is started. Also guarantees that when
@@ -155,7 +149,6 @@ struct inodes_stat_t {#define READ 0#define WRITE RW_MASK#define READA RWA_MASK -#define SWRITE (WRITE | READA)#define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG)#define READ_META (READ | REQ_META)
@@ -165,8 +158,6 @@ struct inodes_stat_t {#define WRITE_META (WRITE | REQ_META)#define WRITE_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \ REQ_HARDBARRIER) -#define SWRITE_SYNC_PLUG (SWRITE | REQ_SYNC | REQ_NOIDLE) -#define SWRITE_SYNC (SWRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG)/* * These aren't really reads or writes, they pass down information about
include/linux/buffer_head.h +1 -0
@@ -182,6 +182,7 @@ void __lock_buffer(struct buffer_head *bvoid 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); +void write_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);