|
@@ -1146,8 +1146,8 @@ static int check_block_validity(struct inode *inode, const char *msg,
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Return the number of dirty pages in the given inode starting at
|
|
|
- * page frame idx.
|
|
|
+ * Return the number of contiguous dirty pages in a given inode
|
|
|
+ * starting at page frame idx.
|
|
|
*/
|
|
|
static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
|
|
|
unsigned int max_pages)
|
|
@@ -1181,15 +1181,15 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
|
|
|
unlock_page(page);
|
|
|
break;
|
|
|
}
|
|
|
- head = page_buffers(page);
|
|
|
- bh = head;
|
|
|
- do {
|
|
|
- if (!buffer_delay(bh) &&
|
|
|
- !buffer_unwritten(bh)) {
|
|
|
- done = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- } while ((bh = bh->b_this_page) != head);
|
|
|
+ if (page_has_buffers(page)) {
|
|
|
+ bh = head = page_buffers(page);
|
|
|
+ do {
|
|
|
+ if (!buffer_delay(bh) &&
|
|
|
+ !buffer_unwritten(bh))
|
|
|
+ done = 1;
|
|
|
+ bh = bh->b_this_page;
|
|
|
+ } while (!done && (bh != head));
|
|
|
+ }
|
|
|
unlock_page(page);
|
|
|
if (done)
|
|
|
break;
|
|
@@ -3378,6 +3378,7 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
|
|
|
ssize_t ret;
|
|
|
int orphan = 0;
|
|
|
size_t count = iov_length(iov, nr_segs);
|
|
|
+ int retries = 0;
|
|
|
|
|
|
if (rw == WRITE) {
|
|
|
loff_t final_size = offset + count;
|
|
@@ -3400,9 +3401,12 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+retry:
|
|
|
ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
|
|
|
offset, nr_segs,
|
|
|
ext4_get_block, NULL);
|
|
|
+ if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
|
|
|
+ goto retry;
|
|
|
|
|
|
if (orphan) {
|
|
|
int err;
|
|
@@ -5612,14 +5616,12 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
|
|
|
*/
|
|
|
void ext4_dirty_inode(struct inode *inode)
|
|
|
{
|
|
|
- handle_t *current_handle = ext4_journal_current_handle();
|
|
|
handle_t *handle;
|
|
|
|
|
|
handle = ext4_journal_start(inode, 2);
|
|
|
if (IS_ERR(handle))
|
|
|
goto out;
|
|
|
|
|
|
- jbd_debug(5, "marking dirty. outer handle=%p\n", current_handle);
|
|
|
ext4_mark_inode_dirty(handle, inode);
|
|
|
|
|
|
ext4_journal_stop(handle);
|