diff options
| -rw-r--r-- | fs/ceph/addr.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index ce8ef6107727..a313e9baeed0 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
| @@ -356,8 +356,8 @@ static struct ceph_snap_context *__get_oldest_context(struct inode *inode, | |||
| 356 | break; | 356 | break; |
| 357 | } | 357 | } |
| 358 | } | 358 | } |
| 359 | if (!snapc && ci->i_snap_realm) { | 359 | if (!snapc && ci->i_head_snapc) { |
| 360 | snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); | 360 | snapc = ceph_get_snap_context(ci->i_head_snapc); |
| 361 | dout(" head snapc %p has %d dirty pages\n", | 361 | dout(" head snapc %p has %d dirty pages\n", |
| 362 | snapc, ci->i_wrbuffer_ref_head); | 362 | snapc, ci->i_wrbuffer_ref_head); |
| 363 | } | 363 | } |
| @@ -412,7 +412,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) | |||
| 412 | dout("writepage %p page %p not dirty?\n", inode, page); | 412 | dout("writepage %p page %p not dirty?\n", inode, page); |
| 413 | goto out; | 413 | goto out; |
| 414 | } | 414 | } |
| 415 | if (snapc != get_oldest_context(inode, &snap_size)) { | 415 | if (snapc->seq > get_oldest_context(inode, &snap_size)->seq) { |
| 416 | dout("writepage %p page %p snapc %p not writeable - noop\n", | 416 | dout("writepage %p page %p snapc %p not writeable - noop\n", |
| 417 | inode, page, (void *)page->private); | 417 | inode, page, (void *)page->private); |
| 418 | /* we should only noop if called by kswapd */ | 418 | /* we should only noop if called by kswapd */ |
| @@ -557,9 +557,9 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
| 557 | dout("inode %p skipping page %p\n", inode, page); | 557 | dout("inode %p skipping page %p\n", inode, page); |
| 558 | wbc->pages_skipped++; | 558 | wbc->pages_skipped++; |
| 559 | } | 559 | } |
| 560 | ceph_put_snap_context((void *)page->private); | ||
| 560 | page->private = 0; | 561 | page->private = 0; |
| 561 | ClearPagePrivate(page); | 562 | ClearPagePrivate(page); |
| 562 | ceph_put_snap_context(snapc); | ||
| 563 | dout("unlocking %d %p\n", i, page); | 563 | dout("unlocking %d %p\n", i, page); |
| 564 | end_page_writeback(page); | 564 | end_page_writeback(page); |
| 565 | 565 | ||
| @@ -617,7 +617,7 @@ static int ceph_writepages_start(struct address_space *mapping, | |||
| 617 | int range_whole = 0; | 617 | int range_whole = 0; |
| 618 | int should_loop = 1; | 618 | int should_loop = 1; |
| 619 | pgoff_t max_pages = 0, max_pages_ever = 0; | 619 | pgoff_t max_pages = 0, max_pages_ever = 0; |
| 620 | struct ceph_snap_context *snapc = NULL, *last_snapc = NULL; | 620 | struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc; |
| 621 | struct pagevec pvec; | 621 | struct pagevec pvec; |
| 622 | int done = 0; | 622 | int done = 0; |
| 623 | int rc = 0; | 623 | int rc = 0; |
| @@ -769,9 +769,10 @@ get_more_pages: | |||
| 769 | } | 769 | } |
| 770 | 770 | ||
| 771 | /* only if matching snap context */ | 771 | /* only if matching snap context */ |
| 772 | if (snapc != (void *)page->private) { | 772 | pgsnapc = (void *)page->private; |
| 773 | dout("page snapc %p != oldest %p\n", | 773 | if (pgsnapc->seq > snapc->seq) { |
| 774 | (void *)page->private, snapc); | 774 | dout("page snapc %p %lld > oldest %p %lld\n", |
| 775 | pgsnapc, pgsnapc->seq, snapc, snapc->seq); | ||
| 775 | unlock_page(page); | 776 | unlock_page(page); |
| 776 | if (!locked_pages) | 777 | if (!locked_pages) |
| 777 | continue; /* keep looking for snap */ | 778 | continue; /* keep looking for snap */ |
| @@ -935,8 +936,8 @@ static int ceph_update_writeable_page(struct file *file, | |||
| 935 | int pos_in_page = pos & ~PAGE_CACHE_MASK; | 936 | int pos_in_page = pos & ~PAGE_CACHE_MASK; |
| 936 | int end_in_page = pos_in_page + len; | 937 | int end_in_page = pos_in_page + len; |
| 937 | loff_t i_size; | 938 | loff_t i_size; |
| 938 | struct ceph_snap_context *snapc; | ||
| 939 | int r; | 939 | int r; |
| 940 | struct ceph_snap_context *snapc, *oldest; | ||
| 940 | 941 | ||
| 941 | retry_locked: | 942 | retry_locked: |
| 942 | /* writepages currently holds page lock, but if we change that later, */ | 943 | /* writepages currently holds page lock, but if we change that later, */ |
| @@ -946,16 +947,16 @@ retry_locked: | |||
| 946 | BUG_ON(!ci->i_snap_realm); | 947 | BUG_ON(!ci->i_snap_realm); |
| 947 | down_read(&mdsc->snap_rwsem); | 948 | down_read(&mdsc->snap_rwsem); |
| 948 | BUG_ON(!ci->i_snap_realm->cached_context); | 949 | BUG_ON(!ci->i_snap_realm->cached_context); |
| 949 | if (page->private && | 950 | snapc = (void *)page->private; |
| 950 | (void *)page->private != ci->i_snap_realm->cached_context) { | 951 | if (snapc && snapc != ci->i_head_snapc) { |
| 951 | /* | 952 | /* |
| 952 | * this page is already dirty in another (older) snap | 953 | * this page is already dirty in another (older) snap |
| 953 | * context! is it writeable now? | 954 | * context! is it writeable now? |
| 954 | */ | 955 | */ |
| 955 | snapc = get_oldest_context(inode, NULL); | 956 | oldest = get_oldest_context(inode, NULL); |
| 956 | up_read(&mdsc->snap_rwsem); | 957 | up_read(&mdsc->snap_rwsem); |
| 957 | 958 | ||
| 958 | if (snapc != (void *)page->private) { | 959 | if (snapc->seq > oldest->seq) { |
| 959 | dout(" page %p snapc %p not current or oldest\n", | 960 | dout(" page %p snapc %p not current or oldest\n", |
| 960 | page, (void *)page->private); | 961 | page, (void *)page->private); |
| 961 | /* | 962 | /* |
