Exemple #1
0
        /*
         * Given a dbn, load the appropriate block and apply the update.
         */
        private void apply_update_internal(int dbn, BLK_TYPE type, int value, REFCNT_OP optype, bool updatechild)
        {
            int rbn = REFDEF.dbn_to_rbn(dbn);

            load_wrbufx(rbn);
            counter++;

            int curr = GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(dbn);

            GLOBALQ.WRObj[rbn].incoretbuf.set_refcount(dbn, curr + value);

            if (optype == REFCNT_OP.INCREMENT_REFCOUNT_ALLOC ||
                optype == REFCNT_OP.DECREMENT_REFCOUNT_ONDEALLOC)
            {
                //DEFS.DEBUG("DSAF", "Apply update internal, " + optype + " : " + dbn + "," + value + "," + updatechild);
                GLOBALQ.WRObj[rbn].incoretbuf.set_dedupe_overwritten_flag(dbn, true);
            }

            if (updatechild)
            {
                if (type != BLK_TYPE.REGULAR_FILE_L0 && type != BLK_TYPE.IGNORE)
                {
                    int currchd = GLOBALQ.WRObj[rbn].incoretbuf.get_childcount(dbn);
                    GLOBALQ.WRObj[rbn].incoretbuf.set_childcount(dbn, currchd + value);
                    DEFS.DEBUGCLR("/-0-0-/", "dbn,  " + dbn + "(" + curr + "->" + (curr + value) + ") (" + currchd + "->" + (currchd + value) + ")");
                }
            }
        }
Exemple #2
0
        private void DoSnapshotWork(int rbn)
        {
            if (GLOBALQ.disk_snapshot_mode_enabled && GLOBALQ.disk_snapshot_map[rbn] == false)
            {
                DEFS.ASSERT(GLOBALQ.disk_snapshot_optype == REFCNT_OP.TAKE_DISK_SNAPSHOT ||
                            GLOBALQ.disk_snapshot_optype == REFCNT_OP.UNDO_DISK_SNAPSHOT,
                            "Failure in having correct optype set");
                DEFS.ASSERT(GLOBALQ.snapshotfile != null, "Snapshot file cannot be null");

                GLOBALQ.disk_snapshot_map[rbn] = true;
                int startdbn = rbn * 512;

                if (GLOBALQ.disk_snapshot_optype == REFCNT_OP.TAKE_DISK_SNAPSHOT)
                {
                    for (int idx = 0; idx < 512; idx++)
                    {
                        int curr = GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(startdbn + idx);
                        if (curr != 0)
                        {
                            GLOBALQ.WRObj[rbn].incoretbuf.set_refcount(startdbn + idx, curr + 1);
                            GLOBALQ.WRObj[rbn].incoretbuf.set_dedupe_overwritten_flag(startdbn + idx, false);
                            REFDEF.snapshot_setbit(idx, tmpsnapshotcache, true);
                        }
                        else
                        {
                            REFDEF.snapshot_setbit(idx, tmpsnapshotcache, false);
                        }
                    }
                    int fileoffset = rbn * 64;
                    GLOBALQ.snapshotfile.Seek(fileoffset, SeekOrigin.Begin);
                    GLOBALQ.snapshotfile.Write(tmpsnapshotcache, 0, 64);
                }
                else
                {
                    int fileoffset = rbn * 64;
                    GLOBALQ.snapshotfile.Seek(fileoffset, SeekOrigin.Begin);
                    GLOBALQ.snapshotfile.Read(tmpsnapshotcache, 0, 64);

                    for (int idx = 0; idx < 512; idx++)
                    {
                        if (REFDEF.snapshot_getbit(idx, tmpsnapshotcache) == true)
                        {
                            int curr = GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(startdbn + idx);
                            GLOBALQ.WRObj[rbn].incoretbuf.set_refcount(startdbn + idx, curr - 1);
                        }
                    }
                }
                GLOBALQ.disk_snapshot_map[rbn]         = true;
                GLOBALQ.WRObj[rbn].incoretbuf.is_dirty = true;
            } //end of if-case.
        }
