From 4a40e3ad61c4fcc72799db0e07dd73f55ab2a1a7 Mon Sep 17 00:00:00 2001 From: shadow Date: Fri, 18 Jan 2008 07:24:32 +0000 Subject: [PATCH] allow userland application to be know about about lost one of stripes. b=9977 i=umka i=deen --- lustre/ChangeLog | 6 ++++++ lustre/include/lustre/lustre_idl.h | 10 ++++++++++ lustre/liblustre/rw.c | 17 +++++++++++------ lustre/llite/file.c | 16 ++++++++++------ lustre/llite/rw.c | 4 ++-- lustre/lov/lov_merge.c | 8 +++++++- lustre/obdfilter/filter_lvb.c | 2 ++ 7 files changed, 48 insertions(+), 15 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 70b403e..710e2bb 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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. diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 193ce82..d308bbc 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -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; diff --git a/lustre/liblustre/rw.c b/lustre/liblustre/rw.c index 45f5097..7d91ef8 100644 --- a/lustre/liblustre/rw.c +++ b/lustre/liblustre/rw.c @@ -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); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index dfaddb8..6e83792 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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); diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index a7973d1..8af953f 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -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)); diff --git a/lustre/lov/lov_merge.c b/lustre/lov/lov_merge.c index f13c389..802e546 100644 --- a/lustre/lov/lov_merge.c +++ b/lustre/lov/lov_merge.c @@ -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() */ diff --git a/lustre/obdfilter/filter_lvb.c b/lustre/obdfilter/filter_lvb.c index 43c69b1..0ea45f1 100644 --- a/lustre/obdfilter/filter_lvb.c +++ b/lustre/obdfilter/filter_lvb.c @@ -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; } -- 1.8.3.1