-#ifndef list_for_each_prev_safe
-#define list_for_each_prev_safe(pos, n, head) \
- for (pos = (head)->prev, n = pos->prev; pos != (head); \
- pos = n, n = pos->prev )
-#endif
-
-/* SYNCHRONOUS I/O to object storage for an inode */
-static int ll_brw(int cmd, struct inode *inode, struct obdo *oa,
- struct page *page, int flags)
-{
- struct ll_inode_info *lli = ll_i2info(inode);
- struct lov_stripe_md *lsm = lli->lli_smd;
- struct timeval start;
- struct brw_page pg;
- int rc;
- ENTRY;
-
- do_gettimeofday(&start);
-
- pg.pg = page;
- pg.disk_offset = pg.page_offset = ((obd_off)page->index) << PAGE_SHIFT;
-
- if (cmd == OBD_BRW_WRITE &&
- (pg.disk_offset + PAGE_SIZE > inode->i_size))
- pg.count = inode->i_size % PAGE_SIZE;
- else
- pg.count = PAGE_SIZE;
-
- CDEBUG(D_PAGE, "%s %d bytes ino %lu at "LPU64"/"LPX64"\n",
- cmd & OBD_BRW_WRITE ? "write" : "read", pg.count, inode->i_ino,
- pg.disk_offset, pg.disk_offset);
- if (pg.count == 0) {
- CERROR("ZERO COUNT: ino %lu: size %p:%Lu(%p:%Lu) idx %lu off "
- LPU64"\n", inode->i_ino, inode, inode->i_size,
- page->mapping->host, page->mapping->host->i_size,
- page->index, pg.disk_offset);
- }
-
- pg.flag = flags;
-
- if (cmd == OBD_BRW_WRITE)
- lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
- LPROC_LL_BRW_WRITE, pg.count);
- else
- lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
- LPROC_LL_BRW_READ, pg.count);
- rc = obd_brw(cmd, ll_i2dtexp(inode), oa, lsm, 1, &pg, NULL);
- if (rc == 0)
- obdo_to_inode(inode, oa, OBD_MD_FLBLOCKS);
- else if (rc != -EIO)
- CERROR("error from obd_brw: rc = %d\n", rc);
- ll_stime_record(ll_i2sbi(inode), &start,
- &ll_i2sbi(inode)->ll_brw_stime);
- RETURN(rc);
-}
-
-__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms);
-
-/*
- * this isn't where truncate starts. roughly:
- * sys_truncate->ll_setattr_raw->vmtruncate->ll_truncate
- * we grab the lock back in setattr_raw to avoid races.