Whamcloud - gitweb
allow userland application to be know about about lost one of stripes.
authorshadow <shadow>
Fri, 18 Jan 2008 07:24:32 +0000 (07:24 +0000)
committershadow <shadow>
Fri, 18 Jan 2008 07:24:32 +0000 (07:24 +0000)
b=9977
i=umka
i=deen

lustre/ChangeLog
lustre/include/lustre/lustre_idl.h
lustre/liblustre/rw.c
lustre/llite/file.c
lustre/llite/rw.c
lustre/lov/lov_merge.c
lustre/obdfilter/filter_lvb.c

index 70b403e..710e2bb 100644 (file)
@@ -13,6 +13,12 @@ tbd  Sun Microsystems, Inc.
         removed cwd "./" (refer to Bugzilla 14399).
 
 Severity   : normal
+Bugzilla   : 9977
+Description: allow userland application know is lost one of stripes.
+Details    : fill lvb_blocks with error code on ost and return it to
+             application if error flag found.
+
+Severity   : normal
 Bugzilla   : 14607
 Description: NULL lov_tgts causing MDS oops
 Details    : more safe checks for NULL lov_tgts for avoid oops.
index 193ce82..d308bbc 100644 (file)
@@ -894,6 +894,16 @@ extern void lustre_swab_ost_last_id(obd_id *id);
 
 /* lock value block communicated between the filter and llite */
 
+/* OST_LVB_ERR_INIT is needed because the return code in rc is 
+ * negative, i.e. because ((MASK + rc) & MASK) != MASK. */
+#define OST_LVB_ERR_INIT 0xffbadbad80000000ULL
+#define OST_LVB_ERR_MASK 0xffbadbad00000000ULL
+#define OST_LVB_IS_ERR(blocks)                                          \
+        ((blocks & OST_LVB_ERR_MASK) == OST_LVB_ERR_MASK)
+#define OST_LVB_SET_ERR(blocks, rc)                                     \
+        do { blocks = OST_LVB_ERR_INIT + rc; } while (0)
+#define OST_LVB_GET_ERR(blocks)    (int)(blocks - OST_LVB_ERR_INIT)
+
 struct ost_lvb {
         __u64 lvb_size;
         __u64 lvb_mtime;
index 45f5097..7d91ef8 100644 (file)
@@ -216,22 +216,27 @@ static int llu_glimpse_callback(struct ldlm_lock *lock, void *reqp)
         return rc;
 }
 
-static void llu_merge_lvb(struct inode *inode)
+static int llu_merge_lvb(struct inode *inode)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
         struct llu_sb_info *sbi = llu_i2sbi(inode);
         struct intnl_stat *st = llu_i2stat(inode);
         struct ost_lvb lvb;
+        int rc;
         ENTRY;
 
         inode_init_lvb(inode, &lvb);
-        obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
+        rc = obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
         st->st_size = lvb.lvb_size;
         st->st_blocks = lvb.lvb_blocks;
+        /* handle st_blocks overflow gracefully */
+        if (st->st_blocks < lvb.lvb_blocks)
+                st->st_blocks = ~0UL;
         st->st_mtime = lvb.lvb_mtime;
         st->st_atime = lvb.lvb_atime;
         st->st_ctime = lvb.lvb_ctime;
-        EXIT;
+
+        RETURN(rc);
 }
 
 int llu_local_size(struct inode *inode)
@@ -254,9 +259,9 @@ int llu_local_size(struct inode *inode)
         else if (rc == 0)
                 RETURN(-ENODATA);
         
-        llu_merge_lvb(inode);
+        rc = llu_merge_lvb(inode);
         obd_cancel(sbi->ll_dt_exp, lli->lli_smd, LCK_PR, &lockh);
