Commit 08d21b5f authored by Linus Torvalds's avatar Linus Torvalds

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
parents 627f4b3e 19350e76
...@@ -577,7 +577,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) ...@@ -577,7 +577,7 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
if (offset >= i_size) { if (offset >= i_size) {
*uptodate = true; *uptodate = true;
EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index); EXOFS_DBGMSG2("offset >= i_size index=0x%lx\n", index);
return ZERO_PAGE(0); return ZERO_PAGE(0);
} }
...@@ -596,10 +596,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) ...@@ -596,10 +596,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
*uptodate = true; *uptodate = true;
else else
*uptodate = PageUptodate(page); *uptodate = PageUptodate(page);
EXOFS_DBGMSG("index=0x%lx uptodate=%d\n", index, *uptodate); EXOFS_DBGMSG2("index=0x%lx uptodate=%d\n", index, *uptodate);
return page; return page;
} else { } else {
EXOFS_DBGMSG("YES that_locked_page index=0x%lx\n", EXOFS_DBGMSG2("YES that_locked_page index=0x%lx\n",
pcol->that_locked_page->index); pcol->that_locked_page->index);
*uptodate = true; *uptodate = true;
return pcol->that_locked_page; return pcol->that_locked_page;
...@@ -611,11 +611,11 @@ static void __r4w_put_page(void *priv, struct page *page) ...@@ -611,11 +611,11 @@ static void __r4w_put_page(void *priv, struct page *page)
struct page_collect *pcol = priv; struct page_collect *pcol = priv;
if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) { if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) {
EXOFS_DBGMSG("index=0x%lx\n", page->index); EXOFS_DBGMSG2("index=0x%lx\n", page->index);
page_cache_release(page); page_cache_release(page);
return; return;
} }
EXOFS_DBGMSG("that_locked_page index=0x%lx\n", EXOFS_DBGMSG2("that_locked_page index=0x%lx\n",
ZERO_PAGE(0) == page ? -1 : page->index); ZERO_PAGE(0) == page ? -1 : page->index);
} }
...@@ -961,6 +961,14 @@ static void exofs_invalidatepage(struct page *page, unsigned int offset, ...@@ -961,6 +961,14 @@ static void exofs_invalidatepage(struct page *page, unsigned int offset,
WARN_ON(1); WARN_ON(1);
} }
/* TODO: Should be easy enough to do proprly */
static ssize_t exofs_direct_IO(int rw, struct kiocb *iocb,
const struct iovec *iov, loff_t offset, unsigned long nr_segs)
{
return 0;
}
const struct address_space_operations exofs_aops = { const struct address_space_operations exofs_aops = {
.readpage = exofs_readpage, .readpage = exofs_readpage,
.readpages = exofs_readpages, .readpages = exofs_readpages,
...@@ -974,7 +982,7 @@ const struct address_space_operations exofs_aops = { ...@@ -974,7 +982,7 @@ const struct address_space_operations exofs_aops = {
/* Not implemented Yet */ /* Not implemented Yet */
.bmap = NULL, /* TODO: use osd's OSD_ACT_READ_MAP */ .bmap = NULL, /* TODO: use osd's OSD_ACT_READ_MAP */
.direct_IO = NULL, /* TODO: Should be trivial to do */ .direct_IO = exofs_direct_IO,
/* With these NULL has special meaning or default is not exported */ /* With these NULL has special meaning or default is not exported */
.get_xip_mem = NULL, .get_xip_mem = NULL,
...@@ -1010,7 +1018,7 @@ static int _do_truncate(struct inode *inode, loff_t newsize) ...@@ -1010,7 +1018,7 @@ static int _do_truncate(struct inode *inode, loff_t newsize)
if (likely(!ret)) if (likely(!ret))
truncate_setsize(inode, newsize); truncate_setsize(inode, newsize);
EXOFS_DBGMSG("(0x%lx) size=0x%llx ret=>%d\n", EXOFS_DBGMSG2("(0x%lx) size=0x%llx ret=>%d\n",
inode->i_ino, newsize, ret); inode->i_ino, newsize, ret);
return ret; return ret;
} }
...@@ -1094,14 +1102,13 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi, ...@@ -1094,14 +1102,13 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
/* If object is lost on target we might as well enable it's /* If object is lost on target we might as well enable it's
* delete. * delete.
*/ */
if ((ret == -ENOENT) || (ret == -EINVAL)) ret = 0;
ret = 0;
goto out; goto out;
} }
ret = extract_attr_from_ios(ios, &attrs[0]); ret = extract_attr_from_ios(ios, &attrs[0]);
if (ret) { if (ret) {
EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); EXOFS_ERR("%s: extract_attr 0 of inode failed\n", __func__);
goto out; goto out;
} }
WARN_ON(attrs[0].len != EXOFS_INO_ATTR_SIZE); 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,7 +1116,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
ret = extract_attr_from_ios(ios, &attrs[1]); ret = extract_attr_from_ios(ios, &attrs[1]);
if (ret) { if (ret) {
EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); EXOFS_ERR("%s: extract_attr 1 of inode failed\n", __func__);
goto out; goto out;
} }
if (attrs[1].len) { if (attrs[1].len) {
...@@ -1124,7 +1131,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi, ...@@ -1124,7 +1131,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
ret = extract_attr_from_ios(ios, &attrs[2]); ret = extract_attr_from_ios(ios, &attrs[2]);
if (ret) { if (ret) {
EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); EXOFS_ERR("%s: extract_attr 2 of inode failed\n", __func__);
goto out; goto out;
} }
if (attrs[2].len) { if (attrs[2].len) {
......
...@@ -103,7 +103,7 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout) ...@@ -103,7 +103,7 @@ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
layout->max_io_length = layout->max_io_length =
(BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) * (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) *
layout->group_width; (layout->group_width - layout->parity);
if (layout->parity) { if (layout->parity) {
unsigned stripe_length = unsigned stripe_length =
(layout->group_width - layout->parity) * (layout->group_width - layout->parity) *
...@@ -286,7 +286,8 @@ int ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc, ...@@ -286,7 +286,8 @@ int ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
if (length) { if (length) {
ore_calc_stripe_info(layout, offset, length, &ios->si); ore_calc_stripe_info(layout, offset, length, &ios->si);
ios->length = ios->si.length; ios->length = ios->si.length;
ios->nr_pages = (ios->length + PAGE_SIZE - 1) / PAGE_SIZE; ios->nr_pages = ((ios->offset & (PAGE_SIZE - 1)) +
ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
if (layout->parity) if (layout->parity)
_ore_post_alloc_raid_stuff(ios); _ore_post_alloc_raid_stuff(ios);
} }
...@@ -430,8 +431,12 @@ int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error) ...@@ -430,8 +431,12 @@ int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error)
if (likely(!ret)) if (likely(!ret))
continue; continue;
if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { if ((OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) &&
/* start read offset passed endof file */ per_dev->bio) {
/* start read offset passed endof file.
* Note: if we do not have bio it means read-attributes
* In this case we should return error to caller.
*/
_clear_bio(per_dev->bio); _clear_bio(per_dev->bio);
ORE_DBGMSG("start read offset passed end of file " ORE_DBGMSG("start read offset passed end of file "
"offset=0x%llx, length=0x%llx\n", "offset=0x%llx, length=0x%llx\n",
...@@ -536,6 +541,7 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, ...@@ -536,6 +541,7 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
u64 H = LmodS - G * T; u64 H = LmodS - G * T;
u32 N = div_u64(H, U); u32 N = div_u64(H, U);
u32 Nlast;
/* "H - (N * U)" is just "H % U" so it's bound to u32 */ /* "H - (N * U)" is just "H % U" so it's bound to u32 */
u32 C = (u32)(H - (N * U)) / stripe_unit + G * group_width; 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,6 +574,10 @@ void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
si->length = T - H; si->length = T - H;
if (si->length > length) if (si->length > length)
si->length = length; si->length = length;
Nlast = div_u64(H + si->length + U - 1, U);
si->maxdevUnits = Nlast - N;
si->M = M; si->M = M;
} }
EXPORT_SYMBOL(ore_calc_stripe_info); EXPORT_SYMBOL(ore_calc_stripe_info);
...@@ -583,13 +593,16 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, ...@@ -583,13 +593,16 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg,
int ret; int ret;
if (per_dev->bio == NULL) { if (per_dev->bio == NULL) {
unsigned pages_in_stripe = ios->layout->group_width * unsigned bio_size;
(ios->layout->stripe_unit / PAGE_SIZE);
unsigned nr_pages = ios->nr_pages * ios->layout->group_width / if (!ios->reading) {
(ios->layout->group_width - bio_size = ios->si.maxdevUnits;
ios->layout->parity); } else {
unsigned bio_size = (nr_pages + pages_in_stripe) / bio_size = (ios->si.maxdevUnits + 1) *
ios->layout->group_width; (ios->layout->group_width - ios->layout->parity) /
ios->layout->group_width;
}
bio_size *= (ios->layout->stripe_unit / PAGE_SIZE);
per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size); per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
if (unlikely(!per_dev->bio)) { if (unlikely(!per_dev->bio)) {
...@@ -609,8 +622,12 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, ...@@ -609,8 +622,12 @@ int _ore_add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg,
added_len = bio_add_pc_page(q, per_dev->bio, pages[pg], added_len = bio_add_pc_page(q, per_dev->bio, pages[pg],
pglen, pgbase); pglen, pgbase);
if (unlikely(pglen != added_len)) { if (unlikely(pglen != added_len)) {
ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=%u\n", /* If bi_vcnt == bi_max then this is a SW BUG */
per_dev->bio->bi_vcnt); ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=0x%x "
"bi_max=0x%x BIO_MAX=0x%x cur_len=0x%x\n",
per_dev->bio->bi_vcnt,
per_dev->bio->bi_max_vecs,
BIO_MAX_PAGES_KMALLOC, cur_len);
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
...@@ -1098,7 +1115,7 @@ int ore_truncate(struct ore_layout *layout, struct ore_components *oc, ...@@ -1098,7 +1115,7 @@ int ore_truncate(struct ore_layout *layout, struct ore_components *oc,
size_attr->attr = g_attr_logical_length; size_attr->attr = g_attr_logical_length;
size_attr->attr.val_ptr = &size_attr->newsize; size_attr->attr.val_ptr = &size_attr->newsize;
ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", ORE_DBGMSG2("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
_LLU(oc->comps->obj.id), _LLU(obj_size), i); _LLU(oc->comps->obj.id), _LLU(obj_size), i);
ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
&size_attr->attr); &size_attr->attr);
......
...@@ -102,6 +102,7 @@ struct ore_striping_info { ...@@ -102,6 +102,7 @@ struct ore_striping_info {
unsigned unit_off; unsigned unit_off;
unsigned cur_pg; unsigned cur_pg;
unsigned cur_comp; unsigned cur_comp;
unsigned maxdevUnits;
}; };
struct ore_io_state; struct ore_io_state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment