Implementation of setSize() using xattrs.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 17 Oct 2013 19:55:30 +0000 (21:55 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Sun, 23 Feb 2014 13:16:18 +0000 (14:16 +0100)
src/VfsNs.cpp

index bf15ee9..6b65abc 100644 (file)
@@ -277,6 +277,7 @@ ExtendedStat VfsCatalog::extendedStat(const std::string& path, bool follow) thro
   }
 
   vfsUpdateStat(meta, xattrs);
+  meta.stat.st_size = xattrs.getU64(VFS_XATTR "size", 0);
 
   meta["pool"] = std::string("vfs");
 
@@ -652,19 +653,24 @@ void VfsCatalog::setOwner(const std::string& path, uid_t newUid, gid_t newGid, b
 
 void VfsCatalog::setSize(const std::string& path, size_t newSize) throw (DmException)
 {
-  ExtendedStat file;
+  ExtendedStat meta;
+  char buf[20];
 
   if (vfsCheckPermissions(path, S_IWRITE))
     vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
 
-  file = this->vfsExtendedStat(path);
-  if (S_ISDIR(file.stat.st_mode))
-    vfsThrow(EISDIR, "'%s' is directory, can not truncate", path.c_str());
-  if (getUid(this->secCtx_) != file.stat.st_uid &&
-     checkPermissions(this->secCtx_, file.acl, file.stat, S_IWRITE) != 0) {
-    vfsThrow(EACCES, "not enough permissions for '%s' to truncate '%s'", clientName.c_str(), path.c_str());
+  meta = this->vfsExtendedStat(path);
+
+  if (S_ISDIR(meta.stat.st_mode))
+    vfsThrow(EISDIR, "'%s' is directory, can not set size", path.c_str());
+
+  if (getUid(this->secCtx_) != meta.stat.st_uid &&
+     checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IWRITE) != 0) {
+    vfsThrow(EACCES, "not enough permissions for '%s' to set size of '%s'", clientName.c_str(), path.c_str());
   }
-  wrapCall(truncate(getLocalPath(path).c_str(), newSize));
+
+  snprintf(buf, sizeof buf, "%zu", newSize);
+  vfsSetXattr(path, getLocalPath(path), VFS_XATTR "size", buf, 0);
 }