Beispiel #1
0
int
fdir_mkdir (fbuf *the_fbuf,
	    AFSFid dot,
	    AFSFid dot_dot)
{
    DirPage0 *page0;
    DirPage1 *page;
    int ind;
    int i;
    int tmp;
    int ret;

    ret = create_new_page (&page, the_fbuf);
    if (ret)
	return ret;

    page0 = (DirPage0 *)fbuf_buf(the_fbuf);
    memset (&page0->dheader, 0, sizeof(page0->dheader));
    tmp = ENTRIESPERPAGE
	- (sizeof(PageHeader) + sizeof(DirHeader)) / sizeof(DirEntry);
    page0->header.pg_freecount = tmp;
    page0->dheader.map[0]      = tmp;
    page0->header.pg_pgcount   = htons(1);

    for (i = 0; i < 13; ++i)
	set_used (page, i);

    assert (page0->dheader.hash[hashentry(".")] == 0);

    ind = add_to_page (page0, page, 0, ".", dot, 0);

    assert (ind >= 0);

    page0->dheader.hash[hashentry(".")] = htons(ind + 1);

    assert (page0->dheader.hash[hashentry("..")] == 0);

    ind = add_to_page (page0, page, 0, "..", dot_dot, 0);

    assert (ind >= 0);

    page0->dheader.hash[hashentry("..")] = htons(ind + 1);

    return 0;
}
Beispiel #2
0
int
fdir_creat (fbuf *dir,
	    const char *name,
	    AFSFid fid)
{
    int ret;
    int i;
    unsigned npages;
    DirPage0 *page0;
    DirPage1 *page;
    int ind = 0;
    unsigned hash_value, next;

    assert (dir->len != 0);

    page0 = (DirPage0 *)fbuf_buf(dir);
    assert (page0);
    npages = ntohs(page0->header.pg_pgcount);

    if (npages < fbuf_len(dir) / AFSDIR_PAGESIZE)
	npages = fbuf_len(dir) / AFSDIR_PAGESIZE;

    if (find_entry (page0, name))
	return EEXIST;

    hash_value = hashentry (name);
    next = page0->dheader.hash[hash_value];

    for (i = 0; i < npages; ++i) {
	page = getpage (page0, i);
	ind = add_to_page (page0, page, i, name, fid, next);
	if (ind >= 0)
	    break;
    }
    if (i == npages) {
	ret = create_new_page (&page, dir);
	if (ret)
	    return ret;
	page0 = (DirPage0 *)fbuf_buf(dir);
	page0->header.pg_pgcount = htons(npages + 1);
	if (i < MAXPAGES)
	    page0->dheader.map[i] = ENTRIESPERPAGE - 1;
	ind = add_to_page (page0, page, i, name, fid, next);
	assert (ind >= 0);
    }
    ind += i * ENTRIESPERPAGE;
    
    page0->dheader.hash[hash_value] = htons(ind + 1);
    
    return 0;
}
Beispiel #3
0
static DirEntry *
find_entry(DirPage0 *page0, const char *name)
{
    DirEntry *entry;
    unsigned short i;

    for (i = ntohs(page0->dheader.hash[hashentry (name)]);
	 i != 0;
	 i = ntohs(entry->next)) {
	entry = getentry (page0, (unsigned short)(i - 1));

	if (strcmp (entry->name, name) == 0)
	    return entry;
    }
    return NULL;
}
Beispiel #4
0
static int
check_dir (const char *filename)
{
    struct stat statbuf;
    int fd;
    fbuf the_fbuf;
    DirPage0 *page0;
    unsigned i, j;
    unsigned ind;
    unsigned len;
    int ret = 0;
    unsigned npages = 0;
    unsigned page_entry_count;
    unsigned hash_entry_count;
    unsigned noverfill;
    uint8_t **my_bitmaps = NULL;

    fd = open (filename, O_RDONLY | O_BINARY, 0);
    if (fd < 0)
	err (1, "open %s", filename);

    if (fstat (fd, &statbuf) < 0)
	err (1, "stat %s", filename);

    len = statbuf.st_size;

    if (len == 0)
	errx (1, "length == 0");

    if (len % AFSDIR_PAGESIZE != 0)
	errx (1, "length %% AFSDIR_PAGESIZE != 0");

    ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ|FBUF_PRIVATE);
    if (ret)
	err (1, "fbuf_create");

    page0 = (DirPage0 *)(the_fbuf.buf);

    printf ("size = %u, pages = %u, pgcount = %u\n",
	    len, len / AFSDIR_PAGESIZE,
	    ntohs(page0->header.pg_pgcount));

    if (len / AFSDIR_PAGESIZE != ntohs(page0->header.pg_pgcount)) {
	ret = 1;
	goto out;
    }

    npages = len / AFSDIR_PAGESIZE;

    my_bitmaps = malloc (npages * sizeof(*my_bitmaps));
    if (my_bitmaps == NULL)
	err (1, "malloc %lu", (unsigned long)npages * sizeof(*my_bitmaps));

    printf ("map: ");
    for (i = 0; i < min(npages, MAXPAGES); ++i) {
	printf ("%u ", page0->dheader.map[i]);
    }
    printf ("\n");

    page_entry_count = 0;

    for (i = 0; i < npages; ++i) {
	PageHeader *ph = (PageHeader *)((char *)page0 + i * AFSDIR_PAGESIZE);
	int start;
	size_t sz = ENTRIESPERPAGE / 8 * sizeof(*my_bitmaps[i]);

	my_bitmaps[i] = malloc (sz);
	if (my_bitmaps[i] == NULL)
	    err (1, "malloc %lu", (unsigned long)sz);

	memset (my_bitmaps[i], 0, sz);

	if (ph->pg_tag != htons(AFSDIRMAGIC)) {
	    printf ("page %d: wrong tag: %u\n", i, htons(ph->pg_tag));
	    ret = 1;
	    goto out;
	}
	printf ("page %d: count = %u, tag = %u, freecount = %u\n",
		i, ntohs(ph->pg_pgcount), htons(ph->pg_tag), ph->pg_freecount);
	if (i == 0) {
	    if (ph->pg_freecount != 51) {
		printf ("freecount should be 51!\n");
		ret = 1;
		goto out;
	    }
	    if (ntohs(ph->pg_pgcount) != npages) {
		printf ("pgcount should be %u!\n", npages);
		ret = 1;
		goto out;
	    }
	} else {
	    if (ph->pg_freecount != 63) {
		printf ("freecount should be 63!\n");
		ret = 1;
		goto out;
	    }
	    if (ntohs(ph->pg_pgcount) != 0) {
		printf ("pgcount should be 0!\n");
		ret = 1;
		goto out;
	    }
	}

	if (i == 0)
	    start = 13;
	else
	    start = 1;

	for (j = start; j < ENTRIESPERPAGE; ++j) {
	    if (ph->pg_bitmap[j / 8] & (1 << (j % 8)))
		++page_entry_count;
	}
    }

    printf ("page entry count = %u\n", page_entry_count);

    hash_entry_count = 0;
    noverfill = 0;

    for (i = 0; i < ADIRHASHSIZE; ++i) {
	const DirEntry *entry;

	for(ind = ntohs(page0->dheader.hash[i]);
	    ind;
	    ind = ntohs(entry->next)) {
	    DirPage1 *page_n;
	    int len;
	    unsigned off;
	    unsigned pageno;

	    entry = getentry (page0, ind - 1);

	    if (verbose)
		printf ("%s - %ld.%ld\n",
			entry->name, 
			(long)ntohl(entry->fid.Vnode),
			(long)ntohl(entry->fid.Unique));
	    
	    if (hashentry (entry->name) != i)
		printf ("wrong name here? hash = %u, name = *%s*\n",
			i, entry->name);

	    pageno = (ind) / ENTRIESPERPAGE;
	    off = (ind) % ENTRIESPERPAGE;

	    page_n = (DirPage1 *)((char *)page0
				  + AFSDIR_PAGESIZE * pageno);

	    if (!(page_n->header.pg_bitmap[off / 8] & (1 << (off % 8)))) {
		printf ("page %d: off %u not set\n",
			(ind - 1) / ENTRIESPERPAGE, off);
	    }

	    my_bitmaps[pageno][off / 8] |= (1 << (off % 8));

	    len = strlen(entry->name);
	    while (len > 15) {
		len -= sizeof(DirEntry);
		++noverfill;
		++off;
		my_bitmaps[pageno][off / 8] |= (1 << (off % 8));
	    }

	    ++hash_entry_count;
	}
    }

    for (i = 0; i < npages; ++i) {
	DirPage1 *page_n;
	int j;
	unsigned unused;

	if (i == 0)
	    unused = 13;
	else
	    unused = 1;

	for (j = 0; j < unused; ++j)
	    my_bitmaps[i][j / 8] |= (1 << (j % 8));

	page_n = (DirPage1 *)((char *)page0 + AFSDIR_PAGESIZE * i);

	if (memcmp (my_bitmaps[i],
		    page_n->header.pg_bitmap, sizeof(my_bitmaps[i])) != 0) {
	    printf ("page %i: bitmaps differ\n"
		    "actual:     ", i);
	    for (j = 0; j < ENTRIESPERPAGE / 8; ++j)
		printf ("%02x ", page_n->header.pg_bitmap[j]);
	    printf ("\n"
		    "calculated: ");
	    for (j = 0; j < ENTRIESPERPAGE / 8; ++j)
		printf ("%02x ", my_bitmaps[i][j]);
	    printf ("\n");
	}
    }


    printf ("hash entry count = %u, noverfill = %u, sum = %u\n",
	    hash_entry_count, noverfill, hash_entry_count + noverfill);

    if (hash_entry_count + noverfill != page_entry_count)
	ret = 1;

