* This code is issued under the GNU General Public License.
* See the file COPYING in this distribution
*
- *
- *
+ * Copyright (C) 2002 Cluster File Systems, Inc. <info@clusterfs.com>
+ */
/* file.c */
extern struct file_operations ll_file_operations;
extern struct inode_operations ll_file_inode_operations;
+struct ldlm_lock;
+int ll_lock_callback(struct ldlm_lock *, struct ldlm_lock_desc *, void *data,
+ __u32 data_len);
/* rw.c */
struct page *ll_getpage(struct inode *inode, unsigned long offset,
struct obdo *oa;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ll_inode_info *lli = ll_i2info(inode);
- struct obd_device *obddev = class_conn2obd(&sbi->ll_osc_conn);
+ //struct obd_device *obddev = class_conn2obd(&sbi->ll_osc_conn);
struct list_head *tmp, *next;
ENTRY;
ll_inode_setattr(inode, &attr, 0);
}
-static int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new,
- void *data, __u32 data_len)
+int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new,
+ void *data, __u32 data_len)
{
struct inode *inode = data;
struct lustre_handle lockh;
if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) {
err = obd_cancel(&sbi->ll_osc_conn, md, LCK_PR, lockhs);
if (err != ELDLM_OK) {
- OBD_FREE(lockhs, md->lmd_stripe_count * sizeof(*lockhs));
CERROR("lock cancel: err: %d\n", err);
- RETURN(err);
+ retval = err;
}
}
RETURN(0);
}
-static struct dentry *ll_lookup2(struct inode * dir, struct dentry *dentry,
+static int ll_file_size(struct inode *inode, obd_id ino,
+ struct lov_stripe_md *md, __u64 *size)
+{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct obdo oa;
+ struct lustre_handle *lockhs = NULL;
+ struct ldlm_extent extent;
+ int err, rc, flags = 0;
+
+ OBD_ALLOC(lockhs, md->lmd_stripe_count * sizeof(*lockhs));
+ if (lockhs == NULL)
+ RETURN(-ENOMEM);
+
+ extent.start = 0;
+ extent.end = ~0;
+
+ rc = obd_enqueue(&sbi->ll_osc_conn, md, NULL, LDLM_EXTENT, &extent,
+ sizeof(extent), LCK_PR, &flags, ll_lock_callback,
+ inode, sizeof(*inode), lockhs);
+ if (rc != ELDLM_OK) {
+ CERROR("lock enqueue: %d\n", rc);
+ GOTO(out, rc);
+ }
+
+ oa.o_id = ino;
+ oa.o_mode = S_IFREG;
+ oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLSIZE;
+ rc = obd_getattr(&sbi->ll_osc_conn, &oa, md);
+ if (!rc)
+ *size = oa.o_size;
+
+ err = obd_cancel(&sbi->ll_osc_conn, md, LCK_PR, lockhs);
+ if (err != ELDLM_OK) {
+ CERROR("lock cancel: %d\n", err);
+ LBUG();
+ }
+
+ out:
+ OBD_FREE(lockhs, md->lmd_stripe_count * sizeof(*lockhs));
+ RETURN(rc);
+}
+
+static struct dentry *ll_lookup2(struct inode *dir, struct dentry *dentry,
struct lookup_intent *it)
{
struct ptlrpc_request *request = NULL;
- struct ptlrpc_request *getattr_req = NULL;
struct inode * inode = NULL;
struct ll_sb_info *sbi = ll_i2sbi(dir);
struct ll_inode_md md;
ll_intent_release(dentry);
RETURN(ERR_PTR(-ENOMEM));
}
+
+ /* Get the authoritative file size */
+#warning FIXME: race condition exists between iget4 and this update!
+ if ((it->it_op & IT_GETATTR) && (inode->i_mode & S_IFREG)) {
+ err = ll_file_size(inode, md.md->lmd_object_id, md.md,
+ &inode->i_size);
+ if (err) {
+ CERROR("ll_file_size: %d\n", err);
+ /* FIXME: need to destroy inode here */
+ GOTO(neg_req, err);
+ }
+ }
+
EXIT;
neg_req:
ptlrpc_free_req(request);
- ptlrpc_free_req(getattr_req);
negative:
dentry->d_op = &ll_d_ops;
d_add(dentry, inode);