+static int llu_glimpse_callback(struct ldlm_lock *lock, void *reqp)
+{
+ struct ptlrpc_request *req = reqp;
+ struct inode *inode = llu_inode_from_lock(lock);
+ struct obd_export *exp;
+ struct llu_inode_info *lli;
+ struct ost_lvb *lvb;
+ struct {
+ int stripe_number;
+ __u64 size;
+ struct lov_stripe_md *lsm;
+ } data;
+ __u32 vallen = sizeof(data);
+ int rc, size = sizeof(*lvb);
+ ENTRY;
+
+ if (inode == NULL)
+ RETURN(0);
+ lli = llu_i2info(inode);
+ if (lli == NULL)
+ goto iput;
+ if (lli->lli_smd == NULL)
+ goto iput;
+ exp = llu_i2obdexp(inode);
+
+ /* First, find out which stripe index this lock corresponds to. */
+ if (lli->lli_smd->lsm_stripe_count > 1)
+ data.stripe_number = llu_lock_to_stripe_offset(inode, lock);
+ else
+ data.stripe_number = 0;
+
+ data.size = lli->lli_st_size;
+ data.lsm = lli->lli_smd;
+
+ rc = obd_get_info(exp, strlen("size_to_stripe"), "size_to_stripe",
+ &vallen, &data);
+ if (rc != 0) {
+ CERROR("obd_get_info: rc = %d\n", rc);
+ LBUG();
+ }
+
+ LDLM_DEBUG(lock, "i_size: %Lu -> stripe number %d -> size %Lu",
+ lli->lli_st_size, data.stripe_number, data.size);
+
+ rc = lustre_pack_reply(req, 1, &size, NULL);
+ if (rc) {
+ CERROR("lustre_pack_reply: %d\n", rc);
+ goto iput;
+ }
+
+ lvb = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*lvb));
+ lvb->lvb_size = data.size;
+ ptlrpc_reply(req);
+
+ iput:
+ I_RELE(inode);
+ RETURN(0);
+}
+
+__u64 lov_merge_size(struct lov_stripe_md *lsm, int kms);
+__u64 lov_merge_mtime(struct lov_stripe_md *lsm, __u64 current_time);
+
+/* NB: lov_merge_size will prefer locally cached writes if they extend the
+ * file (because it prefers KMS over RSS when larger) */
+int llu_glimpse_size(struct inode *inode, struct ost_lvb *lvb)
+{
+ struct llu_inode_info *lli = llu_i2info(inode);
+ struct llu_sb_info *sbi = llu_i2sbi(inode);
+ ldlm_policy_data_t policy = { .l_extent = { 0, OBD_OBJECT_EOF } };
+ struct lustre_handle lockh;
+ int rc, flags = LDLM_FL_HAS_INTENT;
+ ENTRY;
+
+ CDEBUG(D_DLMTRACE, "Glimpsing inode %lu\n", lli->lli_st_ino);
+
+ rc = obd_enqueue(sbi->ll_osc_exp, lli->lli_smd, LDLM_EXTENT, &policy,
+ LCK_PR, &flags, llu_extent_lock_callback,
+ ldlm_completion_ast, llu_glimpse_callback, inode,
+ sizeof(*lvb), lustre_swab_ost_lvb, &lockh);
+ if (rc > 0)
+ RETURN(-EIO);
+
+ lvb->lvb_size = lov_merge_size(lli->lli_smd, 0);
+ //inode->i_mtime = lov_merge_mtime(lli->lli_smd, inode->i_mtime);
+
+ CDEBUG(D_DLMTRACE, "glimpse: size: "LPU64"\n", lvb->lvb_size);
+
+ obd_cancel(sbi->ll_osc_exp, lli->lli_smd, LCK_PR, &lockh);
+
+ RETURN(rc);
+}
+
+int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
+ struct lov_stripe_md *lsm, int mode,
+ ldlm_policy_data_t *policy, struct lustre_handle *lockh,
+ int ast_flags)
+{
+ struct llu_sb_info *sbi = llu_i2sbi(inode);
+ struct llu_inode_info *lli = llu_i2info(inode);
+ int rc;
+ ENTRY;
+
+ LASSERT(lockh->cookie == 0);
+
+ /* XXX phil: can we do this? won't it screw the file size up? */
+ if ((fd && (fd->fd_flags & LL_FILE_IGNORE_LOCK)) ||
+ (sbi->ll_flags & LL_SBI_NOLCK))
+ RETURN(0);
+
+ CDEBUG(D_DLMTRACE, "Locking inode %lu, start "LPU64" end "LPU64"\n",
+ lli->lli_st_ino, policy->l_extent.start, policy->l_extent.end);
+
+ rc = obd_enqueue(sbi->ll_osc_exp, lsm, LDLM_EXTENT, policy, mode,
+ &ast_flags, llu_extent_lock_callback,
+ ldlm_completion_ast, llu_glimpse_callback, inode,
+ sizeof(struct ost_lvb), lustre_swab_ost_lvb, lockh);
+ if (rc > 0)
+ rc = -EIO;
+
+ if (policy->l_extent.start == 0 &&
+ policy->l_extent.end == OBD_OBJECT_EOF)
+ lli->lli_st_size = lov_merge_size(lsm, 1);
+
+ //inode->i_mtime = lov_merge_mtime(lsm, inode->i_mtime);
+
+ RETURN(rc);
+}
+
+#if 0