diff options
| -rw-r--r-- | fs/ocfs2/buffer_head_io.c | 84 | ||||
| -rw-r--r-- | fs/ocfs2/buffer_head_io.h | 2 | ||||
| -rw-r--r-- | fs/ocfs2/inode.c | 7 | ||||
| -rw-r--r-- | fs/ocfs2/journal.c | 5 | ||||
| -rw-r--r-- | fs/ocfs2/resize.c | 8 |
5 files changed, 96 insertions, 10 deletions
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index f136639f5b41..ca4ab7ce85bf 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c | |||
| @@ -66,7 +66,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, | |||
| 66 | /* remove from dirty list before I/O. */ | 66 | /* remove from dirty list before I/O. */ |
| 67 | clear_buffer_dirty(bh); | 67 | clear_buffer_dirty(bh); |
| 68 | 68 | ||
| 69 | get_bh(bh); /* for end_buffer_write_sync() */ | 69 | get_bh(bh); /* for end_buffer_write_sync() */ |
| 70 | bh->b_end_io = end_buffer_write_sync; | 70 | bh->b_end_io = end_buffer_write_sync; |
| 71 | submit_bh(WRITE, bh); | 71 | submit_bh(WRITE, bh); |
| 72 | 72 | ||
| @@ -88,6 +88,88 @@ out: | |||
| 88 | return ret; | 88 | return ret; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, | ||
| 92 | unsigned int nr, struct buffer_head *bhs[]) | ||
| 93 | { | ||
| 94 | int status = 0; | ||
| 95 | unsigned int i; | ||
| 96 | struct buffer_head *bh; | ||
| 97 | |||
| 98 | if (!nr) { | ||
| 99 | mlog(ML_BH_IO, "No buffers will be read!\n"); | ||
| 100 | goto bail; | ||
| 101 | } | ||
| 102 | |||
| 103 | for (i = 0 ; i < nr ; i++) { | ||
| 104 | if (bhs[i] == NULL) { | ||
| 105 | bhs[i] = sb_getblk(osb->sb, block++); | ||
| 106 | if (bhs[i] == NULL) { | ||
| 107 | status = -EIO; | ||
| 108 | mlog_errno(status); | ||
| 109 | goto bail; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | bh = bhs[i]; | ||
| 113 | |||
| 114 | if (buffer_jbd(bh)) { | ||
| 115 | mlog(ML_ERROR, | ||
| 116 | "trying to sync read a jbd " | ||
| 117 | "managed bh (blocknr = %llu), skipping\n", | ||
| 118 | (unsigned long long)bh->b_blocknr); | ||
| 119 | continue; | ||
| 120 | } | ||
| 121 | |||
| 122 | if (buffer_dirty(bh)) { | ||
| 123 | /* This should probably be a BUG, or | ||
| 124 | * at least return an error. */ | ||
| 125 | mlog(ML_ERROR, | ||
| 126 | "trying to sync read a dirty " | ||
| 127 | "buffer! (blocknr = %llu), skipping\n", | ||
| 128 | (unsigned long long)bh->b_blocknr); | ||
| 129 | continue; | ||
| 130 | } | ||
| 131 | |||
| 132 | lock_buffer(bh); | ||
| 133 | if (buffer_jbd(bh)) { | ||
| 134 | mlog(ML_ERROR, | ||
| 135 | "block %llu had the JBD bit set " | ||
| 136 | "while I was in lock_buffer!", | ||
| 137 | (unsigned long long)bh->b_blocknr); | ||
| 138 | BUG(); | ||
| 139 | } | ||
| 140 | |||
| 141 | clear_buffer_uptodate(bh); | ||
| 142 | get_bh(bh); /* for end_buffer_read_sync() */ | ||
| 143 | bh->b_end_io = end_buffer_read_sync; | ||
| 144 | submit_bh(READ, bh); | ||
| 145 | } | ||
| 146 | |||
| 147 | for (i = nr; i > 0; i--) { | ||
| 148 | bh = bhs[i - 1]; | ||
| 149 | |||
| 150 | if (buffer_jbd(bh)) { | ||
| 151 | mlog(ML_ERROR, | ||
| 152 | "the journal got the buffer while it was " | ||
| 153 | "locked for io! (blocknr = %llu)\n", | ||
| 154 | (unsigned long long)bh->b_blocknr); | ||
| 155 | BUG(); | ||
| 156 | } | ||
| 157 | |||
| 158 | wait_on_buffer(bh); | ||
| 159 | if (!buffer_uptodate(bh)) { | ||
| 160 | /* Status won't be cleared from here on out, | ||
| 161 | * so we can safely record this and loop back | ||
| 162 | * to cleanup the other buffers. */ | ||
| 163 | status = -EIO; | ||
| 164 | put_bh(bh); | ||
| 165 | bhs[i - 1] = NULL; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | bail: | ||
| 170 | return status; | ||
| 171 | } | ||
| 172 | |||
| 91 | int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, | 173 | int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, |
| 92 | struct buffer_head *bhs[], int flags, | 174 | struct buffer_head *bhs[], int flags, |
| 93 | struct inode *inode) | 175 | struct inode *inode) |
diff --git a/fs/ocfs2/buffer_head_io.h b/fs/ocfs2/buffer_head_io.h index c2e78614c3e5..71646b470ac8 100644 --- a/fs/ocfs2/buffer_head_io.h +++ b/fs/ocfs2/buffer_head_io.h | |||
| @@ -46,6 +46,8 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, | |||
| 46 | struct buffer_head *bhs[], | 46 | struct buffer_head *bhs[], |
| 47 | int flags, | 47 | int flags, |
| 48 | struct inode *inode); | 48 | struct inode *inode); |
| 49 | int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, | ||
| 50 | unsigned int nr, struct buffer_head *bhs[]); | ||
| 49 | 51 | ||
| 50 | int ocfs2_write_super_or_backup(struct ocfs2_super *osb, | 52 | int ocfs2_write_super_or_backup(struct ocfs2_super *osb, |
| 51 | struct buffer_head *bh); | 53 | struct buffer_head *bh); |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 05ad1186a167..522297033945 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -460,8 +460,11 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
| 460 | } | 460 | } |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, | 463 | if (can_lock) |
| 464 | can_lock ? inode : NULL); | 464 | status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, |
| 465 | inode); | ||
| 466 | else | ||
| 467 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); | ||
| 465 | if (status < 0) { | 468 | if (status < 0) { |
| 466 | mlog_errno(status); | 469 | mlog_errno(status); |
| 467 | goto bail; | 470 | goto bail; |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 562ba652593e..10c51b562be8 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
| @@ -850,9 +850,8 @@ static int ocfs2_force_read_journal(struct inode *inode) | |||
| 850 | 850 | ||
| 851 | /* We are reading journal data which should not | 851 | /* We are reading journal data which should not |
| 852 | * be put in the uptodate cache */ | 852 | * be put in the uptodate cache */ |
| 853 | status = ocfs2_read_blocks(OCFS2_SB(inode->i_sb), | 853 | status = ocfs2_read_blocks_sync(OCFS2_SB(inode->i_sb), |
| 854 | p_blkno, p_blocks, bhs, 0, | 854 | p_blkno, p_blocks, bhs); |
| 855 | NULL); | ||
| 856 | if (status < 0) { | 855 | if (status < 0) { |
| 857 | mlog_errno(status); | 856 | mlog_errno(status); |
| 858 | goto bail; | 857 | goto bail; |
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 8166968e9015..472d854796c2 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c | |||
| @@ -200,7 +200,7 @@ static int update_backups(struct inode * inode, u32 clusters, char *data) | |||
| 200 | if (cluster > clusters) | 200 | if (cluster > clusters) |
| 201 | break; | 201 | break; |
| 202 | 202 | ||
| 203 | ret = ocfs2_read_block(osb, blkno, &backup, 0, NULL); | 203 | ret = ocfs2_read_blocks_sync(osb, blkno, 1, &backup); |
| 204 | if (ret < 0) { | 204 | if (ret < 0) { |
| 205 | mlog_errno(ret); | 205 | mlog_errno(ret); |
| 206 | break; | 206 | break; |
| @@ -236,8 +236,8 @@ static void ocfs2_update_super_and_backups(struct inode *inode, | |||
| 236 | * update the superblock last. | 236 | * update the superblock last. |
| 237 | * It doesn't matter if the write failed. | 237 | * It doesn't matter if the write failed. |
| 238 | */ | 238 | */ |
| 239 | ret = ocfs2_read_block(osb, OCFS2_SUPER_BLOCK_BLKNO, | 239 | ret = ocfs2_read_blocks_sync(osb, OCFS2_SUPER_BLOCK_BLKNO, 1, |
| 240 | &super_bh, 0, NULL); | 240 | &super_bh); |
| 241 | if (ret < 0) { | 241 | if (ret < 0) { |
| 242 | mlog_errno(ret); | 242 | mlog_errno(ret); |
| 243 | goto out; | 243 | goto out; |
| @@ -540,7 +540,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) | |||
| 540 | goto out_unlock; | 540 | goto out_unlock; |
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | ret = ocfs2_read_block(osb, input->group, &group_bh, 0, NULL); | 543 | ret = ocfs2_read_blocks_sync(osb, input->group, 1, &group_bh); |
| 544 | if (ret < 0) { | 544 | if (ret < 0) { |
| 545 | mlog(ML_ERROR, "Can't read the group descriptor # %llu " | 545 | mlog(ML_ERROR, "Can't read the group descriptor # %llu " |
| 546 | "from the device.", (unsigned long long)input->group); | 546 | "from the device.", (unsigned long long)input->group); |
