def create(self, filename, isdir=False): if DEBUG: print "Inside LFSClass:create for filename :", filename fileinodenumber = self._searchfiledir(filename) if DEBUG: print "Inside LFSClass:create 1.", fileinodenumber if fileinodenumber is not None: if not isdir: raise FileSystemException("create: cannot create file '{}': File exist".format(filename)) else: raise FileSystemException("mkdir: cannot create directory '{}': File exist".format(filename)) # create an Inode for the file # Inode constructor writes the inode to disk and implicitly updates the inode map newinode = Inode(isdirectory=isdir) # now append the <filename, inode> entry to the parent directory parentdirname = find_parent_name(filename) if DEBUG: print "Inside LFS.create, Here 1 parentdirname :", parentdirname parentdirinodenumber = self._searchfiledir(parentdirname) if parentdirinodenumber is None: raise FileSystemException("Parent Directory Does Not Exist") parentdirblockloc = InodeMap.inodemap.lookup(parentdirinodenumber) parentdirinode = Inode(str=Segment.segmentmanager.blockread(parentdirblockloc)) self.append_directory_entry(parentdirinode, find_filename(filename), newinode) if isdir: return DirectoryDescriptor(newinode.id) else: return FileDescriptor(newinode.id)
def write(self, offset, data, skip_inodemap_update=False): size = len(data) currentblock = int(math.floor(float(offset) / BLOCKSIZE)) inblockoffset = offset % BLOCKSIZE moretowrite = size if (size / BLOCKSIZE) >= MAXDATABLOCKSINODE: raise FileSystemException("Data exceeded max file size") while moretowrite > 0: if currentblock >= MAXDATABLOCKSINODE: raise FileSystemException("Data exceeded max file size") # check to see if the file has any data blocks at all if self._datablockexists(currentblock): # get the old data from the block olddata = self._getdatablockcontents(currentblock) # slice and dice so we combine the new data with the old newdata = olddata[0:inblockoffset] + data[0:( BLOCKSIZE - inblockoffset)] + olddata[inblockoffset + len(data):] else: newdata = data[0:BLOCKSIZE] # allocate a new data block datablock = Segment.segmentmanager.write_to_newblock( newdata, self.id, currentblock) self._adddatablock(currentblock, datablock) moretowrite -= (BLOCKSIZE - inblockoffset) data = data[(BLOCKSIZE - inblockoffset):] inblockoffset = 0 currentblock += 1 self.filesize = max(self.filesize, offset + size) if not skip_inodemap_update: InodeMap.inodemap.update_inode(self.id, self.serialize())
def delete_directory(self, pathname): inodenumber = self.searchfiledir(pathname) if inodenumber is None: raise FileSystemException("Directory Does Not Exist") dd = self.open(pathname, True) parentdd = self.open(find_parent_name(pathname), True) filecount = 0 for filename, inode in dd.enumerate(): filecount += 1 if filecount == 0: parentdd.delete_entry(find_filename(pathname)) else: raise FileSystemException("Can Only Delete Empty Directory")
def unlink(self, pathname): # XXXDONE - do this tomorrow! after the meteor shower! inodenumber = self.searchfiledir(pathname) if inodenumber is None: raise FileSystemException("File Does Not Exist") parentdd = self.open(find_parent_name(pathname), True) parentdd.delete_entry(find_filename(pathname))
def stat(self, pathname): inodenumber = self.searchfiledir(pathname) if inodenumber is None: raise FileSystemException("File or Directory Does Not Exist") inodeblocknumber = InodeMap.inodemap.lookup(inodenumber) inodeobject = Inode(str=Segment.segmentmanager.blockread(inodeblocknumber)) return inodeobject.filesize, inodeobject.isDirectory
def open(self, path, isdir=False): inodenumber = self.searchfiledir(path) if inodenumber is None: raise FileSystemException("Path Does Not Exist") # create and return a Descriptor of the right kind if isdir: return DirectoryDescriptor(inodenumber) else: return FileDescriptor(inodenumber)
def update_in_place(self, blockno, data): if DEBUG: print "Writing block #%d to the segment" % blockno blockoffset = blockno - 1 - self.currentseg.segmentbase if len(data) > BLOCKSIZE: print "Assertion error 1: data being written to segment is not the right size (%d != %d)" % (len(data), len(self.currentseg.blocks[blockoffset])) raise FileSystemException("Segment.update_in_place, incorrect size passed" + str(len(data))) else: self.currentseg.blocks[blockoffset] = data + self.currentseg.blocks[blockoffset][len(data):]
def _search_file_dir(self, inodenumber, tosearch): if DEBUG: print "Inside LFSClass._searchfiledir for inode and file/dir" , inodenumber, tosearch if len(tosearch) == 0: raise FileSystemException("Inside LFSClass._searchfiledir : Bad file name passed " + str(tosearch)) directory = DirectoryDescriptor(inodenumber) for name, inode in directory.enumerate(): if name == tosearch: return inode return -1
def cd(self, args): # We have to check if the given path is valid!! if len(args) != 2: print "Usage: cd dirname" return dirname = canonicalize(args[1], self.currentDirectory) size, isdir = LFS.filesystem.stat(dirname) if isdir: self.currentDirectory = dirname else: raise FileSystemException("Not a Directory")
def unlink(self, pathname, isdir=False): # XXX - do this tomorrow! after the meteor shower! fileinodenumber = self._searchfiledir(pathname) if fileinodenumber is None: if not isdir: raise FileSystemException("rmdir: cannot remove '{}': No such file or directory".format(pathname)) else: raise FileSystemException("rmdir: failed to remove '{}': No such file or directory".format(pathname)) fileblocknum = InodeMap.inodemap.lookup(fileinodenumber) fileinode = Inode(str=Segment.segmentmanager.blockread(fileblocknum)) if not isdir: if fileinode.isDirectory == 1: raise FileSystemException("rm: cannot remove '{}': Is a directory".format(pathname)) else: if fileinode.isDirectory == 0: raise FileSystemException("rmdir: failed to remove '{}': Not a directory".format(pathname)) parentdirname = find_parent_name(pathname) parentdirinodenumber = self._searchfiledir(parentdirname) if parentdirinodenumber is None: if not isdir: raise FileSystemException("rmdir: cannot remove '{}': No such file or directory".format(pathname)) else: raise FileSystemException("rmdir: failed to remove '{}': No such file or directory".format(pathname)) parentdirblockloc = InodeMap.inodemap.lookup(parentdirinodenumber) parentdirinode = Inode(str=Segment.segmentmanager.blockread(parentdirblockloc)) self.delete_directory_entry(parentdirinode, find_filename(pathname)) result = InodeMap.inodemap.remove_mapping(fileinodenumber) if result ==-1: print "Alert 2 :Check what happened, inode map is corrupt"
def create(self, filename, isdir=False): fileinodenumber = self.searchfiledir(filename) if fileinodenumber is not None: raise FileSystemException("File Already Exists") # create an Inode for the file # Inode constructor writes the inode to disk and implicitly updates the inode map newinode = Inode(isdirectory=isdir) # now append the <filename, inode> entry to the parent directory parentdirname = find_parent_name(filename) parentdirinodenumber = self.searchfiledir(parentdirname) if parentdirinodenumber is None: raise FileSystemException("Parent Directory Does Not Exist") parentdirblockloc = InodeMap.inodemap.lookup(parentdirinodenumber) parentdirinode = Inode(str=Segment.segmentmanager.blockread(parentdirblockloc)) self.append_directory_entry(parentdirinode, find_filename(filename), newinode) if isdir: return DirectoryDescriptor(newinode.id) else: return FileDescriptor(newinode.id)
def open(self, path, isdir=False): if DEBUG: print "Inside LFS.open for path :",path inodenumber = self._searchfiledir(path) if DEBUG: print "Inside LFS.open, HERE1", inodenumber if inodenumber is None: raise FileSystemException("Path Does Not Exist") # create and return a Descriptor of the right kind if isdir: return DirectoryDescriptor(inodenumber) else: return FileDescriptor(inodenumber)
def write_to_newblock(self, data, inodeid, blockoffset): # XXX - do this tomorrow! after the meteor shower! - Okay bro!! if DEBUG: print "Inside SegmentManager:write_to_newblock for datasize :", len(data) #SEE retval = -1 if len(data) > BLOCKSIZE: # NOTE- Add exception later print "Inside SegmentManager:write_to_newblock :Data length greater than Block size for data :", data return -1 retval = self.currentseg.write_to_newblock(data[:BLOCKSIZE], inodeid, blockoffset) if retval == -1: result = self._flush_and_initialize_new_segment() if result == -1: raise FileSystemException("Disk out of space, exiting") else: retval = self.currentseg.write_to_newblock(data[:BLOCKSIZE], inodeid, blockoffset) return (retval + self.currentseg.segmentbase)
def _searchfiledir(self, path): # XXX - do this tomorrow! after the meteor shower! -Ok bro:) if DEBUG: print "Inside LFSClass.searchfiledir : for path :", path if path[0]!= '/': print "Inside LFSClass.searchfiledir : Path not canonicalized properly" return None #print InodeMap.inodemap.mapping inode = 1 path = path[1:] # removing the first / pattern = "([\w|\d|_|\-|\.]*)/*(.*)" while len(path)>0: result = re.match(pattern, path, flags=re.IGNORECASE) if result: l = result.groups() inode = self._search_file_dir(inode, l[0]) if inode == -1: return None path = l[1] else: raise FileSystemException("Inside LFSClass.searchfiledir : Malformed file name passed " + str(path)) return inode
def __init__(self, inodenumber): super(DirectoryDescriptor, self).__init__(inodenumber) inodeobject = self._getinode() if not inodeobject.isDirectory: raise FileSystemException("Not a directory - inode %d" % inodenumber)
def close(self): if not self.isopen: raise FileSystemException("The File is Already Closed!") self.isopen = False