private void CheckSumBuf(RedFS_Inode wip, Red_Buffer wb)
        {
            lock (fpcache_buf)
            {
                if (fpcache_cnt == 1024)
                {
                    fpcache_cnt = 0;
                    clogfile.Write(fpcache_buf, 0, fpcache_buf.Length);
                    clogfile.Flush();
                }

                if (wb.get_level() == 0 && wip.get_wiptype() == WIP_TYPE.REGULAR_FILE)
                {
                    fingerprintCLOG fpt = (fingerprintCLOG)fptemp;

                    fpt.fsid  = wip.get_filefsid();
                    fpt.inode = wip.get_ino();
                    fpt.fbn   = (int)wb.get_start_fbn();
                    fpt.dbn   = wb.get_ondisk_dbn();
                    fpt.cnt   = (int)clogfile.Position;

                    byte[] hash = md5.ComputeHash(wb.buf_to_data());
                    for (int i = 0; i < 16; i++)
                    {
                        fpt.fp[i] = hash[i];
                    }

                    fptemp.get_bytes(fpcache_buf, fpcache_cnt * fptemp.get_size());
                    fpcache_cnt++;
                }
            }
        }
예제 #2
0
 public static void dumplistcontents(List <Red_Buffer> list)
 {
     DEFS.DEBUGCLR("DIMP", "Dumping list contents");
     for (int idx = 0; idx < list.Count; idx++)
     {
         Red_Buffer wb = (Red_Buffer)list.ElementAt(idx);
         DEFS.DEBUG("DUMPLIST", "-> (" + wb.get_level() + ")" + wb.get_ondisk_dbn() + " l=" +
                    wb.get_start_fbn() + " isdirty = " + ((RedBufL0)wb).is_dirty);
     }
 }
예제 #3
0
        /*
         * public static Red_Buffer get_buf2(string who, RedFS_Inode wip, int level, int some_fbn, bool isquery)
         * {
         *  DEFS.DEBUG("getbuf", "-> " + who + "," + wip.m_ino + "," + level + "," + some_fbn + "," + isquery);
         *  Red_Buffer retbuf = wip.FindOrInsertOrRemoveBuf(FIR_OPTYPE.FIND, level, some_fbn, null, null);
         *  if (!isquery)
         *  {
         *      DEFS.ASSERT(retbuf != null, "newer get_buf2 has failed");
         *  }
         *  return retbuf;
         * }
         */
        /*
         * This can never return null, the caller *must* know that this buffer
         * is incore before calling. Must be called with a lock held on wip. But in case
         * is query is set true, then the caller is not sure if the buf is incore, in that
         * case we can return null safely.
         */

        public static Red_Buffer get_buf3(string who, RedFS_Inode wip, int level, int some_fbn, bool isquery)
        {
            List <Red_Buffer> list = null;

            switch (level)
            {
            case 0:
                list = wip.L0list;
                break;

            case 1:
                list = wip.L1list;
                break;

            case 2:
                list = wip.L2list;
                break;
            }
            DEFS.ASSERT(list != null, "List cannot be null in get_buf()");

            int start_fbn = SomeFBNToStartFBN(level, some_fbn);

            //some optimization, 10-12 mbps more.
            if (level == 1)
            {
                if (wip._lasthitbuf != null && wip._lasthitbuf.get_start_fbn() == start_fbn)
                {
                    return(wip._lasthitbuf);
                }
            }

            for (int idx = 0; idx < (list.Count); idx++)
            //for (int idx = (list.Count - 1); idx >= 0; idx--)
            {
                int        idx2 = (level == 0) ? (list.Count - idx - 1) : idx;
                Red_Buffer wb   = (Red_Buffer)list.ElementAt(idx2);
                if (wb.get_start_fbn() == start_fbn)
                {
                    //if (wb.get_level() > 0 && list.Count > 2) //like splay tree.
                    //{
                    //    list.RemoveAt(idx2);
                    //    list.Insert(0, wb);
                    //}
                    if (level == 1)
                    {
                        wip._lasthitbuf = wb;             //good opti - gives 10-12mbps more.
                    }
                    return(wb);
                }
            }

            DEFS.ASSERT(isquery, "who = " + who + ", get_buf() failed " + wip.get_ino() + "," + level + "," + some_fbn);
            return(null);
        }
