]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
truncate()
authorsage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Fri, 10 Feb 2006 20:46:55 +0000 (20:46 +0000)
committersage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Fri, 10 Feb 2006 20:46:55 +0000 (20:46 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@609 29311d96-e01e-0410-9327-a35deaab8ce9

ceph/ebofs/Ebofs.cc
ceph/ebofs/Onode.h
ceph/ebofs/test.ebofs.cc

index 687aaaf0e343b09eaed5b10be4f8eb65f95fca9f..b56a60077aa13d0037fd894086aede8a62c2e0f7 100644 (file)
@@ -82,7 +82,7 @@ int Ebofs::mount()
   commit_thread.create();
   finisher_thread.create();
 
-  dout(1) << "mounted " << dev.get_num_blocks() << " blocks, " << nice_blocks(dev.get_num_blocks()) << endl;
+  dout(1) << "mounted " << dev.get_device_name() << " " << dev.get_num_blocks() << " blocks, " << nice_blocks(dev.get_num_blocks()) << endl;
   mounted = true;
 
   ebofs_lock.Unlock();
@@ -169,7 +169,7 @@ int Ebofs::mkfs()
 
   dev.close();
 
-  dout(1) << "mkfs: " << dev.get_num_blocks() << " blocks, " << nice_blocks(dev.get_num_blocks()) << endl;
+  dout(1) << "mkfs: " << dev.get_device_name() << " "  << dev.get_num_blocks() << " blocks, " << nice_blocks(dev.get_num_blocks()) << endl;
   ebofs_lock.Unlock();
   return 0;
 }
@@ -1811,8 +1811,41 @@ int Ebofs::remove(object_t oid)
 
 int Ebofs::truncate(object_t oid, off_t size)
 {
+  ebofs_lock.Lock();
   dout(7) << "truncate " << hex << oid << dec << " size " << size << endl;
-  assert(0);
+  
+  Onode *on = get_onode(oid);
+  if (!on) {
+       ebofs_lock.Unlock();
+       return -ENOENT;
+  }
+  
+  int r = 0;
+  if (size > on->object_size) {
+       r = -EINVAL;  // whatever
+  } 
+  else if (size < on->object_size) {
+       // change size
+       on->object_size = size;
+       dirty_onode(on);
+       
+       // free blocks
+       block_t nblocks = 0;
+       if (size) nblocks = 1 + (size-1) / EBOFS_BLOCK_SIZE;
+       if (on->object_blocks > nblocks) {
+         vector<Extent> extra;
+         on->truncate_extents(nblocks, extra);
+         for (unsigned i=0; i<extra.size(); i++)
+               allocator.release(extra[i]);
+       }
+  }
+  else {
+       assert(size == on->object_size);
+  }
+  
+  put_onode(on);
+  ebofs_lock.Unlock();
+  return r;
 }
 
 
index 40a9ab532c688c21cb2cb2e1a59b619b92e90448..44fb6a47aa2730c3d4387f66efa2edd659334834 100644 (file)
@@ -250,6 +250,41 @@ public:
        return 0;
   }
 
+  int truncate_extents(block_t len, vector<Extent>& extra) {
+       verify_extents();
+
+       map<block_t,Extent>::iterator p = extent_map.lower_bound(len);
+       if (p != extent_map.begin() &&
+               (p == extent_map.end() || p->first > len && p->first)) {
+         p--;
+         if (p->second.length > len - p->first) {
+               Extent ex;
+               ex.start = p->second.start + (len - p->first);
+               ex.length = p->second.length - (len - p->first);
+               extra.push_back(ex);
+
+               p->second.length = len - p->first;
+               assert(p->second.length > 0);
+               
+               //cout << " got (tail of?) " << p->second << " : " << ex << endl;
+         }
+         p++;
+       }
+       
+       while (p != extent_map.end()) {
+         assert(p->first >= len);
+         extra.push_back(p->second);
+         map<block_t,Extent>::iterator n = p;
+         n++;
+         extent_map.erase(p);
+         p = n;
+       }       
+       
+       object_blocks = len;
+       verify_extents();
+       return 0;
+  }
+
 
   /* map_alloc_regions(start, len, map)
    *  map range into regions that need to be (re)allocated on disk
index 9c8de8f48c36a1a599c2523b65d36b8e3fb11808..15e2aaf8b667435d3f22f6cd915cbd0b3668dd53 100644 (file)
@@ -25,7 +25,7 @@ public:
          if (rand() % 2) a = "two";
          int l = 3;//rand() % 10;
 
-         switch (rand() % 8) {
+         switch (rand() % 9) {
          case 0:
                {
                  cout << t << " read " << oid << " at " << off << " len " << len << endl;
@@ -92,6 +92,13 @@ public:
                  }
                }
                break;
+               
+         case 8:
+               {
+                 cout << t << " truncate " << oid << " " << off << endl;
+                 fs.truncate(oid, 0);
+               }
+               break;
          }