From: NeilBrown As prepare_write, commit_write and readpage are allowed to return AOP_TRUNCATE_PAGE, page_symlink should respond to them. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- fs/namei.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff -puN fs/namei.c~honour-aop_truncate_page-returns-in-page_symlink fs/namei.c --- devel/fs/namei.c~honour-aop_truncate_page-returns-in-page_symlink 2006-03-16 02:08:43.000000000 -0800 +++ devel-akpm/fs/namei.c 2006-03-16 02:08:43.000000000 -0800 @@ -2628,16 +2628,27 @@ int __page_symlink(struct inode *inode, int err = -ENOMEM; char *kaddr; +retry: page = find_or_create_page(mapping, 0, gfp_mask); if (!page) goto fail; err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); + if (err == AOP_TRUNCATED_PAGE) { + page_cache_release(page); + goto retry; + } if (err) goto fail_map; kaddr = kmap_atomic(page, KM_USER0); memcpy(kaddr, symname, len-1); kunmap_atomic(kaddr, KM_USER0); - mapping->a_ops->commit_write(NULL, page, 0, len-1); + err = mapping->a_ops->commit_write(NULL, page, 0, len-1); + if (err == AOP_TRUNCATED_PAGE) { + page_cache_release(page); + goto retry; + } + if (err) + goto fail_map; /* * Notice that we are _not_ going to block here - end of page is * unmapped, so this will only try to map the rest of page, see @@ -2647,7 +2658,8 @@ int __page_symlink(struct inode *inode, */ if (!PageUptodate(page)) { err = mapping->a_ops->readpage(NULL, page); - wait_on_page_locked(page); + if (err != AOP_TRUNCATED_PAGE) + wait_on_page_locked(page); } else { unlock_page(page); } _