static void wurfld_input_handler(iomux_t *iomux, int fd, void *data, int len, void *priv) { wurfld_connection_context *ctx = (wurfld_connection_context *)priv; if (!ctx) return; DEBUG1("New data on fd %d", fd); fbuf_add_binary(ctx->input, data, len); if (fbuf_used(ctx->input) < 4) return; // check if we have a complete requset char *current_data = fbuf_end(ctx->input) - (use_http ? 4 : 1); char *request_terminator = use_http ? strstr(current_data, "\r\n\r\n") : strstr(current_data, "\n"); if (!request_terminator && use_http) { // support some broken clients/requests request_terminator = strstr(current_data, "\n\n"); } if (request_terminator) { // we have a complete request so we can now start // background worker to handle it pthread_t worker_thread; ctx->fd = fd; // let the worker take care of the fd from now on iomux_remove(iomux, fd); if (single_thread) { worker(ctx); } else { pthread_create(&worker_thread, NULL, worker, ctx); pthread_detach(worker_thread); } } }
int mdir_lookup (struct mnode *node, const char *name, AFSFid *file) { fbuf the_fbuf; VenusFid dir, fid; int ret, saved_ret; assert (node->flags.sbp); assert (node->flags.fdp); dir.Cell = 0; dir.fid = node->fid; ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size, FBUF_READ|FBUF_PRIVATE); if (ret) return ret; saved_ret = fdir_lookup (&the_fbuf, &dir, name, &fid); ret = fbuf_end (&the_fbuf); if (ret) return ret; *file = fid.fid; return saved_ret; }
int mdir_changefid(struct mnode *dir, const char *name, AFSFid fid) { fbuf the_fbuf; VenusFid vfid; int ret, saved_ret; int32_t len; assert (dir->flags.sbp); assert (dir->flags.fdp); vfid.Cell = 0; vfid.fid = fid; ret = fbuf_create (&the_fbuf, dir->fd, dir->sb.st_size, FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) return ret; saved_ret = fdir_changefid (&the_fbuf, name, &vfid); if (ret == 0) { len = fbuf_len (&the_fbuf); mnode_update_size (dir, &len); } ret = fbuf_end (&the_fbuf); if (ret) return ret; return saved_ret; }
int mdir_mkdir (struct mnode *node, AFSFid dot, AFSFid dot_dot) { fbuf the_fbuf; int ret, saved_ret; int32_t len; assert (node->flags.sbp); assert (node->flags.fdp); ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size, FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) return ret; saved_ret = fdir_mkdir (&the_fbuf, dot, dot_dot); if (ret == 0) { len = fbuf_len (&the_fbuf); mnode_update_size (node, &len); } ret = fbuf_end (&the_fbuf); if (ret) return ret; return saved_ret; }
int mdir_remove (struct mnode *node, const char *name) { fbuf the_fbuf; int ret, saved_ret; int32_t len; assert (node->flags.sbp); assert (node->flags.fdp); ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size, FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) return ret; saved_ret = fdir_remove (&the_fbuf, name, NULL); if (ret == 0) { len = fbuf_len (&the_fbuf); mnode_update_size (node, &len); } ret = fbuf_end (&the_fbuf); if (ret) return ret; return saved_ret; }
int mdir_readdir (struct mnode *node, int (*func)(VenusFid *, const char *, void *), void *arg, VenusFid dir) { fbuf the_fbuf; int ret, saved_ret; assert (node->flags.sbp); assert (node->flags.fdp); ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size, FBUF_READ|FBUF_PRIVATE); if (ret) return ret; saved_ret = fdir_readdir (&the_fbuf, func, arg, dir, NULL); ret = fbuf_end (&the_fbuf); if (ret) return ret; return saved_ret; }
int mdir_emptyp (struct mnode *node) { fbuf the_fbuf; int ret, saved_ret; assert (node->flags.sbp); assert (node->flags.fdp); ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size, FBUF_READ|FBUF_PRIVATE); if (ret) return ret; saved_ret = fdir_emptyp (&the_fbuf); ret = fbuf_end (&the_fbuf); if (ret) return ret; return saved_ret; }
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; }
int dir_remove_name (FCacheEntry *e, const char *filename, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) { int ret; int fd; fbuf fb; struct stat sb; char *buf; char *p; size_t len; struct nnpfs_dirent *dp; struct nnpfs_dirent *last_dp; fcache_extra_file_name (e, cache_name, cache_name_sz); fd = open (cache_name, O_RDWR, 0); if (fd < 0) return errno; fcache_fhget (cache_name, cache_handle); if (fstat (fd, &sb) < 0) { ret = errno; close (fd); return ret; } len = sb.st_size; ret = fbuf_create (&fb, fd, len, FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) { close (fd); return ret; } last_dp = NULL; ret = ENOENT; for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) { dp = (struct nnpfs_dirent *)p; assert (dp->d_reclen > 0); if (strcmp (filename, dp->d_name) == 0) { if (last_dp != NULL) { size_t off1, off2; unsigned len; /* * d_reclen can be as largest (in worst case) * DIRBLKSIZ, and may not cause the entry to cross a * DIRBLKSIZ boundery. */ len = last_dp->d_reclen + dp->d_reclen; off1 = (char *)last_dp - buf; off2 = off1 + len; off1 /= DIRBLKSIZ; off2 /= DIRBLKSIZ; if (len < DIRBLKSIZ && off1 == off2) last_dp->d_reclen = len; } dp->d_fileno = 0; ret = 0; break; } last_dp = dp; } fbuf_end (&fb); close (fd); return ret; }
int mdir_rename(struct mnode *dir1, const char *name1, int32_t *len1, struct mnode *dir2, const char *name2, int32_t *len2) { fbuf origfbuf; fbuf newfbuf; fbuf *newfbufP = &newfbuf; VenusFid child, origVFid; int ret, dirp; int same_dir = FALSE; origVFid.Cell = 0; origVFid.fid = dir1->fid; ret = fbuf_create (&origfbuf, dir1->fd, dir1->sb.st_size, FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) return ret; ret = fdir_lookup(&origfbuf, &origVFid, name1, &child); if (ret) { fbuf_end (&origfbuf); return ret; } dirp = afs_dir_p (child.fid.Vnode); if (dir1 == dir2) { newfbufP = &origfbuf; same_dir = TRUE; } else { ret = fbuf_create (&newfbuf, dir2->fd, dir2->sb.st_size, FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) { fbuf_end (&origfbuf); return ret; } } { VenusFid sentenced_file; VenusFid dir; dir.fid = dir2->fid; dir.Cell = 0; if (fdir_lookup(newfbufP, &dir, name2, &sentenced_file) == ENOENT) { ret = fdir_creat (newfbufP, name2, child.fid); if (ret) goto out1; } else { if (afs_dir_p (sentenced_file.fid.Vnode) != dirp) { /* XXX check properly */ ret = EISDIR; goto out1; } if (dirp && fdir_emptyp(newfbufP) != TRUE) { ret = ENOTEMPTY; goto out1; } ret = fdir_changefid(newfbufP, name2, &child); if (ret) goto out1; } } ret = fdir_remove (&origfbuf, name1, NULL); if (ret == 0) { *len1 = fbuf_len (&origfbuf); if (!same_dir) *len2 = fbuf_len (newfbufP); } out1: fbuf_end (&origfbuf); if (!same_dir) { fbuf_end (&newfbuf); } return ret; }