From 8c8662fc548bb106e2efa59485d40fdc018efd9b Mon Sep 17 00:00:00 2001 From: yury Date: Wed, 13 Apr 2005 11:27:14 +0000 Subject: [PATCH] - added patches from #5492 and 5654 --- lustre/include/linux/lustre_lite.h | 1 + lustre/llite/llite_lib.c | 6 +++--- lustre/llite/llite_mmap.c | 20 ++++++++++++-------- lustre/llite/rw.c | 26 +++++++++++++++++++------- lustre/mds/mds_open.c | 3 +-- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index 8d295ce..cb6753f 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -71,6 +71,7 @@ extern struct file_operations ll_pgcache_seq_fops; #define LLI_F_PREFER_EXTENDED_SIZE 2 struct ll_inode_info { + int lli_size_pid; int lli_inode_magic; struct lov_stripe_md *lli_smd; struct mea *lli_mea; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 4b85446..500d95a 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -418,6 +418,7 @@ void ll_lli_init(struct ll_inode_info *lli) sema_init(&lli->lli_open_sem, 1); sema_init(&lli->lli_size_sem, 1); lli->lli_flags = 0; + lli->lli_size_pid = 0; lli->lli_maxbytes = PAGE_CACHE_MAXBYTES; spin_lock_init(&lli->lli_lock); INIT_LIST_HEAD(&lli->lli_pending_write_llaps); @@ -1044,7 +1045,6 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) * inode ourselves so we can call obdo_from_inode() always. */ if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN /*| ATTR_RAW*/) : ~0)) { struct lustre_md md; - int save_valid; OBD_ALLOC(op_data, sizeof(*op_data)); if (op_data == NULL) @@ -1073,10 +1073,8 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) * * NB: ATTR_SIZE will only be set at this point if the size * resides on the MDS, ie, this file has no objects. */ - save_valid = attr->ia_valid; attr->ia_valid &= ~ATTR_SIZE; inode_setattr(inode, attr); - attr->ia_valid = save_valid; ll_update_inode(inode, &md); ptlrpc_req_finished(request); @@ -1133,9 +1131,11 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) RETURN(rc); down(&lli->lli_size_sem); + lli->lli_size_pid = current->pid; rc = vmtruncate(inode, attr->ia_size); if (rc != 0) { LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + lli->lli_size_pid = 0; up(&lli->lli_size_sem); } diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index 26bac6c..c763110 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -347,14 +347,15 @@ struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address, struct lustre_handle lockh = { 0 }; ldlm_policy_data_t policy; ldlm_mode_t mode; - struct page *page; + struct page *page = NULL; + struct ll_inode_info *lli = ll_i2info(inode); struct obd_service_time *stime; __u64 kms; unsigned long pgoff, size, rand_read, seq_read; int rc = 0; ENTRY; - if (ll_i2info(inode)->lli_smd == NULL) { + if (lli->lli_smd == NULL) { CERROR("No lsm on fault?\n"); RETURN(NULL); } @@ -363,28 +364,31 @@ struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address, policy_from_vma(&policy, vma, address, PAGE_CACHE_SIZE); CDEBUG(D_MMAP, "nopage vma %p inode %lu, locking ["LPU64", "LPU64"]\n", - vma, inode->i_ino, policy.l_extent.start, - policy.l_extent.end); + vma, inode->i_ino, policy.l_extent.start, policy.l_extent.end); mode = mode_from_vma(vma); stime = (mode & LCK_PW) ? &ll_i2sbi(inode)->ll_write_stime : &ll_i2sbi(inode)->ll_read_stime; - rc = ll_extent_lock(fd, inode, ll_i2info(inode)->lli_smd, mode, &policy, + rc = ll_extent_lock(fd, inode, lli->lli_smd, mode, &policy, &lockh, LDLM_FL_CBPENDING, stime); if (rc != 0) RETURN(NULL); /* XXX change inode size without i_sem hold! there is a race condition * with truncate path. (see ll_extent_lock) */ - kms = lov_merge_size(ll_i2info(inode)->lli_smd, 1); + down(&lli->lli_size_sem); + kms = lov_merge_size(lli->lli_smd, 1); pgoff = ((address - vma->vm_start) >> PAGE_CACHE_SHIFT) + vma->vm_pgoff; size = (kms + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - if (pgoff >= size) + if (pgoff >= size) { + up(&lli->lli_size_sem); ll_glimpse_size(inode); - else + } else { inode->i_size = kms; + up(&lli->lli_size_sem); + } /* disable VM_SEQ_READ and use VM_RAND_READ to make sure that * the kernel will not read other pages not covered by ldlm in diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 549aec9..88b1cc0 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -130,6 +130,10 @@ void ll_truncate(struct inode *inode) GOTO(out_unlock, 0); } + if (lli->lli_size_pid != current->pid) + GOTO(out_unlock, 0); + LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + if (lov_merge_size(lsm, 0) == inode->i_size) { CDEBUG(D_VFSTRACE, "skipping punch for "LPX64" (size = %llu)\n", lsm->lsm_object_id, inode->i_size); @@ -155,7 +159,7 @@ void ll_truncate(struct inode *inode) obd_adjust_kms(ll_i2dtexp(inode), lsm, inode->i_size, 1); - LASSERT(atomic_read(&lli->lli_size_sem.count) <= 0); + lli->lli_size_pid = 0; up(&lli->lli_size_sem); rc = obd_punch(ll_i2dtexp(inode), oa, lsm, inode->i_size, @@ -287,7 +291,8 @@ static int ll_ap_make_ready(void *data, int cmd) * * 1) Further extending writes may have landed in the page cache * since a partial write first queued this page requiring us - * to write more from the page cache. + * to write more from the page cache. (No further races are possible, since + * by the time this is called, the page is locked.) * 2) We might have raced with truncate and want to avoid performing * write RPCs that are just going to be thrown away by the * truncate's punch on the storage targets. @@ -297,6 +302,7 @@ static int ll_ap_make_ready(void *data, int cmd) */ static int ll_ap_refresh_count(void *data, int cmd) { + struct ll_inode_info *lli; struct ll_async_page *llap; struct lov_stripe_md *lsm; struct page *page; @@ -308,8 +314,12 @@ static int ll_ap_refresh_count(void *data, int cmd) llap = LLAP_FROM_COOKIE(data); page = llap->llap_page; - lsm = ll_i2info(page->mapping->host)->lli_smd; + lli = ll_i2info(page->mapping->host); + lsm = lli->lli_smd; + + down(&lli->lli_size_sem); kms = lov_merge_size(lsm, 1); + up(&lli->lli_size_sem); /* catch race with truncate */ if (((__u64)page->index << PAGE_SHIFT) >= kms) @@ -708,7 +718,7 @@ void ll_removepage(struct page *page) EXIT; } -static int ll_page_matches(struct page *page, int fd_flags) +static int ll_page_matches(struct page *page, int fd_flags, int readahead) { struct lustre_handle match_lockh = {0}; struct inode *inode = page->mapping->host; @@ -722,7 +732,9 @@ static int ll_page_matches(struct page *page, int fd_flags) page_extent.l_extent.start = (__u64)page->index << PAGE_CACHE_SHIFT; page_extent.l_extent.end = page_extent.l_extent.start + PAGE_CACHE_SIZE - 1; - flags = LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK; + flags = LDLM_FL_TEST_LOCK; + if (!readahead) + flags |= LDLM_FL_CBPENDING | LDLM_FL_BLOCK_GRANTED; matches = obd_match(ll_i2sbi(inode)->ll_dt_exp, ll_i2info(inode)->lli_smd, LDLM_EXTENT, &page_extent, LCK_PR | LCK_PW, &flags, inode, @@ -858,7 +870,7 @@ static int ll_readahead(struct ll_readahead_state *ras, goto next_page; /* bail when we hit the end of the lock. */ - if ((rc = ll_page_matches(page, flags)) <= 0) { + if ((rc = ll_page_matches(page, flags, 1)) <= 0) { LL_CDEBUG_PAGE(D_READA | D_PAGE, page, "lock match failed: rc %d\n", rc); ll_ra_stats_inc(mapping, RA_STAT_FAILED_MATCH); @@ -1050,7 +1062,7 @@ int ll_readpage(struct file *filp, struct page *page) GOTO(out_oig, rc = 0); } - rc = ll_page_matches(page, fd->fd_flags); + rc = ll_page_matches(page, fd->fd_flags, 0); if (rc < 0) { LL_CDEBUG_PAGE(D_ERROR, page, "lock match failed: rc %d\n", rc); GOTO(out, rc); diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 1c1b41f..7cbc483 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -1558,8 +1558,7 @@ int mds_close(struct ptlrpc_request *req, int offset) mfd = mds_handle2mfd(&body->handle); if (mfd == NULL) { DEBUG_REQ(D_ERROR, req, "no handle for file close ino "LPD64 - ": cookie "LPX64, body->id1.li_stc.u.e3s.l3s_ino, - body->handle.cookie); + ": cookie "LPX64, id_ino(&body->id1), body->handle.cookie); req->rq_status = -ESTALE; RETURN(-ESTALE); } -- 1.8.3.1