Beispiel #1
0
static void
calculate_refcounts(int *counts, vnode_t *vnode)
{
        int ret;

        counts[vnode->vn_vno]++;
        dbg(DBG_S5FS, "calculate_refcounts: Incrementing count of inode %d to"
            " %d\n", vnode->vn_vno, counts[vnode->vn_vno]);
        /*
         * We only consider the children of this directory if this is the
         * first time we have seen it.  Otherwise, we would recurse forever.
         */
        if (counts[vnode->vn_vno] == 1 && S_ISDIR(vnode->vn_mode)) {
                int offset = 0;
                struct dirent d;
                vnode_t *child;

                while (0 < (ret = s5fs_readdir(vnode, offset, &d))) {
                        /*
                         * We don't count '.', because we don't increment the
                         * refcount for this (an empty directory only has a
                         * link count of 1).
                         */
                        if (0 != strcmp(d.d_name, ".")) {
                                child = vget(vnode->vn_fs, d.d_ino);
                                calculate_refcounts(counts, child);
                                vput(child);
                        }
                        offset += ret;
                }

                KASSERT(ret == 0);
        }
}
Beispiel #2
0
/*
 * s5fs_check_refcounts:
 * This will check the refcounts for the filesystem.  It will ensure that that
 * the expected number of refcounts will equal the actual number.  
 * param *fs: the pointer to the file system object
 * return: 0 on success; negative number on failure
 */
int
s5fs_check_refcounts(fs_t *fs)
{
    s5fs_t* s5fs = (s5fs_t *)fs->fs_i;
    int* refcounts;
    int ret = 0;
    uint32_t i;
    
    /* malloc the ref mem */
    refcounts = kmalloc(s5fs->s5f_super->s5s_num_inodes * sizeof(int));
    KASSERT(refcounts);
    memset(refcounts, 0, s5fs->s5f_super->s5s_num_inodes * sizeof(int));
    
    calculate_refcounts(refcounts, fs->fs_root);
    --refcounts[fs->fs_root->vn_vno]; /* the call on the preceding line
                                       * caused this to be incremented
                                       * not because another fs link to
                                       * it was discovered */
    
    dbg(DBG_PRINT, "Checking refcounts of s5fs filesystem on block "
        "device with major %d, minor %d\n",
        MAJOR(s5fs->s5f_bdev->bd_id), MINOR(s5fs->s5f_bdev->bd_id));
    
    for (i = 0; i < s5fs->s5f_super->s5s_num_inodes; i++) {
        vnode_t *vn;
        
        if (!refcounts[i]) continue;
        
        vn = vget(fs, i);
        KASSERT(vn);
        
        if (refcounts[i] != VNODE_TO_S5INODE(vn)->s5_linkcount - 1) {
            dbg(DBG_PRINT, "   Inode %d, expecting %d, found %d\n", i,
                refcounts[i], VNODE_TO_S5INODE(vn)->s5_linkcount - 1);
            ret = -1;
        }
        vput(vn);
    }
    
    dbg(DBG_PRINT, "Refcount check of s5fs filesystem on block "
        "device with major %d, minor %d completed %s.\n",
        MAJOR(s5fs->s5f_bdev->bd_id), MINOR(s5fs->s5f_bdev->bd_id),
        (ret ? "UNSUCCESSFULLY" : "successfully"));
    
    kfree(refcounts);
    return ret;
}