- rc = filter_start_page_write(dentry->d_inode, lnb);
- if (rc) {
- CDEBUG(D_ERROR, "page err %u@"LPU64" %u/%u %p: rc %d\n",
- lnb->len, lnb->offset,
- i, obj->ioo_bufcnt, dentry, rc);
- while (lnb-- > res)
- __free_pages(lnb->page, 0);
- f_dput(dentry);
- GOTO(cleanup, rc);
+ /*
+ * ost_brw_write()->ost_nio_pages_get() already initialized
+ * lnb->page to point to the page from the per-thread page
+ * pool (bug 5137), initialize page.
+ */
+ LASSERT(lnb->page != NULL);
+ if (lnb->len != CFS_PAGE_SIZE) {
+ memset(kmap(lnb->page) + lnb->len,
+ 0, CFS_PAGE_SIZE - lnb->len);
+ kunmap(lnb->page);
+ }
+ lnb->page->index = lnb->offset >> CFS_PAGE_SHIFT;
+
+ cleanup_phase = 4;
+
+ /* If the filter writes a partial page, then has the file
+ * extended, the client will read in the whole page. the
+ * filter has to be careful to zero the rest of the partial
+ * page on disk. we do it by hand for partial extending
+ * writes, send_bio() is responsible for zeroing pages when
+ * asked to read unmapped blocks -- brw_kiovec() does this. */
+ if (lnb->len != CFS_PAGE_SIZE) {
+ __s64 maxidx;
+
+ maxidx = ((dentry->d_inode->i_size + CFS_PAGE_SIZE - 1) >>
+ CFS_PAGE_SHIFT) - 1;
+ if (maxidx >= lnb->page->index) {
+ LL_CDEBUG_PAGE(D_PAGE, lnb->page, "write %u @ "
+ LPU64" flg %x before EOF %llu\n",
+ lnb->len, lnb->offset,lnb->flags,
+ dentry->d_inode->i_size);
+ filter_iobuf_add_page(exp->exp_obd, iobuf,
+ dentry->d_inode,
+ lnb->page);
+ } else {
+ long off;
+ char *p = kmap(lnb->page);
+
+ off = lnb->offset & ~CFS_PAGE_MASK;
+ if (off)
+ memset(p, 0, off);
+ off = (lnb->offset + lnb->len) & ~CFS_PAGE_MASK;
+ if (off)
+ memset(p + off, 0, CFS_PAGE_SIZE - off);
+ kunmap(lnb->page);
+ }