+ if ((rec->cr_hdr.lrh_type != CHANGELOG_REC) ||
+ (rec->cr.cr_type >= CL_LAST)) {
+ CERROR("Not a changelog rec %d/%d\n", rec->cr_hdr.lrh_type,
+ rec->cr.cr_type);
+ RETURN(-EINVAL);
+ }
+
+ if (rec->cr.cr_index < cs->cs_startrec) {
+ /* Skip entries earlier than what we are interested in */
+ CDEBUG(D_CHANGELOG, "rec="LPU64" start="LPU64"\n",
+ rec->cr.cr_index, cs->cs_startrec);
+ RETURN(0);
+ }
+
+ CDEBUG(D_CHANGELOG, LPU64" %02d%-5s "LPU64" 0x%x t="DFID" p="DFID
+ " %.*s\n", rec->cr.cr_index, rec->cr.cr_type,
+ changelog_type2str(rec->cr.cr_type), rec->cr.cr_time,
+ rec->cr.cr_flags & CLF_FLAGMASK,
+ PFID(&rec->cr.cr_tfid), PFID(&rec->cr.cr_pfid),
+ rec->cr.cr_namelen, rec->cr.cr_name);
+
+ len = sizeof(*lh) + sizeof(rec->cr) + rec->cr.cr_namelen;
+
+ /* Set up the netlink message */
+ lh = changelog_lnl_alloc(len, cs->cs_flags);
+ if (lh == NULL)
+ RETURN(-ENOMEM);
+ memcpy(lh + 1, &rec->cr, len - sizeof(*lh));
+
+ rc = libcfs_klnl_msg_put(cs->cs_pid, 0, lh);
+ CDEBUG(D_CHANGELOG, "nlmsg pid %d len %d rc %d\n", cs->cs_pid, len, rc);
+
+ OBD_FREE(lh, len);
+
+ RETURN(rc);
+}
+
+static int lproc_mdc_wr_changelog(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct obd_device *obd = data;
+ struct llog_ctxt *ctxt;
+ struct llog_handle *llh;
+ struct lnl_hdr *lnlh;
+ struct changelog_show cs = {};
+ int rc;
+
+ if (count != sizeof(cs))
+ return -EINVAL;
+
+ if (cfs_copy_from_user(&cs, buffer, sizeof(cs)))
+ return -EFAULT;
+
+ CDEBUG(D_CHANGELOG, "changelog to pid=%d start "LPU64"\n",
+ cs.cs_pid, cs.cs_startrec);