]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: for wrlock when updating max_size in issue_caps()
authorSage Weil <sage@newdream.net>
Fri, 9 Jan 2009 18:25:15 +0000 (10:25 -0800)
committerSage Weil <sage@newdream.net>
Fri, 9 Jan 2009 18:25:15 +0000 (10:25 -0800)
If check_inode_max_size() changes the lock state, teh issue_caps local
values for *_allowed etc. are out of date, and we do the wrong thing.

And in any case, we can safely update max_size even when a wrlock isn't
normally allowed, e.g. when in LONER state.

src/mds/Locker.cc
src/mds/Locker.h
src/mds/MDCache.cc

index 5060f76fa59bc9c656b7563d4b8f8922a8912dee..930fa557d59dee10f8a128eaca0d917ed84c4a09 100644 (file)
@@ -602,9 +602,11 @@ bool Locker::issue_caps(CInode *in)
 
   // should we increase max_size?
   if (in->is_file() &&
-      ((all_allowed|loner_allowed) & (CEPH_CAP_GWR<<CEPH_CAP_SFILE)) &&
+      ((all_allowed|loner_allowed) & CEPH_CAP_FILE_WR) &&
       in->is_auth())
-    check_inode_max_size(in);
+    // we force an update here, which among other things avoids twiddling
+    // the lock state.
+    check_inode_max_size(in, true);
 
   // client caps
   for (map<int, Capability*>::iterator it = in->client_caps.begin();
@@ -881,14 +883,14 @@ public:
 };
 
 
-bool Locker::check_inode_max_size(CInode *in, bool forceupdate, __u64 new_size)
+bool Locker::check_inode_max_size(CInode *in, bool force_wrlock, bool update_size, __u64 new_size)
 {
   assert(in->is_auth());
 
   inode_t *latest = in->get_projected_inode();
   uint64_t new_max = latest->max_size;
   __u64 size = latest->size;
-  if (forceupdate)
+  if (update_size)
     size = new_size;
 
   if ((in->get_caps_wanted() & ((CEPH_CAP_GWR|CEPH_CAP_GWRBUFFER) << CEPH_CAP_SFILE)) == 0)
@@ -896,13 +898,13 @@ bool Locker::check_inode_max_size(CInode *in, bool forceupdate, __u64 new_size)
   else if ((size << 1) >= latest->max_size)
     new_max = latest->max_size ? (latest->max_size << 1):in->get_layout_size_increment();
 
-  if (new_max == latest->max_size && !forceupdate)
+  if (new_max == latest->max_size && !update_size)
     return false;  // no change.
 
   dout(10) << "check_inode_max_size " << latest->max_size << " -> " << new_max
           << " on " << *in << dendl;
 
-  if (!forceupdate && !in->filelock.can_wrlock()) {
+  if (!force_wrlock && !in->filelock.can_wrlock()) {
     // lock?
     if (in->filelock.is_stable())
       file_lock(&in->filelock);
@@ -920,7 +922,7 @@ bool Locker::check_inode_max_size(CInode *in, bool forceupdate, __u64 new_size)
   inode_t *pi = in->project_inode();
   pi->version = in->pre_dirty();
   pi->max_size = new_max;
-  if (forceupdate) {
+  if (update_size) {
     dout(10) << "check_inode_max_size also forcing size " 
             << pi->size << " -> " << new_size << dendl;
     pi->size = new_size;
@@ -943,7 +945,7 @@ bool Locker::check_inode_max_size(CInode *in, bool forceupdate, __u64 new_size)
     metablob = &eu->metablob;
     le = eu;
   }
-  if (forceupdate) {  // FIXME if/when we do max_size nested accounting
+  if (update_size) {  // FIXME if/when we do max_size nested accounting
     mdcache->predirty_journal_parents(mut, metablob, in, 0, PREDIRTY_PRIMARY);
     // no cow, here!
     CDentry *parent = in->get_projected_parent_dn();
index 67fb6f66e110a5b65713763eee7227952f0dea06..a81475dbed277d1141479ea84ba105e2a5be8124 100644 (file)
@@ -223,7 +223,7 @@ public:
   void file_update_finish(CInode *in, Mutation *mut, bool share, int client,
                          MClientCaps *ack, ceph_seq_t releasecap);
 public:
-  bool check_inode_max_size(CInode *in, bool forceupdate=false, __u64 newsize=0);
+  bool check_inode_max_size(CInode *in, bool force_wrlock=false, bool update_size=false, __u64 newsize=0);
 private:
   void share_inode_max_size(CInode *in);
 
index 2859b92a6d76403918d6a6164babfd612423e4ba..91c4594d832fcca594d723ba25264ff4bd9666c0 100644 (file)
@@ -4037,7 +4037,7 @@ void MDCache::_recovered(CInode *in, int r)
     remove_inode(in);
   } else {
     // journal
-    mds->locker->check_inode_max_size(in, true, in->inode.size);
+    mds->locker->check_inode_max_size(in, true, true, in->inode.size);
     in->auth_unpin(this);
   }