static int llog_lvfs_read_blob(struct obd_device *obd, struct file *file, void *buf, int size, loff_t off) { loff_t offset = off; int rc; rc = fsfilt_read_record(obd, file, buf, size, &offset); if (rc) { CERROR("error reading log record: rc %d\n", rc); return rc; } return 0; }
/* reads the catalog list */ int llog_get_cat_list(struct obd_device *disk_obd, char *name, int idx, int count, struct llog_catid *idarray) { struct lvfs_run_ctxt saved; struct l_file *file; int rc, rc1 = 0; int size = sizeof(*idarray) * count; loff_t off = idx * sizeof(*idarray); ENTRY; if (!count) RETURN(0); push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); file = filp_open(name, O_RDWR | O_CREAT | O_LARGEFILE, 0700); if (!file || IS_ERR(file)) { rc = PTR_ERR(file); CERROR("OBD filter: cannot open/create %s: rc = %d\n", name, rc); GOTO(out, rc); } if (!S_ISREG(file->f_dentry->d_inode->i_mode)) { CERROR("%s is not a regular file!: mode = %o\n", name, file->f_dentry->d_inode->i_mode); GOTO(out, rc = -ENOENT); } CDEBUG(D_CONFIG, "cat list: disk size=%d, read=%d\n", (int)i_size_read(file->f_dentry->d_inode), size); /* read for new ost index or for empty file */ memset(idarray, 0, size); if (i_size_read(file->f_dentry->d_inode) < off) GOTO(out, rc = 0); rc = fsfilt_read_record(disk_obd, file, idarray, size, &off); if (rc) { CERROR("OBD filter: error reading %s: rc %d\n", name, rc); GOTO(out, rc); } EXIT; out: pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); if (file && !IS_ERR(file)) rc1 = filp_close(file, 0); if (rc == 0) rc = rc1; return rc; }
static int llog_lvfs_read_blob(struct obd_device *obd, struct l_file *file, void *buf, int size, loff_t off) { loff_t offset = off; int rc; ENTRY; rc = fsfilt_read_record(obd, file, buf, size, &offset); if (rc) { CERROR("error reading log record: rc %d\n", rc); RETURN(rc); } RETURN(0); }
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) continue; /* sanity check that the start of the new buffer is no farther * than the record that we wanted. This shouldn't happen. */ rec = buf; if (le32_to_cpu(rec->lrh_index) > prev_idx) { CERROR("missed desired record? %u > %u\n", le32_to_cpu(rec->lrh_index), prev_idx); RETURN(-ENOENT); } RETURN(0); } RETURN(-EIO); }
/* sets: * - cur_offset to the furthest point read in the log file * - cur_idx to the log index preceeding cur_offset * returns -EIO/-EINVAL on error */ static int llog_lvfs_next_block(struct llog_handle *loghandle, int *cur_idx, int next_idx, __u64 *cur_offset, void *buf, int len) { int rc; ENTRY; if (len == 0 || len & (LLOG_CHUNK_SIZE - 1)) RETURN(-EINVAL); CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off "LPU64")\n", next_idx, *cur_idx, *cur_offset); 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; llog_skip_over(cur_offset, *cur_idx, next_idx); 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 < len) { /* signal the end of the valid buffer to llog_process */ memset(buf + rc, 0, len - rc); } 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); } rec = buf; tail = (struct llog_rec_tail *)((char *)buf + rc - sizeof(struct llog_rec_tail)); if (LLOG_REC_HDR_NEEDS_SWABBING(rec)) { lustre_swab_llog_rec(rec, tail); } *cur_idx = tail->lrt_index; /* 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 (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(const struct lu_env *env, struct llog_handle *loghandle, int prev_idx, void *buf, int len) { __u64 cur_offset; int rc; 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, *last_rec; struct llog_rec_tail *tail; loff_t ppos = cur_offset; rc = fsfilt_read_record(loghandle->lgh_ctxt->loc_exp->exp_obd, loghandle->lgh_file, buf, len, &cur_offset); if (rc < 0) { CERROR("Cant read llog block at log id "DOSTID "/%u offset %llu\n", POSTID(&loghandle->lgh_id.lgl_oi), loghandle->lgh_id.lgl_ogen, cur_offset); return rc; } /* put number of bytes read into rc to make code simpler */ rc = 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 "DOSTID"/%u offset%llu\n", POSTID(&loghandle->lgh_id.lgl_oi), loghandle->lgh_id.lgl_ogen, cur_offset); return -EINVAL; } rec = buf; if (LLOG_REC_HDR_NEEDS_SWABBING(rec)) lustre_swab_llog_rec(rec); tail = (struct llog_rec_tail *)(buf + rc - sizeof(struct llog_rec_tail)); /* get the last record in block */ last_rec = (struct llog_rec_hdr *)(buf + rc - le32_to_cpu(tail->lrt_len)); if (LLOG_REC_HDR_NEEDS_SWABBING(last_rec)) lustre_swab_llog_rec(last_rec); LASSERT(last_rec->lrh_index == tail->lrt_index); /* this shouldn't happen */ if (tail->lrt_index == 0) { CERROR("Invalid llog tail at log id "DOSTID"/%u offset%llu\n", POSTID(&loghandle->lgh_id.lgl_oi), loghandle->lgh_id.lgl_ogen, cur_offset); return -EINVAL; } if (tail->lrt_index < prev_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 > prev_idx) { CERROR("missed desired record? %u > %u\n", rec->lrh_index, prev_idx); return -ENOENT; } return 0; } return -EIO; }