out:    
    fbuf_end (&the_fbuf);
    close (fd);
    if (my_bitmaps) {
	for (i = 0; i < npages; ++i)
	    free (my_bitmaps[i]);
	free (my_bitmaps);
    }
    return ret;
}
Beispiel #5
0
int
fdir_remove (fbuf *dir,
	     const char *name,
	     AFSFid *fid)
{
    int i;
    unsigned len = dir->len;
    DirPage0 *page0;
    DirPage1 *page;
    unsigned hash_value;
    DirEntry *entry = NULL;
    DirEntry *prev_entry;
    unsigned pageno;
    int found;
    unsigned npages;


    page0 = (DirPage0 *)fbuf_buf(dir);
    npages = ntohs(page0->header.pg_pgcount);
    if (npages < len / AFSDIR_PAGESIZE)
	npages = len / AFSDIR_PAGESIZE;

    hash_value = hashentry (name);
    i = ntohs(page0->dheader.hash[hash_value]);
    found = i == 0;
    prev_entry = NULL;
    while (!found) {
	entry = getentry (page0, i - 1);

	if (strcmp (entry->name, name) == 0) {
	    found = TRUE;
	} else {
	    i = ntohs(entry->next);
	    if (i == 0)
		found = TRUE;
	    prev_entry = entry;
	}
    }
    if (i == 0)
	return ENOENT;
    else {
	if (fid) {
	    fid->Vnode = ntohl(entry->fid.Vnode);
	    fid->Unique = ntohl(entry->fid.Unique);
	}

	if (prev_entry == NULL)
	    page0->dheader.hash[hash_value] = entry->next;
	else
	    prev_entry->next = entry->next;

	pageno = (i - 1) / ENTRIESPERPAGE;
	page = getpage (page0, pageno);
	remove_from_page (page0, page, pageno, (i - 1) % ENTRIESPERPAGE);
	if (pageno == npages - 1
	    && is_page_empty (page0, pageno)) {
	    do {
		len -= AFSDIR_PAGESIZE;
		--pageno;
		--npages;
	    } while(is_page_empty(page0, pageno));
	    page0->header.pg_pgcount = htons(npages);
	    fbuf_truncate (dir, len);
	}
	return 0;
    }
}