aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 13:57:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 13:57:14 -0500
commit08d21b5f93eb92a781daea71b6fcb3a340909141 (patch)
tree365a88c9d977914a6dd42dcc1c27e33f80c0b76c
parent627f4b3ee3899bb70263ee77454a43c73136562f (diff)
parent19350e7627a6f3b0f662cbd2eb1128c9961a41fe (diff)
Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
Pull exofs and ore fixes from Boaz Harrosh: "The main fix here, the first patch, is also destined for -stable. The rest is small trivia and cosmetics. The ORE patches effect both exofs and pnfs-objects very reproducible bugs" [ ORE is "object raid engine", used by exofs and pnfs - Linus ] * 'for-linus' of git://git.open-osd.org/linux-open-osd: exofs: Print less in r4w exofs: Allow corrupted directory entry to be empty file exofs: Allow O_DIRECT open ore: Don't crash on NULL bio in _clear_bio ore: Fix wrong math in allocation of per device BIO
-rw-r--r--fs/exofs/inode.c31
-rw-r--r--fs/exofs/ore.c45
-rw-r--r--include/scsi/osd_ore.h1
3 files changed, 51 insertions, 26 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index a52a5d23c30b..ee4317faccb1 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -577,7 +577,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
577 577
578 if (offset >= i_size) { 578 if (offset >= i_size) {
579 *uptodate = true; 579 *uptodate = true;
580 EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index); 580 EXOFS_DBGMSG2("offset >= i_size index=0x%lx\n", index);
581 return ZERO_PAGE(0); 581 return ZERO_PAGE(0);
582 } 582 }
583 583
@@ -596,10 +596,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
596 *uptodate = true; 596 *uptodate = true;
597 else 597 else
598 *uptodate = PageUptodate(page); 598 *uptodate = PageUptodate(page);
599 EXOFS_DBGMSG("index=0x%lx uptodate=%d\n", index, *uptodate); 599 EXOFS_DBGMSG2("index=0x%lx uptodate=%d\n", index, *uptodate);
600 return page; 600 return page;
601 } else { 601 } else {
602 EXOFS_DBGMSG("YES that_locked_page index=0x%lx\n", 602 EXOFS_DBGMSG2("YES that_locked_page index=0x%lx\n",
603 pcol->that_locked_page->index); 603 pcol->that_locked_page->index);
604 *uptodate = true; 604 *uptodate = true;
605 return pcol->that_locked_page; 605 return pcol->that_locked_page;
@@ -611,11 +611,11 @@ static void __r4w_put_page(void *priv, struct page *page)
611 struct page_collect *pcol = priv; 611 struct page_collect *pcol = priv;
612 612
613 if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) { 613 if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) {
614 EXOFS_DBGMSG("index=0x%lx\n", page->index); 614 EXOFS_DBGMSG2("index=0x%lx\n", page->index);
615 page_cache_release(page); 615 page_cache_release(page);
616 return; 616 return;
617 } 617 }
618 EXOFS_DBGMSG("that_locked_page index=0x%lx\n", 618 EXOFS_DBGMSG2("that_locked_page index=0x%lx\n",
619 ZERO_PAGE(0) == page ? -1 : page->index); 619 ZERO_PAGE(0) == page ? -1 : page->index);
620} 620}
621 621
@@ -961,6 +961,14 @@ static void exofs_invalidatepage(struct page *page, unsigned int offset,
961 WARN_ON(1); 961 WARN_ON(1);
962} 962}
963 963
964
965 /* TODO: Should be easy enough to do proprly */
966static ssize_t exofs_direct_IO(int rw, struct kiocb *iocb,
967 const struct iovec *iov, loff_t offset, unsigned long nr_segs)
968{
969 return 0;
970}
971
964const struct address_space_operations exofs_aops = { 972const struct address_space_operations exofs_aops = {
965 .readpage = exofs_readpage, 973 .readpage = exofs_readpage,
966 .readpages = exofs_readpages, 974 .readpages = exofs_readpages,
@@ -974,7 +982,7 @@ const struct address_space_operations exofs_aops = {
974 982
975 /* Not implemented Yet */ 983 /* Not implemented Yet */
976 .bmap = NULL, /* TODO: use osd's OSD_ACT_READ_MAP */ 984 .bmap = NULL, /* TODO: use osd's OSD_ACT_READ_MAP */
977 .direct_IO = NULL, /* TODO: Should be trivial to do */ 985 .direct_IO = exofs_direct_IO,
978 986
979 /* With these NULL has special meaning or default is not exported */ 987 /* With these NULL has special meaning or default is not exported */
980 .get_xip_mem = NULL, 988 .get_xip_mem = NULL,
@@ -1010,7 +1018,7 @@ static int _do_truncate(struct inode *inode, loff_t newsize)
1010 if (likely(!ret)) 1018 if (likely(!ret))
1011 truncate_setsize(inode, newsize); 1019 truncate_setsize(inode, newsize);
1012 1020
1013 EXOFS_DBGMSG("(0x%lx) size=0x%llx ret=>%d\n", 1021 EXOFS_DBGMSG2("(0x%lx) size=0x%llx ret=>%d\n",
1014 inode->i_ino, newsize, ret); 1022 inode->i_ino, newsize, ret);
1015 return ret; 1023 return ret;
1016} 1024}
@@ -1094,14 +1102,13 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
1094 /* If object is lost on target we might as well enable it's 1102 /* If object is lost on target we might as well enable it's
1095 * delete. 1103 * delete.
1096 */ 1104 */
1097 if ((ret == -ENOENT) || (ret == -EINVAL)) 1105 ret = 0;
1098 ret = 0;
1099 goto out; 1106 goto out;
1100 } 1107 }
1101 1108
1102 ret = extract_attr_from_ios(ios, &attrs[0]); 1109 ret = extract_attr_from_ios(ios, &attrs[0]);
1103 if (ret) { 1110 if (ret) {
1104 EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); 1111 EXOFS_ERR("%s: extract_attr 0 of inode failed\n", __func__);
1105 goto out; 1112 goto out;
1106 } 1113 }
1107 WARN_ON(attrs[0].len != EXOFS_INO_ATTR_SIZE); 1114 WARN_ON(attrs[0].len != EXOFS_INO_ATTR_SIZE);
@@ -1109,7 +1116,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
1109 1116
1110 ret = extract_attr_from_ios(ios, &attrs[1]); 1117 ret = extract_attr_from_ios(ios, &attrs[1]);
1111 if (ret) { 1118 if (ret) {
1112 EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); 1119 EXOFS_ERR("%s: extract_attr 1 of inode failed\n", __func__);
1113 goto out; 1120 goto out;
1114 } 1121 }
1115 if (attrs[1].len) { 1122 if (attrs[1].len) {
@@ -1124,7 +1131,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
1124 1131
1125 ret = extract_attr_from_ios(ios, &attrs[2]); 1132 ret = extract_attr_from_ios(ios, &attrs[2]);
1126 if (ret) { 1133 if (ret) {
1127 EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); 1134 EXOFS_ERR("%s: extract_attr 2 of inode failed\n", __func__);
1128 goto out; 1135 goto out;
1129 } 1136 }
1130 if (attrs[2].len) { 1137 if (attrs[2].len) {
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index b74422888604..dae884694bd9 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -103,7 +103,7 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
103 103
104 layout->max_io_length = 104 layout->max_io_length =
105 (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * 105 (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) *
106 layout->group_width; 106 (layout->group_width - layout->parity);
107 if (layout->parity) { 107 if (layout->parity) {
108 unsigned stripe_length = 108 unsigned stripe_length =
109 (layout->group_width - layout->parity) * 109 (layout->group_width - layout->parity) *
@@ -286,7 +286,8 @@ int ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
286 if (length) { 286 if (length) {
287 ore_calc_stripe_info(layout, offset, length, &ios->si); 287 ore_calc_stripe_info(layout, offset, length, &ios->si);
288 ios->length = ios->si.length; 288 ios->length = ios->si.length;
289 ios->nr_pages = (ios->length + PAGE_SIZE - 1) / PAGE_SIZE; 289 ios->nr_pages = ((ios->offset & (PAGE_SIZE - 1)) +
290 ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
290 if (layout->parity) 291 if (layout->parity)
291 _ore_post_alloc_raid_stuff(ios); 292 _ore_post_alloc_raid_stuff(ios);
292 } 293 }
@@ -430,8 +431,12 @@ int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error)
430 if (likely(!ret)) 431 if (likely(!ret))
431 continue; 432 continue;
432 433
433 if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { 434 if ((OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) &&
434 /* start read offset passed endof file */ 435 per_dev->bio) {
436 /* start read offset passed endof file.
437 * Note: if we do not have bio it means read-attributes
438 * In this case we should return error to caller.
439 */
435 _clear_bio(per_dev->bio); 440 _clear_bio(per_dev->bio);
436 ORE_DBGMSG("start read offset passed end of file " 441 ORE_DBGMSG("start read offset passed end of file "
437 "offset=0x%llx, length=0x%llx\n", 442 "offset=0x%llx, length=0x%llx\n",
@@ -536,6 +541,7 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
536 u64 H = LmodS - G * T; 541 u64 H = LmodS - G * T;
537 542
538 u32 N = div_u64(H, U); 543 u32 N = div_u64(H, U);
544 u32 Nlast;
539 545
540 /* "H - (N * U)" is just "H % U" so it's bound to u32 */ 546 /* "H - (N * U)" is just "H % U" so it's bound to u32 */
541 u32 C = (u32)(H - (N * U)) / stripe_unit + G * group_width; 547 u32 C = (u32)(H - (N * U)) / stripe_unit + G * group_width;
@@ -568,6 +574,10 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
568 si->length = T - H; 574 si->length = T - H;
569 if (si->length > length) 575 if (si->length > length)
570 si->length = length; 576 si->length = length;
577
578 Nlast = div_u64(H + si->length + U - 1, U);
579 si->maxdevUnits = Nlast - N;
580
571 si->M = M; 581 si->M = M;
572} 582}
573EXPORT_SYMBOL(ore_calc_stripe_info); 583EXPORT_SYMBOL(ore_calc_stripe_info);
@@ -583,13 +593,16 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg,
583 int ret; 593 int ret;
584 594
585 if (per_dev->bio == NULL) { 595 if (per_dev->bio == NULL) {
586 unsigned pages_in_stripe = ios->layout->group_width * 596 unsigned bio_size;
587 (ios->layout->stripe_unit / PAGE_SIZE); 597
588 unsigned nr_pages = ios->nr_pages * ios->layout->group_width / 598 if (!ios->reading) {
589 (ios->layout->group_width - 599 bio_size = ios->si.maxdevUnits;
590 ios->layout->parity); 600 } else {
591 unsigned bio_size = (nr_pages + pages_in_stripe) / 601 bio_size = (ios->si.maxdevUnits + 1) *
592 ios->layout->group_width; 602 (ios->layout->group_width - ios->layout->parity) /
603 ios->layout->group_width;
604 }
605 bio_size *= (ios->layout->stripe_unit / PAGE_SIZE);
593 606
594 per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size); 607 per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
595 if (unlikely(!per_dev->bio)) { 608 if (unlikely(!per_dev->bio)) {
@@ -609,8 +622,12 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg,
609 added_len = bio_add_pc_page(q, per_dev->bio, pages[pg], 622 added_len = bio_add_pc_page(q, per_dev->bio, pages[pg],
610 pglen, pgbase); 623 pglen, pgbase);
611 if (unlikely(pglen != added_len)) { 624 if (unlikely(pglen != added_len)) {
612 ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=%u\n", 625 /* If bi_vcnt == bi_max then this is a SW BUG */
613 per_dev->bio->bi_vcnt); 626 ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=0x%x "
627 "bi_max=0x%x BIO_MAX=0x%x cur_len=0x%x\n",
628 per_dev->bio->bi_vcnt,
629 per_dev->bio->bi_max_vecs,
630 BIO_MAX_PAGES_KMALLOC, cur_len);
614 ret = -ENOMEM; 631 ret = -ENOMEM;
615 goto out; 632 goto out;
616 } 633 }
@@ -1098,7 +1115,7 @@ int ore_truncate(struct ore_layout *layout, struct ore_components *oc,
1098 size_attr->attr = g_attr_logical_length; 1115 size_attr->attr = g_attr_logical_length;
1099 size_attr->attr.val_ptr = &size_attr->newsize; 1116 size_attr->attr.val_ptr = &size_attr->newsize;
1100 1117
1101 ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", 1118 ORE_DBGMSG2("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
1102 _LLU(oc->comps->obj.id), _LLU(obj_size), i); 1119 _LLU(oc->comps->obj.id), _LLU(obj_size), i);
1103 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, 1120 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
1104 &size_attr->attr); 1121 &size_attr->attr);
diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h
index a5f9b960dfc8..6ca3265a4dca 100644
--- a/include/scsi/osd_ore.h
+++ b/include/scsi/osd_ore.h
@@ -102,6 +102,7 @@ struct ore_striping_info {
102 unsigned unit_off; 102 unsigned unit_off;
103 unsigned cur_pg; 103 unsigned cur_pg;
104 unsigned cur_comp; 104 unsigned cur_comp;
105 unsigned maxdevUnits;
105}; 106};
106 107
107struct ore_io_state; 108struct ore_io_state;