+ if (tail->lrt_index < next_idx)
+ continue;
+
+ /* sanity check that the start of the new buffer is no farther
+ * than the record that we wanted. This shouldn't happen. */
+ if (rec->lrh_index > next_idx) {
+ CERROR("missed desired record? %u > %u\n",
+ rec->lrh_index, next_idx);
+ RETURN(-ENOENT);
+ }
+ RETURN(0);
+ }
+ RETURN(-EIO);
+}
+
+static int llog_lvfs_prev_block(struct llog_handle *loghandle,
+ int prev_idx, void *buf, int len)
+{
+ __u64 cur_offset;
+ int rc;
+ ENTRY;
+
+ if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
+ RETURN(-EINVAL);
+
+ CDEBUG(D_OTHER, "looking for log index %u\n", prev_idx);
+
+ cur_offset = LLOG_CHUNK_SIZE;
+ llog_skip_over(&cur_offset, 0, prev_idx);
+
+ while (cur_offset < i_size_read(loghandle->lgh_file->f_dentry->d_inode)) {
+ struct llog_rec_hdr *rec;
+ struct llog_rec_tail *tail;
+ loff_t ppos;
+
+ ppos = cur_offset;
+
+ rc = fsfilt_read_record(loghandle->lgh_ctxt->loc_exp->exp_obd,
+ loghandle->lgh_file, buf, len,
+ &ppos);
+ if (rc) {
+ CERROR("Cant read llog block at log id "LPU64
+ "/%u offset "LPU64"\n",
+ loghandle->lgh_id.lgl_oid,
+ loghandle->lgh_id.lgl_ogen,
+ cur_offset);
+ RETURN(rc);
+ }
+
+ /* put number of bytes read into rc to make code simpler */
+ rc = ppos - cur_offset;
+ cur_offset = ppos;
+
+ if (rc == 0) /* end of file, nothing to do */
+ RETURN(0);
+
+ if (rc < sizeof(*tail)) {
+ CERROR("Invalid llog block at log id "LPU64"/%u offset "
+ LPU64"\n", loghandle->lgh_id.lgl_oid,
+ loghandle->lgh_id.lgl_ogen, cur_offset);
+ RETURN(-EINVAL);
+ }
+
+ tail = buf + rc - sizeof(struct llog_rec_tail);
+
+ /* this shouldn't happen */
+ if (tail->lrt_index == 0) {
+ CERROR("Invalid llog tail at log id "LPU64"/%u offset "
+ LPU64"\n", loghandle->lgh_id.lgl_oid,
+ loghandle->lgh_id.lgl_ogen, cur_offset);
+ RETURN(-EINVAL);
+ }
+ if (le32_to_cpu(tail->lrt_index) < prev_idx)