]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: send mds a cap message when we approach file_max
authorSage Weil <sage@newdream.net>
Wed, 9 Apr 2008 20:44:37 +0000 (13:44 -0700)
committerSage Weil <sage@newdream.net>
Wed, 9 Apr 2008 20:44:37 +0000 (13:44 -0700)
src/TODO
src/kernel/addr.c
src/kernel/inode.c
src/kernel/super.h
src/mds/Locker.cc
src/messages/MClientUnmount.h

index 5e3a6842746e2b951c7ab65b29e930564aab92ae..c7f9aafdfc329bd1f4ac5f1eb11f28a90a384997 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -19,12 +19,11 @@ yehuda:
 - apply_truncate needs to truncate page cache, or something?
 
 kernel client
+- somehow get a max_size bump if we lseek into a (sparse) file ...
 - why is mds_client delayed work not working?
 - file_data_version stuff!
 - deal with CAP_RDCACHE properly: invalidate cache pages?
 - trim expired leases so we don't indefinitely hold dcache/icache refs...
-- obey file_max
-- send mds a file_cap message when we approach the current file_max
 - procfs/debugfs
   - adjust granular debug levels too
     - should we be using debugfs?
index afc02756f17d70a97125ce55578af46215b7fdcb..33ff3f172c1bb51ea7fa87a5980551f94ebeb4a2 100644 (file)
@@ -452,6 +452,7 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
                          struct page *page, void *fsdata)
 {
        struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
        unsigned from = pos & (PAGE_CACHE_SIZE - 1);
 
        dout(10, "write_end file %p inode %p page %p %d~%d (%d)\n", file,
@@ -467,8 +468,12 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
        
        /* did file size increase? */
        /* (no need for i_size_read(); we caller holds i_mutex */
-       if (pos+copied > inode->i_size)
+       if (pos+copied > inode->i_size) {
                i_size_write(inode, pos + copied);
+               if ((inode->i_size << 1) >= ci->i_max_size &&
+                   (ci->i_reported_size << 1) < ci->i_max_size) 
+                       ceph_check_caps(ci, GFP_KERNEL);
+       }
 
        if (!PageUptodate(page))
                SetPageUptodate(page);
index c30ff5f81eda3f086138299084f625237dc4c498..8e73f10593474197122849e5c814f46c5f1be7b5 100644 (file)
@@ -134,6 +134,7 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info)
        ci->i_old_atime = inode->i_atime;
 
        ci->i_max_size = le64_to_cpu(info->max_size);
+       ci->i_reported_size = inode->i_size;  /* reset */
 
        inode->i_mapping->a_ops = &ceph_aops;
 
@@ -764,7 +765,7 @@ void ceph_remove_cap(struct ceph_inode_cap *cap)
  * examine currently used, wanted versus held caps.
  *  release, ack revoked caps to mds as appropriate.
  */
-void ceph_check_caps_wanted(struct ceph_inode_info *ci, gfp_t gfpmask)
+void ceph_check_caps(struct ceph_inode_info *ci, gfp_t gfpmask)
 {
        struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
        struct ceph_mds_client *mdsc = &client->mdsc;
@@ -797,6 +798,15 @@ retry:
                        goto ack;
                }
 
+               /* approaching file_max? */
+               if ((cap->issued & CEPH_CAP_WR) &&
+                   (ci->vfs_inode.i_size << 1) >= ci->i_max_size &&
+                   (ci->i_reported_size << 1) < ci->i_max_size) {
+                       dout(10, "i_size approaching max_size\n");
+                       ci->i_reported_size = ci->vfs_inode.i_size;
+                       goto ack;
+               }
+               
                if ((cap->issued & ~wanted) == 0)
                        continue;     /* nothing extra, all good */
 
@@ -861,7 +871,7 @@ void ceph_put_mode(struct ceph_inode_info *ci, int mode)
        spin_unlock(&ci->vfs_inode.i_lock);
 
        if (last)
-               ceph_check_caps_wanted(ci, GFP_KERNEL);
+               ceph_check_caps(ci, GFP_KERNEL);
 }
 
 
