From: Alex Zhuravlev Date: Sun, 2 May 2021 09:16:01 +0000 (+0300) Subject: LU-14663 mdc: start changelog thread upon first access X-Git-Tag: 2.14.52~26 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=72a08ea547dceb542d554e9057e0ed257138bd48 LU-14663 mdc: start changelog thread upon first access thus leaving the caller a chance to set CHANGELOG_FLAG_FOLLOW, otherwise the thread (started from open()) can reach the end of the changelog and exit early. Signed-off-by: Alex Zhuravlev Change-Id: Ic14b6c991010bbe5197b5a8b0fedf0f4007e98c1 Reviewed-on: https://review.whamcloud.com/43513 Reviewed-by: Andreas Dilger Reviewed-by: Alexander Boyko Reviewed-by: John L. Hammond Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/mdc/mdc_changelog.c b/lustre/mdc/mdc_changelog.c index 459f4f0..843c4de 100644 --- a/lustre/mdc/mdc_changelog.c +++ b/lustre/mdc/mdc_changelog.c @@ -364,6 +364,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 +423,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 +623,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 +640,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 +684,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);