Whamcloud - gitweb
in getattr requests, get the authoritative file size from the OST
authorpschwan <pschwan>
Wed, 21 Aug 2002 23:52:51 +0000 (23:52 +0000)
committerpschwan <pschwan>
Wed, 21 Aug 2002 23:52:51 +0000 (23:52 +0000)
lustre/include/linux/lustre_lite.h
lustre/llite/file.c
lustre/llite/namei.c

index b89d829..086758e 100644 (file)
@@ -6,8 +6,8 @@
  * 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>
+ */
 
 
 
@@ -134,6 +134,9 @@ extern struct inode_operations ll_dir_inode_operations;
 /* 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,
index b1a6287..8951c43 100644 (file)
@@ -134,7 +134,7 @@ static int ll_file_release(struct inode *inode, struct file *file)
         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;
@@ -243,8 +243,8 @@ static void ll_update_atime(struct inode *inode)
         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;
@@ -321,9 +321,8 @@ static ssize_t ll_file_read(struct file *filp, char *buf, size_t count,
         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;
                 }
         }
 
index d6b71c4..052d6b1 100644 (file)
@@ -134,11 +134,52 @@ int ll_unlock(__u32 mode, struct lustre_handle *lockh)
         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;
@@ -255,10 +296,22 @@ static struct dentry *ll_lookup2(struct inode * dir, struct dentry *dentry,
                 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);