splice: partial write handling fix
PATCH 1/1 splice: partial write handling fix
currently if partial write has happened while ->commit_write() then page wasn't marked as accessed and rebalanced.
fs/splice.c +16 -9
@@ -682,18 +682,25 @@ find_page: } ret = mapping->a_ops->commit_write (file, page, offset, offset+this_len); -if (!ret) { +if (ret) { +if (ret ==AOP_TRUNCATED_PAGE ) { +page_cache_release (page); + goto find_page; + } +if (ret <0 ) + goto out;/* -* Return the number of bytes written and mark page as -* accessed, we are now done! +* Partial write has happened, so 'ret' already initialized by +* number of bytes written, Where is nothing we have to do here. */ + }else ret = this_len; -mark_page_accessed (page); -balance_dirty_pages_ratelimited (mapping); - }else if (ret ==AOP_TRUNCATED_PAGE ) { -page_cache_release (page); - goto find_page; - } +/* +* Return the number of bytes written and mark page as +* accessed, we are now done! +*/ +mark_page_accessed (page); +balance_dirty_pages_ratelimited (mapping); out:page_cache_release (page);unlock_page (page);
Quoted 2 lines · Dmitriy Monakhov
currently if partial write has happened while ->commit_write() then page wasn't marked as accessed and rebalanced.
The ->commit_write() return values aren't very well designed imho. Is your fix correct getting the pipe_to_file() return value correct now?
Signature · 1 line
Jens Axboe
Quoted 6 lines · Jens Axboe
Quoted 2 lines · Dmitriy Monakhov
currently if partial write has happened while ->commit_write() then page wasn't marked as accessed and rebalanced.
The ->commit_write() return values aren't very well designed imho. Is your fix correct getting the
pipe_to_file()return value correct now?
I think yes, after my patch this path look like follows:
ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len);
if (ret) {
if(ret == AOP_TRUNCATED_PAGE) {
page_cache_release(page);
goto find_page;
}
if (ret < 0)
goto out;
/*
* Partial write has happened, so 'ret' already initialized by
* number of bytes written, Where is nothing we have to do here.
*/
} else
ret = this_len;
/*
* Return the number of bytes written and mark page as
* accessed, we are now done!
*/
mark_page_accessed(page);
balance_dirty_pages_ratelimited(mapping);
out:
page_cache_release(page);
unlock_page(page);
out_ret:
return ret;
}But off corse this patch does't fix issues spotted by Nick.
Quoted 9 lines
Signature · 8 lines
-- Jens Axboe - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/