예제 #1
0
파일: mkfs.c 프로젝트: fr0stbyte/rdfs
int main(int argc, char **argv) {
  int devfd;

  // get the device from argv
  if(argc != 2) {
    fprintf(stderr, "need to pass in a device\n");
    exit(1);
  }
  // open device
  devfd = open_device(argv[1], O_WRONLY);

  // find if there is enough space -- seek blocks * block size
  verify_device_space(devfd);

  // write the superblock
  write_superblock(devfd);

  // setup the inodes for /
  write_inode(devfd, 3, 1);

  // setup the inode for lost+found
  write_inode(devfd, 2, 2);

  // skip into file section
  // write directories for / ., ..
  struct rdfs_dirent *p = calloc(3, sizeof(struct rdfs_dirent));
  struct rdfs_dirent *dirent = p;
  p->d_inode = 1;
  strcpy(p->d_name, ".");
  p++;
  p->d_inode = 1;
  strcpy(p->d_name, "..");
  p++;
  p->d_inode = 2;
  strcpy(p->d_name, "lost+found");
  write_directory(devfd, dirent, 3, 0);
  free(dirent);

  // write directories for lost+found ., ..
  p = calloc(2, sizeof(struct rdfs_dirent));
  dirent = p;
  p->d_inode = 2;
  strcpy(p->d_name, ".");
  p++;
  p->d_inode = 1;
  strcpy(p->d_name, "..");
  write_directory(devfd, dirent, 2, 1);

  free(dirent);

  return 0;
}
예제 #2
0
파일: archive.c 프로젝트: AbelTian/git
static int queue_or_write_archive_entry(const unsigned char *sha1,
		struct strbuf *base, const char *filename,
		unsigned mode, int stage, void *context)
{
	struct archiver_context *c = context;

	while (c->bottom &&
	       !(base->len >= c->bottom->len &&
		 !strncmp(base->buf, c->bottom->path, c->bottom->len))) {
		struct directory *next = c->bottom->up;
		free(c->bottom);
		c->bottom = next;
	}

	if (S_ISDIR(mode)) {
		queue_directory(sha1, base, filename,
				mode, stage, c);
		return READ_TREE_RECURSIVE;
	}

	if (write_directory(c))
		return -1;
	return write_archive_entry(sha1, base->buf, base->len, filename, mode,
				   stage, context);
}
예제 #3
0
void db_close(CH_DBFile* db, CH_DBHeader* header_template) {
  int r;

  write_directory(db, header_template);

  r = close(db->fd);
  if (r < 0) {
    perror("Cannot close fd");
  }
}
예제 #4
0
파일: archive.c 프로젝트: fcharlie/git
static int write_directory(struct archiver_context *c)
{
	struct directory *d = c->bottom;
	int ret;

	if (!d)
		return 0;
	c->bottom = d->up;
	d->path[d->len - 1] = '\0'; /* no trailing slash */
	ret =
		write_directory(c) ||
		write_archive_entry(&d->oid, d->path, d->baselen,
				    d->path + d->baselen, d->mode,
				    d->stage, c) != READ_TREE_RECURSIVE;
	free(d);
	return ret ? -1 : 0;
}
예제 #5
0
파일: main.c 프로젝트: CoryXie/BarrelfishOS
static int cpio_entry_handler(int n, const cpio_generic_header_t *h, void *arg)
{
    struct dirent *root = arg;
    errval_t err;

    if(CPIO_MODE_FILE == (h->mode & CPIO_MODE_FILE_TYPE_MASK)) {
        err = write_file(root, h->name, (void *)h->data, h->datasize);
    } else if(CPIO_MODE_DIRECTORY == (h->mode & CPIO_MODE_FILE_TYPE_MASK)) {
        err = write_directory(root, h->name);
    } else {
        return 0;
    }

    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "error writing file to ramfs");
    }

    return 0;
}
예제 #6
0
파일: archive.c 프로젝트: fcharlie/git
static int queue_or_write_archive_entry(const struct object_id *oid,
		struct strbuf *base, const char *filename,
		unsigned mode, int stage, void *context)
{
	struct archiver_context *c = context;

	while (c->bottom &&
	       !(base->len >= c->bottom->len &&
		 !strncmp(base->buf, c->bottom->path, c->bottom->len))) {
		struct directory *next = c->bottom->up;
		free(c->bottom);
		c->bottom = next;
	}

	if (S_ISDIR(mode)) {
		size_t baselen = base->len;
		const struct attr_check *check;

		/* Borrow base, but restore its original value when done. */
		strbuf_addstr(base, filename);
		strbuf_addch(base, '/');
		check = get_archive_attrs(c->args->repo->index, base->buf);
		strbuf_setlen(base, baselen);

		if (check_attr_export_ignore(check))
			return 0;
		queue_directory(oid->hash, base, filename,
				mode, stage, c);
		return READ_TREE_RECURSIVE;
	}

	if (write_directory(c))
		return -1;
	return write_archive_entry(oid, base->buf, base->len, filename, mode,
				   stage, context);
}
예제 #7
0
errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino,
			    struct problem_context *pctx)
{
	ext2_filsys 		fs = ctx->fs;
	errcode_t		retval;
	struct ext2_inode 	inode;
	char			*dir_buf = 0;
	struct fill_dir_struct	fd;
	struct out_dir		outdir;

