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.
/* 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;
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)
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
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);
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)
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,
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);
* 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));
__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__
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;
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() */
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;
}