diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 7ab7e35251ab74130aeecbaa0b228393577dddf1..f9df72c19affe1256b75380db1f5be18c6b8200a 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -238,6 +238,15 @@ Details : using LL_ORIGIN_REMOVEPAGE origin flag instead of LL_ORIGIN_UNKNOW for llap_from_page call in ll_removepage prevents from taking the superblock lock for a soon died page. +Severity : normal +Frequency : rare +Bugzilla : 11935 +Description: Not check open intent error before release open handle +Details : in some rare cases, the open intent error is not checked before + release open handle, which may cause + ASSERTION(open_req->rq_transno != 0), because it tries to release + the failed open handle. + -------------------------------------------------------------------------------- 2007-05-03 Cluster File Systems, Inc. <info@clusterfs.com> diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 0b45483a9a52027601649ec0269e08f592e1b19a..0db3cb4c635cb2603e30211b3e5f5c145d5a0fd9 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -288,15 +288,17 @@ static int ll_intent_file_open(struct file *file, void *lmm, /* reason for keep own exit path - don`t flood log * with messages with -ESTALE errors. */ - if (!it_disposition(itp, DISP_OPEN_OPEN)) + if (!it_disposition(itp, DISP_OPEN_OPEN) || + it_open_error(DISP_OPEN_OPEN, itp)) GOTO(out, rc); ll_release_openhandle(file->f_dentry, itp); GOTO(out_stale, rc); } - if (rc != 0) { - CERROR("lock enqueue: err: %d\n", rc); - GOTO(out, rc); + if (rc != 0 || it_open_error(DISP_OPEN_OPEN, itp)) { + rc = rc ? rc : it_open_error(DISP_OPEN_OPEN, itp); + CERROR("lock enqueue: err: %d\n", rc); + GOTO(out, rc); } if (itp->d.lustre.it_lock_mode) @@ -442,7 +444,14 @@ int ll_file_open(struct inode *inode, struct file *file) if (it_disposition(it, DISP_OPEN_OPEN)) { /* Well, there's extra open request that we do not need, let's close it somehow. This will decref request. */ + rc = it_open_error(DISP_OPEN_OPEN, it); + if (rc) { + ll_file_data_put(fd); + GOTO(out_och_free, rc); + } ll_release_openhandle(file->f_dentry, it); + lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, + LPROC_LL_OPEN); } (*och_usecount)++; @@ -1899,9 +1908,10 @@ static int join_file(struct inode *head_inode, struct file *head_filp, rc = oit.d.lustre.it_status; - if (rc < 0) { + if (rc < 0 || it_open_error(DISP_OPEN_OPEN, &oit)) { + rc = rc ? rc : it_open_error(DISP_OPEN_OPEN, &oit); ptlrpc_req_finished((struct ptlrpc_request *) - oit.d.lustre.it_data); + oit.d.lustre.it_data); GOTO(out, rc); } @@ -2028,6 +2038,8 @@ int ll_release_openhandle(struct dentry *dentry, struct lookup_intent *it) if (!it_disposition(it, DISP_OPEN_OPEN)) RETURN(0); + LASSERT(it_open_error(DISP_OPEN_OPEN, it) == 0); + OBD_ALLOC(och, sizeof(*och)); if (!och) GOTO(out, rc = -ENOMEM);