X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdc%2Fmdc_changelog.c;h=c3a65f046ce89138a369b2509fed0a73cc41683d;hb=aadc6de18ed9af8f26cc829faa5643f8b4f0bba7;hp=459f4f0879b2ee92f5304eb39c68fd9d1d410781;hpb=5ecd5a5ecfb880236b5fbc23621102239de5f5d6;p=fs%2Flustre-release.git diff --git a/lustre/mdc/mdc_changelog.c b/lustre/mdc/mdc_changelog.c index 459f4f0..c3a65f0 100644 --- a/lustre/mdc/mdc_changelog.c +++ b/lustre/mdc/mdc_changelog.c @@ -228,6 +228,11 @@ static int chlg_read_cat_process_cb(const struct lu_env *env, RETURN(rc); } + /* Check if we can skip the entire llog plain */ + if (llog_is_plain_skipable(llh->lgh_hdr, hdr, rec->cr.cr_index, + crs->crs_start_offset)) + RETURN(LLOG_SKIP_PLAIN); + /* Skip undesired records */ if (rec->cr.cr_index < crs->crs_start_offset) RETURN(0); @@ -364,6 +369,33 @@ err_out: RETURN(rc); } +static int chlg_start_thread(struct file *file) +{ + struct chlg_reader_state *crs = file->private_data; + struct task_struct *task; + int rc = 0; + + if (likely(crs->crs_prod_task)) + return 0; + if (unlikely(file->f_mode & FMODE_READ) == 0) + return 0; + + mutex_lock(&crs->crs_lock); + if (crs->crs_prod_task == NULL) { + task = kthread_run(chlg_load, crs, "chlg_load_thread"); + if (IS_ERR(task)) { + rc = PTR_ERR(task); + CERROR("%s: cannot start changelog thread: rc = %d\n", + crs->crs_ced->ced_name, rc); + GOTO(out, rc); + } + crs->crs_prod_task = task; + } +out: + mutex_unlock(&crs->crs_lock); + return rc; +} + /** * Read handler, dequeues records from the chlg_reader_state if any. * No partial records are copied to userland so this function can return less @@ -396,6 +428,10 @@ static ssize_t chlg_read(struct file *file, char __user *buff, size_t count, RETURN(-EAGAIN); } + rc = chlg_start_thread(file); + if (rc) + RETURN(rc); + rc = wait_event_interruptible(crs->crs_waitq_cons, crs->crs_rec_count > 0 || crs->crs_eof || crs->crs_err); @@ -592,8 +628,6 @@ static int chlg_open(struct inode *inode, struct file *file) { struct chlg_reader_state *crs; struct chlg_registered_dev *dev; - struct task_struct *task; - int rc; ENTRY; dev = container_of(inode->i_cdev, struct chlg_registered_dev, ced_cdev); @@ -611,25 +645,10 @@ static int chlg_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&crs->crs_rec_queue); init_waitqueue_head(&crs->crs_waitq_prod); init_waitqueue_head(&crs->crs_waitq_cons); - - if (file->f_mode & FMODE_READ) { - task = kthread_run(chlg_load, crs, "chlg_load_thread"); - if (IS_ERR(task)) { - rc = PTR_ERR(task); - CERROR("%s: cannot start changelog thread: rc = %d\n", - dev->ced_name, rc); - GOTO(err_crs, rc); - } - crs->crs_prod_task = task; - } + crs->crs_prod_task = NULL; file->private_data = crs; RETURN(0); - -err_crs: - kref_put(&dev->ced_refs, chlg_dev_clear); - OBD_FREE_PTR(crs); - return rc; } /** @@ -670,6 +689,11 @@ static unsigned int chlg_poll(struct file *file, poll_table *wait) { struct chlg_reader_state *crs = file->private_data; unsigned int mask = 0; + int rc; + + rc = chlg_start_thread(file); + if (rc) + RETURN(rc); mutex_lock(&crs->crs_lock); poll_wait(file, &crs->crs_waitq_cons, wait); @@ -807,7 +831,7 @@ int mdc_changelog_cdev_init(struct obd_device *obd) rc = chlg_minor_alloc(&minor); if (rc) - GOTO(out_unlock, rc); + GOTO(out_listrm, rc); device_initialize(&entry->ced_device); entry->ced_device.devt = MKDEV(MAJOR(mdc_changelog_dev), minor); @@ -835,6 +859,7 @@ out_device_name: out_minor: chlg_minor_free(minor); +out_listrm: list_del_init(&obd->u.cli.cl_chg_dev_linkage); list_del(&entry->ced_link);