+static void dio_unlock_page_range(struct dio *dio) +{ + if (dio->lock_type != DIO_NO_LOCKING) { + remove_placeholder_pages(dio->inode->i_mapping, + dio->fspages_start_off, + dio->fspages_end_off); + dio->fspages_end_off = dio->fspages_start_off;
I wonder if it should call remove_placeholder_pages when _end_off != _start_off. That feels like a more direct test.
+ max_size = (dio->fspages_end_off - index) << PAGE_CACHE_SHIFT; + if (map_bh->b_size > max_size) + map_bh->b_size = max_size;
b_size = min(b_size, math) ?
+ /* if the mapping is mapped, they may be using a mmap'd portion + * of the file as the buffer for this io. That will deadlock + * with placeholders because the placeholder code forces the + * page fault handler to block. The (ugly) solution is to + * limit the span of inserted placeholders to the same + * increment we use for get_user_pages. + */ + if (inode->i_mapping->nrpages || + mapping_mapped(inode->i_mapping)) + dio->fspages_span = DIO_PAGES; + else + dio->fspages_span = ULONG_MAX;
Couldn't the decision to use DIO_PAGES in the presence of a mapping race with establishing a mapping? I fear we have to use DIO_PAGES all the time, which at least has the benefit of getting rid of the _span member of dio :).
- z - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html