int fileTruncate(File *f, char *uid) { if(fileIsDir(f)){ vtSetError(ENotFile); return 0; } if(!fileLock(f)) return 0; if(f->source->mode != OReadWrite){ vtSetError(EReadOnly); fileUnlock(f); return 0; } if(!sourceLock(f->source, -1)){ fileUnlock(f); return 0; } if(!sourceTruncate(f->source)){ sourceUnlock(f->source); fileUnlock(f); return 0; } sourceUnlock(f->source); fileUnlock(f); fileWAccess(f, uid); return 1; }
int sourceSetSize(Source *r, uint64_t size) { int depth; Entry e; Block *b; assert(sourceIsLocked(r)); if(size == 0) return sourceTruncate(r); if(size > VtMaxFileSize || size > ((uint64_t)MaxBlock)*r->dsize) { vtSetError(ETooBig); return 0; } b = sourceLoad(r, &e); if(b == nil) return 0; /* quick out */ if(e.size == size) { blockPut(b); return 1; } depth = sizeToDepth(size, e.psize, e.dsize); if(depth < e.depth) { if(!sourceShrinkDepth(r, b, &e, depth)) { blockPut(b); return 0; } } else if(depth > e.depth) { if(!sourceGrowDepth(r, b, &e, depth)) { blockPut(b); return 0; } } if(size < e.size) sourceShrinkSize(r, &e, size); e.size = size; entryPack(&e, b->data, r->offset % r->epb); blockDirty(b); blockPut(b); return 1; }