Whamcloud - gitweb
- added patches from #5492 and 5654
authoryury <yury>
Wed, 13 Apr 2005 11:27:14 +0000 (11:27 +0000)
committeryury <yury>
Wed, 13 Apr 2005 11:27:14 +0000 (11:27 +0000)
lustre/include/linux/lustre_lite.h
lustre/llite/llite_lib.c
lustre/llite/llite_mmap.c
lustre/llite/rw.c
lustre/mds/mds_open.c

index 8d295ce..cb6753f 100644 (file)
@@ -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;
index 4b85446..500d95a 100644 (file)
@@ -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);
                 }
 
index 26bac6c..c763110 100644 (file)
@@ -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
index 549aec9..88b1cc0 100644 (file)
@@ -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);
index 1c1b41f..7cbc483 100644 (file)
@@ -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);
         }