+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);
+ 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;
+
+ RETURN(rc);
+}
+
+int llu_local_size(struct inode *inode)
+{
+ ldlm_policy_data_t policy = { .l_extent = { 0, OBD_OBJECT_EOF } };
+ struct llu_inode_info *lli = llu_i2info(inode);
+ struct llu_sb_info *sbi = llu_i2sbi(inode);
+ struct lustre_handle lockh = { 0 };
+ int flags = 0;
+ int rc;
+ ENTRY;
+
+ if (lli->lli_smd->lsm_stripe_count == 0)
+ RETURN(0);
+
+ rc = obd_match(sbi->ll_dt_exp, lli->lli_smd, LDLM_EXTENT,
+ &policy, LCK_PR, &flags, inode, &lockh);
+ if (rc < 0)
+ RETURN(rc);
+ else if (rc == 0)
+ RETURN(-ENODATA);
+
+ rc = llu_merge_lvb(inode);
+ obd_cancel(sbi->ll_dt_exp, lli->lli_smd, LCK_PR, &lockh);
+ RETURN(rc);
+}