class MedusaFile(object): def __init__(self, path, flags, *mode): global METHOD global NORMAL global SNAP global FRESH_SNAP self.path = path tf.writelines("File initiating..\n") self.file = os.fdopen(os.open("." + path, flags, *mode),flag2mode (flags)) self.fd = self.file.fileno() curdir = GetDirPath('.' + path) self.snapdir = '.' + path + '_snaps' self.snap_cnt = 0 if os.path.exists(self.snapdir): self.snap_cnt = len(os.listdir(self.snapdir)) METHOD = SNAP elif FRESH_SNAP == 1: self.snap_cnt += 1 os.mkdir(self.snapdir) os.mkdir(self.snapdir+'/snap%s' % repr(self.snap_cnt)) METHOD = SNAP FRESH_SNAP = 0 tf.writelines("File initiated..\n") def read(self, length, offset): global METHOD global NORMAL global SNAP tf.writelines("Read length: %d offset: %d\n" % (length,offset)) blk_num = offset/4096 no_blks = length/4096 + 1 blocks = [] block_read = False ## Read form the Base File (Snap 1) if METHOD == NORMAL: self.file.seek(offset) tf.writelines("Normal read\n") return self.file.read(length) ## Read blocks from the snapshots else: snap_list = range(self.snap_cnt) rev_snap_list = snap_list rev_snap_list.reverse() for i in snap_list: blocks.append(os.listdir(self.snapdir+'/snap%s' % repr(i+1))) ## list of blocks in the current snapshot off = offset bend = 0 data = '' for block in range(blk_num,blk_num+no_blks): ## loop through the blocks which are to be read for i in rev_snap_list: ## loop through snapshots (starting from latest snap) tf.writelines('Snapshot %d opened..\n' % i) if repr(block) in blocks[i]: ## Check if it is in the snapshot tf.writelines("Snap read\n") self.snap = open(self.snapdir + '/snap%d/%d' % (i+1, block),'r') self.snap.seek(off%4096) bend = 4096-(off%4096) block_read = True if length-bend <= 0: ## if only a part of block file is to be read (i.e. not till the end of block file) tf.writelines("Partial read from snap \n") data = self.snap.read(length) self.snap.close() break tf.writelines("Full block read from snap\n") data += self.snap.read(bend) length -= bend off = 4096 self.snap.close() break tf.writelines("Block not in snap\n") if block_read: block_read = False continue ## otherwise the block should be in the base file itself. So, read from there tf.writelines("Reading from Base File\n") self.file.seek(block*4096 + off%4096) bend = 4096-(off%4096) if length-bend <= 0: ## if only a part of a block is to be read (not till the end of the block) data = self.file.read(length) break data += self.file.read(bend) length -= bend off = 4096 return data
This is the filesystem class for files. Whenever a read occurs an instance is created and read function is called. In my example when accessing a file named 'mango.txt' it checks for mango.txt_snaps/snap1 dirctory and open file '0' as self.snap. But the read() returns (i.e data) a small part.... Almost all the code worked weird in this example. Apart from read(), the break and continue also works weird. When opening the file 'mango.txt' the following output is written by tf (an output file). Here METHOD is not NORMAL, self.snap_cnt is 1, blocks is [['0']] File initiating.. File initiated.. Read length: 4096 offset: 0 Snapshot 0 opened.. Snap read Partial read from snap Snapshot 0 opened.. Block not in snap Reading from Base File See the weirdness of continue and break here ?(loop was supposed to loop only once as rev_snap_list contains 0 only) -- http://mail.python.org/mailman/listinfo/python-list