pgoff_t index;
unsigned from, to;
struct page *page;
+ DEFINE_WAIT(wq);
index = pos >> PAGE_CACHE_SHIFT;
from = pos & (PAGE_CACHE_SIZE - 1);
first = from >> bits;
last = (to-1) >> bits;
- wait_event(fs->trunc_wait,
- !test_bit(I_Trunc, &LAFSI(ino)->iflags) ||
- LAFSI(ino)->trunc_next > last);
+ while (test_bit(I_Trunc, &LAFSI(ino)->iflags) &&
+ LAFSI(ino)->trunc_next <= last) {
+ struct datablock *db = lafs_inode_dblock(ino,
+ SYNC, MKREF(writetrunc));
+ prepare_to_wait(&fs->async_complete, &wq,
+ TASK_UNINTERRUPTIBLE);
+ lafs_inode_handle_orphan(db);
+ if (test_bit(B_Orphan, &db->b.flags))
+ schedule();
+ putdref(db, MKREF(writetrunc));
+ }
+ finish_wait(&fs->async_complete, &wq);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
page = __grab_cache_page(mapping, index);
*/
struct fs *fs = fs_from_inode(ino);
struct datablock *db = lafs_inode_dblock(ino, SYNC, MKREF(trunc));
+ loff_t trunc_block;
+ DEFINE_WAIT(wq);
if (IS_ERR(db))
return;
- wait_event(fs->trunc_wait,
- !test_bit(I_Trunc, &LAFSI(ino)->iflags));
+ trunc_block = ((i_size_read(ino) + fs->blocksize - 1)
+ >> fs->blocksize_bits);
+ /* We hold i_mutex, so regular orphan processing cannot
+ * contine - we have to push it forward ourselves.
+ */
+ while (test_bit(I_Trunc, &LAFSI(ino)->iflags) &&
+ LAFSI(ino)->trunc_next < trunc_block) {
+ prepare_to_wait(&fs->async_complete, &wq,
+ TASK_UNINTERRUPTIBLE);
+ lafs_inode_handle_orphan(db);
+ if (test_bit(B_Orphan, &db->b.flags))
+ schedule();
+ }
+ finish_wait(&fs->async_complete, &wq);
/* FIXME there is nothing I can do with an error here */
lafs_make_orphan(fs, db);
- LAFSI(ino)->trunc_next = (i_size_read(ino) +
- fs->blocksize - 1)
- >> fs->blocksize_bits;
- set_bit(I_Trunc, &LAFSI(ino)->iflags);
+ LAFSI(ino)->trunc_next = trunc_block;
putdref(db, MKREF(trunc));
}