Exemple #3
0
        /*
         * Also write this file to the delete log,
         */
        private void checkset_if_blockfree(int dbn, int c)
        {
            int rbn = REFDEF.dbn_to_rbn(dbn);

            if (GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(dbn) == 0)
            {
                DEFS.ASSERT(GLOBALQ.WRObj[rbn].incoretbuf.get_childcount(dbn) == 0,
                            "WTF happened? chdcnt = " + c + " -> " + GLOBALQ.WRObj[rbn].incoretbuf.get_childcount(dbn));
                lock (GLOBALQ.m_deletelog2)
                {
                    GLOBALQ.m_deletelog2.Add(dbn);
                    //dfile1.write ->
                }
                GLOBALQ.WRObj[rbn].incoretbuf.set_childcount(dbn, 0); //must clear this.
            }
        }
Exemple #4
0
        public void get_refcount(int dbn, ref int refcnt, ref int childcnt)
        {
            UpdateReqI r = new UpdateReqI();

            r.optype = REFCNT_OP.GET_REFANDCHD_INFO;
            r.dbn    = dbn;
            GLOBALQ.m_reqi_queue.Add(r);

            int rbn = REFDEF.dbn_to_rbn(dbn);

            while (r.processed == false)
            {
                //Console.WriteLine("Waiting for refcount to turn up : " + dbn + "," + GLOBALQ.m_reqi_queue.Count);
                Thread.Sleep(10);
            }
            refcnt   = GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(dbn);
            childcnt = GLOBALQ.WRObj[rbn].incoretbuf.get_childcount(dbn);
        }