@@ -1001,10 +1011,13 @@ out:
 
 void apply_truncate(struct inode *inode, loff_t size)
 {
+       struct ceph_inode_info *ci = ceph_inode(inode);
+
        spin_lock(&inode->i_lock);
        dout(10, "apply_truncate %p size %lld -> %llu\n", inode,
             inode->i_size, size);
        inode->i_size = size;
+       ci->i_reported_size = size;
        spin_unlock(&inode->i_lock);
 
        /*
@@ -1021,7 +1034,6 @@ int ceph_handle_cap_trunc(struct inode *inode, struct ceph_mds_file_caps *trunc,
        u64 size = le64_to_cpu(trunc->size);
        dout(10, "handle_cap_trunc inode %p ci %p mds%d seq %d\n", inode, ci, 
             mds, seq);
-
        apply_truncate(inode, size);
        return 0;
 }
@@ -1096,7 +1108,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
             last ? "last":"");
        
        if (last) 
-               ceph_check_caps_wanted(ci, GFP_KERNEL);
+               ceph_check_caps(ci, GFP_KERNEL);
 }
 
 void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr)
@@ -1114,7 +1126,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr)
             last ? "last":"");
        
        if (last) 
-               ceph_check_caps_wanted(ci, GFP_KERNEL);
+               ceph_check_caps(ci, GFP_KERNEL);
 }
 
 
index 407dc43fd57dddbe8b23c8fbbc8a3a9dbc799f34..0ecdfa6bd74b4eea64d4a76b4d4160176a1c166f 100644 (file)
@@ -156,8 +156,8 @@ struct ceph_inode_info {
        wait_queue_head_t i_cap_wq;
 
        int i_nr_by_mode[4];
-       int i_cap_wanted;      /* what we've told the mds(s) */
-       loff_t i_max_size;     /* size authorized by mds */
+       loff_t i_max_size;      /* size authorized by mds */
+       loff_t i_reported_size; /* size we're reported to mds(s) */
        struct timespec i_old_atime;
 
        /* held references to caps */
@@ -376,7 +376,7 @@ extern int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int
 extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int got);
 extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
 extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr);
-extern void ceph_check_caps_wanted(struct ceph_inode_info *ci, gfp_t gfpmask);
+extern void ceph_check_caps(struct ceph_inode_info *ci, gfp_t gfpmask);
 extern void ceph_get_mode(struct ceph_inode_info *ci, int mode);
 extern void ceph_put_mode(struct ceph_inode_info *ci, int mode);
 
index b6f6fd1faf9e23e595f9071ad5d8c3d3fbf962c3..4d29c912cb23c8273912e3b7b974adc62878dc37 100644 (file)
@@ -560,7 +560,7 @@ bool Locker::issue_caps(CInode *in)
     inode_t *latest = in->get_projected_inode();
     int64_t inc = in->get_layout_size_increment();
     if (latest->size + inc > latest->max_size) {
-      int64_t new_max = ROUND_UP_TO(latest->size + inc/2, inc);
+      int64_t new_max = latest->max_size ? (latest->max_size << 1):inc;
       dout(10) << "increasing max_size " << latest->max_size << " -> " << new_max << dendl;
       
       inode_t *pi = in->project_inode();
@@ -925,7 +925,7 @@ void Locker::handle_client_file_caps(MClientFileCaps *m)
       pi->max_size = 0;
     } else if (increase_max) {
       int64_t inc = in->get_layout_size_increment();
-      int64_t new_max = ROUND_UP_TO(latest->size + inc, inc);
+      int64_t new_max = latest->max_size ? (latest->max_size << 1):inc;
       dout(7) << " increasing max_size " << pi->max_size << " to " << new_max << dendl;
       pi->max_size = new_max;
     }    
@@ -952,7 +952,7 @@ void Locker::handle_client_file_caps(MClientFileCaps *m)
     le->metablob.add_dir_context(in->get_parent_dir());
     le->metablob.add_primary_dentry(in->parent, true, 0, pi);
     LogSegment *ls = mds->mdlog->get_current_segment();
-    mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, ls));
+    mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, ls, increase_max));
     file_wrlock_start(&in->filelock);  // wrlock for duration of journal
   }
 
index 97e40c4c17168f9ae89dbca53100e8e8ae2dca87..4848a5bb8649158e2f525e7a9130d94c09069106 100644 (file)
 class MClientUnmount : public Message {
 public:
   MClientUnmount() : Message(CEPH_MSG_CLIENT_UNMOUNT) { }
-  /*
-  MClientUnmount(entity_inst_t i) : 
-    Message(CEPH_MSG_CLIENT_UNMOUNT),
-    inst(i) { }
-  */
-  
   const char *get_type_name() { return "client_unmount"; }
 
-  void decode_payload() { 
-    //int off = 0;
-    //::_decode(inst, payload, off);
-  }
-  void encode_payload() { 
-    //::_encode(inst, payload);
-  }
+  void decode_payload() { }
+  void encode_payload() { }
 };
 
 #endif