示例#1
0
        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);
        }