예제 #4
0
 public void decrement_refcount(int fsid, Red_Buffer wb, bool isinodefilel0)
 {
     if (wb.get_level() == 0 && isinodefilel0)
     {
         m_wrloader.mod_refcount(fsid, wb.get_ondisk_dbn(), REFCNT_OP.DECREMENT_REFCOUNT, wb, isinodefilel0);
     }
     else
     {
         m_wrloader.mod_refcount(fsid, wb.get_ondisk_dbn(), REFCNT_OP.DECREMENT_REFCOUNT, null, false);
     }
 }
예제 #5
0
        private Red_Buffer allocate_wb(BLK_TYPE type)
        {
            Red_Buffer wb = null;

            switch (type)
            {
            case BLK_TYPE.REGULAR_FILE_L1:
                wb = new RedBufL1(0);
                break;

            case BLK_TYPE.REGULAR_FILE_L2:
                wb = new RedBufL2(0);
                break;
            }
            DEFS.ASSERT(wb != null, "Wrong request for allocate_wb(), type = " + type);
            return(wb);
        }
        public bool write(RedFS_Inode wip, Red_Buffer wb)
        {
            if (!initialized)
            {
                return(false);
            }
            total_disk_writes++;
            lock (dfile)
            {
                //DEFS.DEBUG("RAID", "Writing dbn : " + wb.get_ondisk_dbn() + " level : " + wb.get_level());
                dfile.Seek((long)wb.get_ondisk_dbn() * 4096, SeekOrigin.Begin);
                dfile.Write(wb.buf_to_data(), 0, 4096);
                dfile.Flush();
                wb.set_dirty(false);
                CheckSumBuf(wip, wb);
            }

            return(true);
        }
예제 #7
0
        private void do_regular_dirORfile_work(UpdateReqI cu, int childcnt)
        {
            Red_Buffer wb = allocate_wb(cu.blktype);

            byte[] buffer = new byte[4096];

            lock (tfile0)
            {
                tfile0.Seek((long)cu.tfbn * 4096, SeekOrigin.Begin);
                tfile0.Read(tmpiodatatfileR, 0, 4096);
                CONFIG.Decrypt_Read_WRBuf(tmpiodatatfileR, buffer);
                //DEFS.DEBUG("ENCY", "READ RF : " + OPS.ChecksumPageWRLoader(buffer));
                DEFS.DEBUG("CNTR", "do_regular_dirORfile_work (" + cu.tfbn + ") childcnt =" + childcnt);
            }

            wb.data_to_buf(buffer);

            REDFS_BUFFER_ENCAPSULATED wbe = new REDFS_BUFFER_ENCAPSULATED(wb);

            BLK_TYPE belowtype = BLK_TYPE.IGNORE;

            switch (cu.blktype)
            {
            case BLK_TYPE.REGULAR_FILE_L1:
                belowtype = BLK_TYPE.REGULAR_FILE_L0;
                break;

            case BLK_TYPE.REGULAR_FILE_L2:
                belowtype = BLK_TYPE.REGULAR_FILE_L1;
                break;
            }

            for (int i = 0; i < 1024; i++)
            {
                int dbnt = wbe.get_child_dbn(i);
                if (dbnt <= 0)
                {
                    continue;
                }
                apply_update_internal(dbnt, belowtype, childcnt, cu.optype, true);
            }
        }
        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);
        }
예제 #9
0
        /*
         * Below three functions are exposed for public.
         * MP Safe function, can take long if there
         * are too many updates to be made.
         */
        public void touch_refcount(Red_Buffer wb, bool isinodefilel0)
        {
            DEFS.ASSERT(wb != null, "touch refcount needs the wb");

            if (wb.get_touchrefcnt_needed() == false)// || wb.get_ondisk_dbn() == 0)
            {
                return;
            }
            else
            {
                //DEFS.DEBUG("-REF-", "CTH refcount for dbn = " + wb.get_ondisk_dbn() + " inofile = " + isinodefilel0);
                wb.set_touchrefcnt_needed(false);
            }

            if (wb.get_level() == 0 && isinodefilel0)
            {
                m_wrloader.mod_refcount(0, wb.get_ondisk_dbn(), REFCNT_OP.TOUCH_REFCOUNT, wb, true);
            }
            else
            {
                DEFS.ASSERT(wb.get_level() > 0, "touch_refcount is only for indirects only, except for ino-L0!");
                m_wrloader.mod_refcount(0, wb.get_ondisk_dbn(), REFCNT_OP.TOUCH_REFCOUNT, wb, false);
            }
        }
