]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: apply_truncate helper, used by setattr and handle_cap_trunc
authorSage Weil <sage@newdream.net>
Fri, 4 Apr 2008 20:41:59 +0000 (13:41 -0700)
committerSage Weil <sage@newdream.net>
Fri, 4 Apr 2008 20:41:59 +0000 (13:41 -0700)
src/TODO
src/kernel/inode.c
src/kernel/super.h

index e38089a577cc1b3bda38cad4dafe47f2729e3e49..622524cd4fa094b0b226f63b843f4100f3a30da3 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -16,11 +16,8 @@ userspace client
 - reference count lease validations on path lookup?
 
 kernel client
-- truncate
-  - do locally if EXCL
-  - helper that is called when mds does a truncate
-- setattr should check lease before believing something is a no-op
-- trim expired leases so we don't indefinitely hold dcache refs...
+- trim expired leases so we don't indefinitely hold dcache/icache refs...
+- apply_truncate needs to truncate page cache, or something?
 - procfs/debugfs
   - adjust granular debug levels too
     - should we be using debugfs?
@@ -30,13 +27,10 @@ kernel client
 - vfs
  - can we use dentry_path(), if it gets merged into mainline?
 - io / osd client
-  - writepages should do io on more than 14 pages at a time!
   - carry wrbuffer/rdcache caps until data is flushed
     - this should make the utimes bit kick in
     - invalidate cache pages?
   - kick requests when new map arrives
-  - sync?
-  - sync on unmount?
   - capability changes (flush.. need way to initiate/block on writeback initiated by mds)
   - osd ack vs commit handling.  hmm!
 - mon client
index 212ca6f92304a23dc91136041c7969521c8393ef..237874c1dc00eadc312c312fd35ba2319fb58f1b 100644 (file)
@@ -934,6 +934,19 @@ out:
        return ret;     
 }
 
+void apply_truncate(struct inode *inode, loff_t size)
+{
+       spin_lock(&inode->i_lock);
+       dout(10, "apply_truncate %p size %lld -> %llu\n", inode,
+            inode->i_size, size);
+       inode->i_size = size;
+       spin_unlock(&inode->i_lock);
+
+       /*
+        * FIXME: how to truncate the page cache here?
+        */
+}
+
 int ceph_handle_cap_trunc(struct inode *inode, struct ceph_mds_file_caps *trunc,
                          struct ceph_mds_session *session)
 {
@@ -944,14 +957,7 @@ int ceph_handle_cap_trunc(struct inode *inode, struct ceph_mds_file_caps *trunc,
        dout(10, "handle_cap_trunc inode %p ci %p mds%d seq %d\n", inode, ci, 
             mds, seq);
 
-       spin_lock(&inode->i_lock);
-       dout(10, "trunc size %lld -> %llu\n", inode->i_size, size);
-       inode->i_size = size;
-       spin_unlock(&inode->i_lock);
-
-       /*
-        * FIXME: how to truncate the page cache here?
-        */
+       apply_truncate(inode, size);
        return 0;
 }
 
@@ -1048,6 +1054,7 @@ struct ceph_mds_request *prepare_setattr(struct ceph_mds_client *mdsc,
        return req;
 }
 
+
 int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
@@ -1121,7 +1128,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
        /* utimes */
        if (ia_valid & (ATTR_ATIME|ATTR_MTIME)) {
                /* do i hold CAP_EXCL? */
-               if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL) {
+               if (ceph_caps_issued(ci) & CEPH_CAP_EXCL) {
                        dout(10, "utime holding EXCL, doing locally\n");
                        inode->i_atime = attr->ia_atime;
                        inode->i_mtime = attr->ia_mtime;
@@ -1131,8 +1138,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
                    !(((ia_valid & ATTR_MTIME) &&
                       !timespec_equal(&inode->i_atime, &attr->ia_atime)) ||
                      ((ia_valid & ATTR_MTIME) && 
-                      !timespec_equal(&inode->i_mtime, &attr->ia_mtime))))
-                       return 0;  /* lease is valid, and this is a no-op */
+                      !timespec_equal(&inode->i_mtime, &attr->ia_mtime)))) {
+                       dout(10, "lease indicates utimes is a no-op\n");
+                       return 0;
+               }
                req = prepare_setattr(mdsc, dentry, CEPH_MDS_OP_UTIME);
                if (IS_ERR(req)) 
                        return PTR_ERR(req);
@@ -1148,10 +1157,19 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        /* truncate? */
-       if (ia_valid & ATTR_SIZE &&
-           attr->ia_size < inode->i_size) {  /* fixme? */
+       if (ia_valid & ATTR_SIZE) {
+               if (ceph_caps_issued(ci) & CEPH_CAP_EXCL) {
+                       dout(10, "holding EXCL, doing truncate locally\n");
+                       apply_truncate(inode, attr->ia_size);
+                       return 0;
+               }
                dout(10, "truncate: ia_size %d i_size %d\n",
                     (int)attr->ia_size, (int)inode->i_size);
+               if (ceph_inode_lease_valid(inode, CEPH_LOCK_ICONTENT) &&
+                   attr->ia_size < inode->i_size) {
+                       dout(10, "lease indicates truncate is a no-op\n");
+                       return 0; 
+               }
                if (ia_valid & ATTR_FILE) 
                        req = ceph_mdsc_create_request(mdsc, 
                                       CEPH_MDS_OP_TRUNCATE, 
index 1826233fa35ecd053de246c0547fb69fd95c3b38..771ac082ef76111f4493797587f004360798bc5e 100644 (file)
@@ -236,6 +236,15 @@ static inline int ceph_ino_compare(struct inode *inode, void *data)
  */
 extern int __ceph_caps_issued(struct ceph_inode_info *ci);
 
+static inline int ceph_caps_issued(struct ceph_inode_info *ci)
+{
+       int issued;
+       spin_lock(&ci->vfs_inode.i_lock);
+       issued = __ceph_caps_issued(ci);
+       spin_unlock(&ci->vfs_inode.i_lock);
+       return issued;
+}
+
 static inline int __ceph_caps_used(struct ceph_inode_info *ci)
 {
        int used = 0;