	outdir.max = outdir.num = 0;
	outdir.buf = 0;
	outdir.hashes = 0;
	e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");

	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
				      EXT4_FEATURE_INCOMPAT_INLINE_DATA) &&
	   (inode.i_flags & EXT4_INLINE_DATA_FL))
		return 0;

	retval = ENOMEM;
	fd.harray = 0;
	dir_buf = malloc(inode.i_size);
	if (!dir_buf)
		goto errout;

	fd.max_array = inode.i_size / 32;
	fd.num_array = 0;
	fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
	if (!fd.harray)
		goto errout;

	fd.ctx = ctx;
	fd.buf = dir_buf;
	fd.inode = &inode;
	fd.ino = ino;
	fd.err = 0;
	fd.dir_size = 0;
	fd.compress = 0;
	fd.dir = ino;
	if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
	    (inode.i_size / fs->blocksize) < 2)
		fd.compress = 1;
	fd.parent = 0;

retry_nohash:
	/* Read in the entire directory into memory */
	retval = ext2fs_block_iterate3(fs, ino, 0, 0,
				       fill_dir_block, &fd);
	if (fd.err) {
		retval = fd.err;
		goto errout;
	}

	/* 
	 * If the entries read are less than a block, then don't index
	 * the directory
	 */
	if (!fd.compress && (fd.dir_size < (fs->blocksize - 24))) {
		fd.compress = 1;
		fd.dir_size = 0;
		fd.num_array = 0;
		goto retry_nohash;
	}

#if 0
	printf("%d entries (%d bytes) found in inode %d\n",
	       fd.num_array, fd.dir_size, ino);
#endif

	/* Sort the list */
resort:
	if (fd.compress && fd.num_array > 1)
		qsort(fd.harray+2, fd.num_array-2, sizeof(struct hash_entry),
		      hash_cmp);
	else
		qsort(fd.harray, fd.num_array, sizeof(struct hash_entry),
		      hash_cmp);

	/*
	 * Look for duplicates
	 */
	if (duplicate_search_and_fix(ctx, fs, ino, &fd))
		goto resort;

	if (ctx->options & E2F_OPT_NO) {
		retval = 0;
		goto errout;
	}

	/* Sort non-hashed directories by inode number */
	if (fd.compress && fd.num_array > 1)
		qsort(fd.harray+2, fd.num_array-2,
		      sizeof(struct hash_entry), ino_cmp);

	/*
	 * Copy the directory entries.  In a htree directory these
	 * will become the leaf nodes.
	 */
	retval = copy_dir_entries(ctx, &fd, &outdir);
	if (retval)
		goto errout;

	free(dir_buf); dir_buf = 0;

	if (!fd.compress) {
		/* Calculate the interior nodes */
		retval = calculate_tree(fs, &outdir, ino, fd.parent);
		if (retval)
			goto errout;
	}

	retval = write_directory(ctx, fs, &outdir, ino, &inode, fd.compress);
	if (retval)
		goto errout;

	if (ctx->options & E2F_OPT_CONVERT_BMAP)
		retval = e2fsck_rebuild_extents_later(ctx, ino);
	else
		retval = e2fsck_check_rebuild_extents(ctx, ino, &inode, pctx);
errout:
	free(dir_buf);
	free(fd.harray);

	free_out_dir(&outdir);
	return retval;
}
예제 #8
0
errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
{
	ext2_filsys		fs = ctx->fs;
	errcode_t		retval;
	struct ext2_inode	inode;
	char			*dir_buf = 0;
	struct fill_dir_struct	fd;
	struct out_dir		outdir;

	outdir.max = outdir.num = 0;
	outdir.buf = 0;
	outdir.hashes = 0;
	e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");

	retval = ENOMEM;
	fd.harray = 0;
	dir_buf = malloc(inode.i_size);
	if (!dir_buf)
		goto errout;

	fd.max_array = inode.i_size / 32;
	fd.num_array = 0;
	fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
	if (!fd.harray)
		goto errout;

	fd.ctx = ctx;
	fd.buf = dir_buf;
	fd.inode = &inode;
	fd.err = 0;
	fd.dir_size = 0;
	fd.compress = 0;
	if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
	    (inode.i_size / fs->blocksize) < 2)
		fd.compress = 1;
	fd.parent = 0;

	/* Read in the entire directory into memory */
	retval = ext2fs_block_iterate2(fs, ino, 0, 0,
				       fill_dir_block, &fd);
	if (fd.err) {
		retval = fd.err;
		goto errout;
	}

#if 0
	printf("%d entries (%d bytes) found in inode %d\n",
	       fd.num_array, fd.dir_size, ino);
#endif

	/* Sort the list */
resort:
	if (fd.compress)
		qsort(fd.harray+2, fd.num_array-2,
		      sizeof(struct hash_entry), ino_cmp);
	else
		qsort(fd.harray, fd.num_array,
		      sizeof(struct hash_entry), hash_cmp);

	/*
	 * Look for duplicates
	 */
	if (duplicate_search_and_fix(ctx, fs, ino, &fd))
		goto resort;

	if (ctx->options & E2F_OPT_NO) {
		retval = 0;
		goto errout;
	}

	/*
	 * Copy the directory entries.  In a htree directory these
	 * will become the leaf nodes.
	 */
	retval = copy_dir_entries(ctx, &fd, &outdir);
	if (retval)
		goto errout;

	free(dir_buf); dir_buf = 0;

	if (!fd.compress) {
		/* Calculate the interior nodes */
		retval = calculate_tree(fs, &outdir, ino, fd.parent);
		if (retval)
			goto errout;
	}

	retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
	if (retval)
		goto errout;

errout:
	free(dir_buf);
	free(fd.harray);

	free_out_dir(&outdir);
	return retval;
}