Exemple #5
0
        /*
         * Will block on GLOBALQ.m_reqi_queue and take it to
         * its logical conclusion.
         */
        public void tServiceThread()
        {
            //long protected_blkdiff_counter = 0;
            long[] protected_blkdiff_counter = new long[1024];

            while (true)
            {
                UpdateReqI cu = (UpdateReqI)GLOBALQ.m_reqi_queue.Take();

                if (cu.optype == REFCNT_OP.SHUT_DOWN)
                {
                    internal_sync_and_flush_cache_advanced();
                    DEFS.ASSERT(GLOBALQ.m_reqi_queue.Count == 0, "There cannot be any pending updates when shutting down");
                    DEFS.DEBUGYELLOW("REF", "Bailing out now!!");
                    //dont take a lock here.

                    for (int i = 0; i < 1024; i++)
                    {
                        if (REDDY.FSIDList[i] == null || protected_blkdiff_counter[i] == 0)
                        {
                            continue;
                        }

                        REDDY.FSIDList[i].diff_upadate_logical_data(protected_blkdiff_counter[i]);
                        REDDY.FSIDList[i].set_dirty(true);
                        protected_blkdiff_counter[i] = 0;
                    }

                    cu.processed  = true;
                    m_initialized = false;
                    break;
                }

                if (cu.optype == REFCNT_OP.DO_SYNC)
                {
                    internal_sync_and_flush_cache_advanced();

                    //dont take a lock here.
                    for (int i = 0; i < 1024; i++)
                    {
                        if (REDDY.FSIDList[i] == null || protected_blkdiff_counter[i] == 0)
                        {
                            continue;
                        }

                        REDDY.FSIDList[i].diff_upadate_logical_data(protected_blkdiff_counter[i]);
                        REDDY.FSIDList[i].set_dirty(true);
                        protected_blkdiff_counter[i] = 0;
                    }
                    cu.processed = true;
                    tfile0.Flush();
                    mfile1.Flush();
                    dfile1.Flush();
                    continue;
                }

                if (cu.optype == REFCNT_OP.TAKE_DISK_SNAPSHOT ||
                    cu.optype == REFCNT_OP.UNDO_DISK_SNAPSHOT)
                {
                    int rbn_update = cu.tfbn; //overloaded since its just file offset.
                    load_wrbufx(rbn_update);  //will dowork
                    DEFS.ASSERT(cu.dbn == 0, "This should not be set");
                    DEFS.ASSERT(cu.optype == GLOBALQ.disk_snapshot_optype, "this must also match");
                    //DoSnapshotWork(rbn_update);
                    counter++;
                    total_ops++;
                    printspeed();
                    continue;
                }

                if (cu.dbn != 0)
                {
                    if (cu.optype == REFCNT_OP.DECREMENT_REFCOUNT_ONDEALLOC)
                    {
                        protected_blkdiff_counter[cu.fsid] -= 4096;
                    }
                    else if (cu.optype == REFCNT_OP.INCREMENT_REFCOUNT_ALLOC)
                    {
                        protected_blkdiff_counter[cu.fsid] += 4096;
                    }
                    //all other ops you can ignore.
                }

                int rbn = REFDEF.dbn_to_rbn(cu.dbn);
                total_ops++;
                counter++;

                /*
                 * Now if this has a child update pending, then we must clean it up.
                 * For each entry, i.e dbn, load the upto 1024, into memory and update
                 * the refcount. Essentially when we access this buffer - it must not
                 * have any pending update to itself or its children.
                 *
                 * How the children are updated depends on the blk_type, thats why so many
                 * cases.
                 */
                load_wrbufx(rbn);

                if (cu.optype == REFCNT_OP.GET_REFANDCHD_INFO)
                {
                    cu.processed = true;
                    continue;
                }

                int childcnt = GLOBALQ.WRObj[rbn].incoretbuf.get_childcount(cu.dbn);

                if (childcnt > 0)
                {
                    DEFS.DEBUG("CNTr", "Encountered child update for " + cu.dbn + " = " +
                               GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(cu.dbn) + "," + childcnt);

                    if (cu.blktype == BLK_TYPE.REGULAR_FILE_L0)// || cu.blktype == BLK_TYPE.DIRFILE_L0)
                    {
                        /* Normal handling*/
                        //DEFS.ASSERT(cu.blktype == GLOBALQ.WRObj[rbn].incoretbuf.get_blk_type(cu.dbn), "Block mismatch");
                        DEFS.ASSERT(cu.tfbn == -1, "tfbn cannot be set for a level 0 block generally");
                        DEFS.ASSERT(false, "How can there be a childcnt update for a level zero block?");
                    }
                    else if (cu.blktype == BLK_TYPE.REGULAR_FILE_L1 || cu.blktype == BLK_TYPE.REGULAR_FILE_L2) /* ||
                                                                                                                * cu.blktype == BLK_TYPE.DIRFILE_L1 || cu.blktype == BLK_TYPE.DIRFILE_L2 ||
                                                                                                                * cu.blktype == BLK_TYPE.PUBLIC_INODE_FILE_L2 || cu.blktype == BLK_TYPE.PUBLIC_INODE_FILE_L1)*/
                    {
                        //DEFS.ASSERT(false, "Not yet implimented chdcnt in wrloader : " + REFDEF.get_string_rep(cu));
                        DEFS.ASSERT(cu.tfbn != -1, "Tfbn should've been set here.");
                        do_regular_dirORfile_work(cu, childcnt);
                        GLOBALQ.WRObj[rbn].incoretbuf.set_childcount(cu.dbn, 0);
                    }
                    else if (cu.blktype == BLK_TYPE.PUBLIC_INODE_FILE_L0)
                    {
                        DEFS.DEBUGCLR("------", "Do ino-L0 update work," + cu.optype + " , chdcnt = " + childcnt +
                                      " curr_refcnt = " + GLOBALQ.WRObj[rbn].incoretbuf.get_refcount(cu.dbn));
                        do_inode_refupdate_work(cu, childcnt);
                        GLOBALQ.WRObj[rbn].incoretbuf.set_childcount(cu.dbn, 0);
                    }
                    else
                    {
                        DEFS.ASSERT(false, "passed type = " + cu.blktype + "dbn = " + cu.dbn + " chdcnt = " + childcnt);
                    }
                }

                if (cu.optype != REFCNT_OP.TOUCH_REFCOUNT)
                {
                    /*
                     * Now that pending updates are propogated ,apply the queued update to this refcount.
                     * If it becomes free, notify that.
                     */
                    load_wrbufx(rbn);

                    apply_update_internal(cu.dbn, cu.blktype, cu.value, cu.optype, (cu.optype == REFCNT_OP.INCREMENT_REFCOUNT));

                    checkset_if_blockfree(cu.dbn, childcnt);
                }

                /* After the load, see if we have to clean up */
                if (cachesize > 15 * 1024)
                {
                    internal_sync_and_flush_cache_advanced();
                }
                printspeed();
            }

            tfile0.Flush();
            tfile0.Close();
            dfile1.Flush();
            dfile1.Close();
            mfile1.Flush();
            mfile1.Close();
        }