-        RETURN(0);
+        RETURN(rc);
 }
 
 /* NB: lov_merge_size will prefer locally cached writes if they extend the
@@ -302,7 +307,7 @@ int llu_glimpse_size(struct inode *inode)
                 RETURN(rc > 0 ? -EIO : rc);
         }
 
-        llu_merge_lvb(inode);
+        rc = llu_merge_lvb(inode);
         CDEBUG(D_DLMTRACE, "glimpse: size: "LPU64", blocks: "LPU64"\n",
                (__u64)st->st_size, (__u64)st->st_blocks);
 
index dfaddb8..6e83792 100644 (file)
@@ -1061,23 +1061,27 @@ static int ll_glimpse_callback(struct ldlm_lock *lock, void *reqp)
         return rc;
 }
 
-static void ll_merge_lvb(struct inode *inode)
+static int ll_merge_lvb(struct inode *inode)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         struct ost_lvb lvb;
+        int rc;
+
         ENTRY;
 
         ll_inode_size_lock(inode, 1);
         inode_init_lvb(inode, &lvb);
-        obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
+        rc = obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
         i_size_write(inode, lvb.lvb_size);
         inode->i_blocks = lvb.lvb_blocks;
+
         LTIME_S(inode->i_mtime) = lvb.lvb_mtime;
         LTIME_S(inode->i_atime) = lvb.lvb_atime;
         LTIME_S(inode->i_ctime) = lvb.lvb_ctime;
         ll_inode_size_unlock(inode, 1);
-        EXIT;
+
+        RETURN(rc);
 }
 
 int ll_local_size(struct inode *inode)
@@ -1100,9 +1104,9 @@ int ll_local_size(struct inode *inode)
         else if (rc == 0)
                 RETURN(-ENODATA);
 
-        ll_merge_lvb(inode);
+        rc = ll_merge_lvb(inode);
         obd_cancel(sbi->ll_dt_exp, lli->lli_smd, LCK_PR, &lockh);
-        RETURN(0);
+        RETURN(rc);
 }
 
 int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm,
@@ -1199,7 +1203,7 @@ int ll_glimpse_size(struct inode *inode, int ast_flags)
                 RETURN(rc > 0 ? -EIO : rc);
         }
 
-        ll_merge_lvb(inode);
+        rc = ll_merge_lvb(inode);
 
         CDEBUG(D_DLMTRACE, "glimpse: size: %llu, blocks: %lu\n",
                i_size_read(inode), inode->i_blocks);
index a7973d1..8af953f 100644 (file)
@@ -145,8 +145,8 @@ void ll_truncate(struct inode *inode)
          * race condition. */
         lov_stripe_lock(lli->lli_smd);
         inode_init_lvb(inode, &lvb);
-        obd_merge_lvb(ll_i2dtexp(inode), lli->lli_smd, &lvb, 0);
-        if (lvb.lvb_size == i_size_read(inode)) {
+        rc = obd_merge_lvb(ll_i2dtexp(inode), lli->lli_smd, &lvb, 0);
+        if (lvb.lvb_size == i_size_read(inode) && rc == 0) {
                 CDEBUG(D_VFSTRACE, "skipping punch for obj "LPX64", %Lu=%#Lx\n",
                        lli->lli_smd->lsm_object_id, i_size_read(inode),
                        i_size_read(inode));
index f13c389..802e546 100644 (file)
@@ -56,6 +56,7 @@ int lov_merge_lvb(struct obd_export *exp, struct lov_stripe_md *lsm,
         __u64 current_atime = lvb->lvb_atime;
         __u64 current_ctime = lvb->lvb_ctime;
         int i;
+        int rc = 0;
 
         LASSERT_SPIN_LOCKED(&lsm->lsm_lock);
 #ifdef __KERNEL__
@@ -66,6 +67,11 @@ int lov_merge_lvb(struct obd_export *exp, struct lov_stripe_md *lsm,
                 struct lov_oinfo *loi = lsm->lsm_oinfo[i];
                 obd_size lov_size, tmpsize;
 
+                if (OST_LVB_IS_ERR(loi->loi_lvb.lvb_blocks)) {
+                        rc = OST_LVB_GET_ERR(loi->loi_lvb.lvb_blocks);
+                        continue;
+                }
+
                 tmpsize = loi->loi_kms;
                 if (kms_only == 0 && loi->loi_lvb.lvb_size > tmpsize)
                         tmpsize = loi->loi_lvb.lvb_size;
@@ -93,7 +99,7 @@ int lov_merge_lvb(struct obd_export *exp, struct lov_stripe_md *lsm,
         lvb->lvb_mtime = current_mtime;
         lvb->lvb_atime = current_atime;
         lvb->lvb_ctime = current_ctime;
-        RETURN(0);
+        RETURN(rc);
 }
 
 /* Must be called under the lov_stripe_lock() */
index 43c69b1..0ea45f1 100644 (file)
@@ -95,6 +95,8 @@ static int filter_lvbo_init(struct ldlm_resource *res)
 out_dentry:
         f_dput(dentry);
 
+        if (rc)
+                OST_LVB_SET_ERR(lvb->lvb_blocks, rc);
         /* Don't free lvb data on lookup error */
         return rc;
 }