diff options
author | NeilBrown <neilb@suse.de> | 2006-03-25 06:07:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 11:22:58 -0500 |
commit | 7e53cac41da9ebb9be774220c1b2615182667c9d (patch) | |
tree | e7da5e8189ed1949d091d28e132736542352b739 /fs/namei.c | |
parent | 341546f5ad6fce584531f744853a5807a140f2a9 (diff) |
[PATCH] Honour AOP_TRUNCATE_PAGE returns in page_symlink
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 <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/namei.c b/fs/namei.c index 1baf1b06fe47..712dfc77793b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2627,16 +2627,27 @@ int __page_symlink(struct inode *inode, const char *symname, int len, | |||
2627 | int err = -ENOMEM; | 2627 | int err = -ENOMEM; |
2628 | char *kaddr; | 2628 | char *kaddr; |
2629 | 2629 | ||
2630 | retry: | ||
2630 | page = find_or_create_page(mapping, 0, gfp_mask); | 2631 | page = find_or_create_page(mapping, 0, gfp_mask); |
2631 | if (!page) | 2632 | if (!page) |
2632 | goto fail; | 2633 | goto fail; |
2633 | err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); | 2634 | err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); |
2635 | if (err == AOP_TRUNCATED_PAGE) { | ||
2636 | page_cache_release(page); | ||
2637 | goto retry; | ||
2638 | } | ||
2634 | if (err) | 2639 | if (err) |
2635 | goto fail_map; | 2640 | goto fail_map; |
2636 | kaddr = kmap_atomic(page, KM_USER0); | 2641 | kaddr = kmap_atomic(page, KM_USER0); |
2637 | memcpy(kaddr, symname, len-1); | 2642 | memcpy(kaddr, symname, len-1); |
2638 | kunmap_atomic(kaddr, KM_USER0); | 2643 | kunmap_atomic(kaddr, KM_USER0); |
2639 | mapping->a_ops->commit_write(NULL, page, 0, len-1); | 2644 | err = mapping->a_ops->commit_write(NULL, page, 0, len-1); |
2645 | if (err == AOP_TRUNCATED_PAGE) { | ||
2646 | page_cache_release(page); | ||
2647 | goto retry; | ||
2648 | } | ||
2649 | if (err) | ||
2650 | goto fail_map; | ||
2640 | /* | 2651 | /* |
2641 | * Notice that we are _not_ going to block here - end of page is | 2652 | * Notice that we are _not_ going to block here - end of page is |
2642 | * unmapped, so this will only try to map the rest of page, see | 2653 | * unmapped, so this will only try to map the rest of page, see |
@@ -2646,7 +2657,8 @@ int __page_symlink(struct inode *inode, const char *symname, int len, | |||
2646 | */ | 2657 | */ |
2647 | if (!PageUptodate(page)) { | 2658 | if (!PageUptodate(page)) { |
2648 | err = mapping->a_ops->readpage(NULL, page); | 2659 | err = mapping->a_ops->readpage(NULL, page); |
2649 | wait_on_page_locked(page); | 2660 | if (err != AOP_TRUNCATED_PAGE) |
2661 | wait_on_page_locked(page); | ||
2650 | } else { | 2662 | } else { |
2651 | unlock_page(page); | 2663 | unlock_page(page); |
2652 | } | 2664 | } |