public bool read(byte[] buffer, int bufoffset, int buflen, long fileoffset) { if (m_state == FILE_STATE.FILE_DELETED) { return(false); } lock (this) { if (_mywip == null || (fileoffset >= m_size)) { OPS.BZERO(buffer); return(false); } long request_end_offset = fileoffset + buflen; if (request_end_offset > m_size) { int old_buflen = buflen; long true_end_offset = m_size; DEFS.DEBUG("ERROR", "Trying to read beyond EOF = " + m_size + " (start_offset, end_offset) = " + fileoffset + "," + (fileoffset + buflen)); buflen = (int)(true_end_offset - fileoffset); DEFS.ASSERT(old_buflen >= buflen, "Something wrong in calculation"); for (int i = (bufoffset + buflen); i < (bufoffset + old_buflen); i++) { buffer[i] = 0; } } REDDY.ptrRedFS.redfs_read(_mywip, fileoffset, buffer, bufoffset, buflen); /* * VLC and office apps tries to read beyond EOF, and we end up growing the file, this happens * with filesize blowing up infinitely. */ m_size = _mywip.get_filesize(); touch(); return(true); } }
/* * Give a fsid, it looks into the iMapWip and gets a free bit. The fsid block has the * largest inode number that is currently used, and the iMapWip itself. I'm not using anylocks * for this wip since this operation will never be concurrent. All FS modification code that * may use this path already would have a lock on the rootdir. Ex duping, deleting, inserting etc. * * XXX: Note that we are never freeing the inode bit once set!. So basically this is a dummy function. * We still work because we can afford to wait for 500M inodes to allocated before we do a wrap around!!. */ private int find_free_ino_bit(int fsid) { int max_fbns = 16384; int curr_max_inode = REDDY.FSIDList[fsid].get_start_inonumber(); byte[] buffer = new byte[4096]; RedFS_Inode iMapWip = REDDY.FSIDList[fsid].get_inodemap_wip(); int fbn = OPS.OffsetToFBN(curr_max_inode / 8); for (int cfbn = fbn; cfbn < max_fbns; cfbn++) { OPS.BZERO(buffer); REDDY.ptrRedFS.redfs_read(iMapWip, (cfbn * 4096), buffer, 0, 4096); int startsearchoffset = ((cfbn == fbn) ? (curr_max_inode / 8) : 0) % 4096; int free_bit = get_free_bitoffset(startsearchoffset, buffer); if (free_bit != -1) { int free_inode = ((cfbn * (4096 * 8)) + free_bit); REDDY.ptrRedFS.redfs_write(iMapWip, (cfbn * 4096), buffer, 0, 4096); REDDY.ptrRedFS.sync(iMapWip); REDDY.FSIDList[fsid].set_inodemap_wip(iMapWip); REDDY.ptrRedFS.flush_cache(iMapWip, true); REDDY.FSIDList[fsid].set_start_inonumber(free_inode + 1); DEFS.DEBUG("IFSDMux", "Found free ino = " + free_inode + " so setting currmaxino = " + curr_max_inode + " for fsid = " + fsid); REDDY.ptrRedFS.redfs_commit_fsid(REDDY.FSIDList[fsid]); return(free_inode); } } REDDY.FSIDList[fsid].set_start_inonumber(64); REDDY.ptrRedFS.redfs_commit_fsid(REDDY.FSIDList[fsid]); //do we need this regularly? DEFS.DEBUG("FSID", "XXXXX VERY RARE EVENT XXXX INODE WRAP AROUND XXXX"); return(find_free_ino_bit(fsid)); }
public bool read(Red_Buffer wb) { if (!initialized) { return(false); } //Array.Clear(wb.buf_to_data(), 0, 4096); OPS.BZERO(wb.buf_to_data()); total_disk_reads++; if (wb.get_ondisk_dbn() == 0) { return(true); } lock (dfile) { //DEFS.DEBUG("RAID", "Reading dbn : " + wb.get_ondisk_dbn() + " level : " + wb.get_level()); dfile.Seek((long)wb.get_ondisk_dbn() * 4096, SeekOrigin.Begin); dfile.Read(wb.buf_to_data(), 0, 4096); } return(true); }