예제 #10
0
        public void mod_refcount(int fsid, int dbn, REFCNT_OP optype, Red_Buffer wb, bool isinodefilel0)
        {
            DEFS.ASSERT(optype == REFCNT_OP.INCREMENT_REFCOUNT || /*optype == REFCNT_OP.DECREMENT_REFCOUNT ||*/
                        optype == REFCNT_OP.TOUCH_REFCOUNT ||     /*optype == REFCNT_OP.DO_LOAD || */
                        optype == REFCNT_OP.INCREMENT_REFCOUNT_ALLOC ||
                        optype == REFCNT_OP.DECREMENT_REFCOUNT_ONDEALLOC, "Wrong param in mod_refcount");

            DEFS.ASSERT(isinodefilel0 || (wb == null || wb.get_level() > 0), "wrong type to mod_refcount " + isinodefilel0 + (wb == null));

            UpdateReqI r = new UpdateReqI();

            r.optype = optype;
            r.dbn    = dbn;
            r.fsid   = fsid;

            switch (optype)
            {
            case REFCNT_OP.INCREMENT_REFCOUNT:
            case REFCNT_OP.INCREMENT_REFCOUNT_ALLOC:
                r.value = 1;
                break;

            //case REFCNT_OP.DECREMENT_REFCOUNT:
            case REFCNT_OP.DECREMENT_REFCOUNT_ONDEALLOC:
                r.value = -1;
                break;

            case REFCNT_OP.TOUCH_REFCOUNT:
                //case REFCNT_OP.DO_LOAD:
                r.value = 0;
                break;
            }

            r.blktype = (wb != null) ? ((isinodefilel0) ? BLK_TYPE.PUBLIC_INODE_FILE_L0 : wb.get_blk_type()) :
                        ((optype == REFCNT_OP.INCREMENT_REFCOUNT_ALLOC || optype == REFCNT_OP.DECREMENT_REFCOUNT_ONDEALLOC)?
                         BLK_TYPE.IGNORE : BLK_TYPE.REGULAR_FILE_L0);

            if (wb != null && (wb.get_level() > 0 || BLK_TYPE.PUBLIC_INODE_FILE_L0 == r.blktype))
            {
                lock (tfile0)
                {
                    CONFIG.Encrypt_Data_ForWrite(tmpiodatatfileW, wb.buf_to_data());
                    tfile0.Seek((long)tfilefbn * 4096, SeekOrigin.Begin);
                    tfile0.Write(tmpiodatatfileW, 0, 4096);
                    //DEFS.DEBUG("ENCY", "Wrote : " + OPS.ChecksumPageWRLoader(wb.buf_to_data()));
                    r.tfbn = tfilefbn;
                    tfilefbn++;
                }
            }
            else
            {
                r.tfbn = -1;
            }

            if (optype != REFCNT_OP.INCREMENT_REFCOUNT_ALLOC && optype != REFCNT_OP.DECREMENT_REFCOUNT &&
                optype != REFCNT_OP.DECREMENT_REFCOUNT_ONDEALLOC && optype != REFCNT_OP.TOUCH_REFCOUNT)
            {
                DEFS.DEBUG("REFCNT", "Queued update for " + r.blktype + ", dbn = " +
                           r.dbn + ", and operation = " + r.optype + ", transaction offset : " + r.tfbn);
            }

            GLOBALQ.m_reqi_queue.Add(r);
        }
예제 #11
0
 public REDFS_BUFFER_ENCAPSULATED(Red_Buffer wb)
 {
     mwb = wb;
 }
예제 #12
0
 public void increment_refcount(int fsid, Red_Buffer wb, bool isinodefilel0)
 {
     m_wrloader.mod_refcount(fsid, wb.get_ondisk_dbn(), REFCNT_OP.INCREMENT_REFCOUNT, wb, isinodefilel0);
 }