def getmetadata(path): pth = 'METADATA=' + path # print "Finding metadata for", path if not blockexists(pth): # print "No metadata for ", path, "using default" return dict(st_size=0, blocks=[], xattr={}, files=[], st_mode=(S_IFDIR | 0755), st_ctime=time(), st_mtime=time(), st_atime=time(), st_nlink=2) return simplejson.loads(getblock(pth))
def write(self, path, data, offset, fh): # print "Writing", data, path, offset, fh meta = getmetadata(path) dblocks = meta['blocks'] whichblock = offset / BLOCKSIZE whereinblock = offset % BLOCKSIZE if whichblock >= len(dblocks): curblock = "" else: curblock = getblock(dblocks[whichblock]) datalen = min(len(data), BLOCKSIZE) #only write one block at a time data = data[:datalen] #truncate data that can't be written curblock = curblock[:offset] + data + curblock[offset + datalen:] blockname = nameblock(curblock) putblock(blockname, curblock) #store the new block #now update the metadata if whichblock < len(dblocks): dblocks[whichblock] = blockname else: #new block, need to update the size sze = BLOCKSIZE * len(dblocks) #how many full blocks do we have? sze += len(curblock) #add in the length of the current block #New block, update size dblocks += [blockname] meta['st_size'] = sze meta['blocks'] = dblocks setmetadata(path, meta) return min(len(data), BLOCKSIZE)
def truncate(self, path, length, fh=None): #truncate path to length bytes meta = getmetadata(path) dblocks = meta['blocks'] numblocks = length / BLOCKSIZE lastblocklen = length % BLOCKSIZE dblocks = dblocks[:numblocks] if len(dblocks) == 0: meta['blocks'] = dblocks setmetadata(path, meta) return lastblock = getblock(dblocks[-1]) lastblock = lastblock[:lastblocklen] blockname = nameblock[block] putblock(blockname, lastblock) dblocks[-1] = blockname meta['blocks'] = dblocks setmetadata(path, meta)
def blockexists(key): return getblock(key) != ""