aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-20 14:43:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-20 14:43:53 -0400
commitce9f8d6b39b0d8f62092477b8d96a835860fb45a (patch)
treef35de5d7aa8f0d8e711ac3027e23cf555a722c37 /fs/nfs
parent17934162875ef93fefbf5df9dfc46b7c07828fd1 (diff)
parentc999ff68029ebd0f56ccae75444f640f6d5a27d2 (diff)
Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
Pull pnfs/ore fixes from Boaz Harrosh: "These are catastrophic fixes to the pnfs objects-layout that were just discovered. They are also destined for @stable. I have found these and worked on them at around RC1 time but unfortunately went to the hospital for kidney stones and had a very slow recovery. I refrained from sending them as is, before proper testing, and surly I have found a bug just yesterday. So now they are all well tested, and have my sign-off. Other then fixing the problem at hand, and assuming there are no bugs at the new code, there is low risk to any surrounding code. And in anyway they affect only these paths that are now broken. That is RAID5 in pnfs objects-layout code. It does also affect exofs (which was not broken) but I have tested exofs and it is lower priority then objects-layout because no one is using exofs, but objects-layout has lots of users." * 'for-linus' of git://git.open-osd.org/linux-open-osd: pnfs-obj: Fix __r4w_get_page when offset is beyond i_size pnfs-obj: don't leak objio_state if ore_write/read fails ore: Unlock r4w pages in exact reverse order of locking ore: Remove support of partial IO request (NFS crash) ore: Fix NFS crash by supporting any unaligned RAID IO
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/objlayout/objio_osd.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index b47277baebab..f50d3e8d6f22 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -454,7 +454,10 @@ int objio_read_pagelist(struct nfs_read_data *rdata)
454 objios->ios->done = _read_done; 454 objios->ios->done = _read_done;
455 dprintk("%s: offset=0x%llx length=0x%x\n", __func__, 455 dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
456 rdata->args.offset, rdata->args.count); 456 rdata->args.offset, rdata->args.count);
457 return ore_read(objios->ios); 457 ret = ore_read(objios->ios);
458 if (unlikely(ret))
459 objio_free_result(&objios->oir);
460 return ret;
458} 461}
459 462
460/* 463/*
@@ -486,8 +489,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
486 struct nfs_write_data *wdata = objios->oir.rpcdata; 489 struct nfs_write_data *wdata = objios->oir.rpcdata;
487 struct address_space *mapping = wdata->header->inode->i_mapping; 490 struct address_space *mapping = wdata->header->inode->i_mapping;
488 pgoff_t index = offset / PAGE_SIZE; 491 pgoff_t index = offset / PAGE_SIZE;
489 struct page *page = find_get_page(mapping, index); 492 struct page *page;
493 loff_t i_size = i_size_read(wdata->header->inode);
494
495 if (offset >= i_size) {
496 *uptodate = true;
497 dprintk("%s: g_zero_page index=0x%lx\n", __func__, index);
498 return ZERO_PAGE(0);
499 }
490 500
501 page = find_get_page(mapping, index);
491 if (!page) { 502 if (!page) {
492 page = find_or_create_page(mapping, index, GFP_NOFS); 503 page = find_or_create_page(mapping, index, GFP_NOFS);
493 if (unlikely(!page)) { 504 if (unlikely(!page)) {
@@ -507,8 +518,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
507 518
508static void __r4w_put_page(void *priv, struct page *page) 519static void __r4w_put_page(void *priv, struct page *page)
509{ 520{
510 dprintk("%s: index=0x%lx\n", __func__, page->index); 521 dprintk("%s: index=0x%lx\n", __func__,
511 page_cache_release(page); 522 (page == ZERO_PAGE(0)) ? -1UL : page->index);
523 if (ZERO_PAGE(0) != page)
524 page_cache_release(page);
512 return; 525 return;
513} 526}
514 527
@@ -539,8 +552,10 @@ int objio_write_pagelist(struct nfs_write_data *wdata, int how)
539 dprintk("%s: offset=0x%llx length=0x%x\n", __func__, 552 dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
540 wdata->args.offset, wdata->args.count); 553 wdata->args.offset, wdata->args.count);
541 ret = ore_write(objios->ios); 554 ret = ore_write(objios->ios);
542 if (unlikely(ret)) 555 if (unlikely(ret)) {
556 objio_free_result(&objios->oir);
543 return ret; 557 return ret;
558 }
544 559
545 if (objios->sync) 560 if (objios->sync)
546 _write_done(objios->ios, objios); 561 _write_done(objios->ios, objios);