Пример #1
0
int
dir_try_enter(zone_t z, ino_t child, char const *name)
{
  struct direct *dir_entry = alloc_block();
  int r = 0;
  block_t b;
  int i, l;

  b = z << zone_shift;
  for (l = 0; l < zone_per_block; l++, b++) {
	get_block(b, dir_entry);

	for (i = 0; i < NR_DIR_ENTRIES(block_size); i++)
		if (!dir_entry[i].d_ino)
			break;

	if(i < NR_DIR_ENTRIES(block_size)) {
		r = 1;
		dir_entry[i].d_ino = child;
		assert(sizeof(dir_entry[i].d_name) == MFS_DIRSIZ);
		if (verbose && strlen(name) > MFS_DIRSIZ)
			fprintf(stderr, "File name %s is too long, truncated\n", name);
		strncpy(dir_entry[i].d_name, name, MFS_DIRSIZ);
		put_block(b, dir_entry);
		break;
	}
  }

  free(dir_entry);

  return r;
}
Пример #2
0
/*
 * Search a directory for a name and return its
 * inode number.
 */
static int
search_directory(const char *name, int length, struct open_file *f,
	ino32_t *inumber_p)
{
	struct file *fp = (struct file *)f->f_fsdata;
	struct mfs_sblock *fs = fp->f_fs;
	struct mfs_direct *dp;
	struct mfs_direct *dbuf;
	size_t buf_size;
	int namlen;
	int rc;

	fp->f_seekp = 0;

	while (fp->f_seekp < (off_t)fp->f_di.mdi_size) {
		rc = buf_read_file(f, (void *)&dbuf, &buf_size);
		if (rc)
			return rc;
		if (buf_size == 0)
			return EIO;

		/* XXX we assume, that buf_read_file reads an fs block and
		 * doesn't truncate buffer. Currently i_size in MFS doesn't
		 * the same as size of allocated blocks, it makes buf_read_file
		 * to truncate buf_size.
		 */
		if (buf_size < fs->mfs_block_size)
			buf_size = fs->mfs_block_size;

		for (dp = dbuf; dp < &dbuf[NR_DIR_ENTRIES(fs)]; dp++) {
			char *cp;
			if (fs2h32(dp->mfsd_ino) == (ino32_t) 0)
				continue;
			/* Compute the length of the name */
			cp = memchr(dp->mfsd_name, '\0', sizeof(dp->mfsd_name));
			if (cp == NULL)
				namlen = sizeof(dp->mfsd_name);
			else
				namlen = cp - (dp->mfsd_name);

			if (namlen == length &&
			    !memcmp(name, dp->mfsd_name, length)) {
				/* found entry */
				*inumber_p = fs2h32(dp->mfsd_ino);
				return 0;
			}
		}
		fp->f_seekp += buf_size;
	}
	return ENOENT;
}
Пример #3
0
void
sizeup_dir(struct fs_size * fssize)
{
  char *token[MAX_TOKENS], *p;
  char line[LINE_LEN]; 
  FILE *f;
  off_t size;
  int dir_entries = 2;
  zone_t dir_zones = 0, fzones, indirects;

  while (1) {
	get_line(line, token);
	p = token[0];
	if (*p == '$') {
		dir_zones = (dir_entries / (NR_DIR_ENTRIES(block_size) * zone_per_block));
		if(dir_entries % (NR_DIR_ENTRIES(block_size) * zone_per_block))
			dir_zones++;
		if(dir_zones > NR_DZONES)
			dir_zones++;	/* Max single indir */
		fssize->zonecount += dir_zones;
		return;
	}

	p = token[1];
	fssize->inocount++;
	dir_entries++;

	if (*p == 'd') {
		sizeup_dir(fssize);
	} else if (*p == 'b' || *p == 'c') {

	} else if (*p == 's') {
		fssize->zonecount++; /* Symlink contents is always stored a block */
	} else {
		if ((f = fopen(token[4], "rb")) == NULL) {
			warn("dynamic sizing: can't open %s", token[4]);
		} else if (fseek(f, 0, SEEK_END) < 0) {
			pexit("dynamic size detection failed: seek to end of %s",
			    token[4]);
		} else if ( (size = ftell(f)) == (off_t)(-1)) {
			pexit("dynamic size detection failed: can't tell size of %s",
			    token[4]);
		} else {
			fclose(f);
			fzones = roundup(size, zone_size) / zone_size;
			indirects = 0;
			/* XXX overflow? fzones is u32, size is potentially 64-bit */
			if (fzones > NR_DZONES)
				indirects++; /* single indirect needed */
			if (fzones > nr_indirzones) {
				/* Each further group of 'indir_per_zone'
				 * needs one supplementary indirect zone:
				 */
				indirects += roundup(fzones - nr_indirzones,
				    indir_per_zone) / indir_per_zone;
				indirects++;	/* + double indirect needed!*/
			}
			fssize->zonecount += fzones + indirects;
		}
	}
  }
}
Пример #4
0
void
print_fs(void)
{
  int i, j;
  ino_t k;
  struct inode *inode2;
  unsigned short *usbuf;
  block_t b;
  struct direct *dir;

  assert(inodes_per_block * sizeof(*inode2) == block_size);
  if(!(inode2 = alloc_block()))
	err(1, "couldn't allocate a block of inodes");

  assert(NR_DIR_ENTRIES(block_size)*sizeof(*dir) == block_size);
  if(!(dir = alloc_block()))
	err(1, "couldn't allocate a block of directory entries");

  usbuf = alloc_block();
  get_super_block(usbuf);
  printf("\nSuperblock: ");
  for (i = 0; i < 8; i++) printf("%06ho ", usbuf[i]);
  printf("\n            ");
  for (i = 0; i < 8; i++) printf("%#04hX ", usbuf[i]);
  printf("\n            ");
  for (i = 8; i < 15; i++) printf("%06ho ", usbuf[i]);
  printf("\n            ");
  for (i = 8; i < 15; i++) printf("%#04hX ", usbuf[i]);
  get_block((block_t) INODE_MAP, usbuf);
  printf("...\nInode map:  ");
  for (i = 0; i < 9; i++) printf("%06ho ", usbuf[i]);
  get_block((block_t) zone_map, usbuf);
  printf("...\nZone  map:  ");
  for (i = 0; i < 9; i++) printf("%06ho ", usbuf[i]);
  printf("...\n");

  free(usbuf);
  usbuf = NULL;

  k = 0;
  for (b = inode_offset; k < nrinodes; b++) {
	get_block(b, inode2);
	for (i = 0; i < inodes_per_block; i++) {
		k = inodes_per_block * (int) (b - inode_offset) + i + 1;
		/* Lint but OK */
		if (k > nrinodes) break;
		{
			if (inode2[i].i_mode != 0) {
				printf("Inode %3u:  mode=", (unsigned)k);
				printf("%06o", (unsigned)inode2[i].i_mode);
				printf("  uid=%2d  gid=%2d  size=",
					(int)inode2[i].i_uid, (int)inode2[i].i_gid);
				printf("%6ld", (long)inode2[i].i_size);
				printf("  zone[0]=%u\n", (unsigned)inode2[i].i_zone[0]);
			}
			if ((inode2[i].i_mode & S_IFMT) == S_IFDIR) {
				/* This is a directory */
				get_block(inode2[i].i_zone[0] << zone_shift, dir);
				for (j = 0; j < NR_DIR_ENTRIES(block_size); j++)
					if (dir[j].d_ino)
						printf("\tInode %2u: %s\n",
							(unsigned)dir[j].d_ino,
							dir[j].d_name);
			}
		}
	}
  }

  if (zone_shift)
	printf("%d inodes used.     %u zones (%u blocks) used.\n",
		(int)next_inode-1, next_zone, next_zone*zone_per_block);
  else
	printf("%d inodes used.     %u zones used.\n", (int)next_inode-1, next_zone);
  free(dir);
  free(inode2);
}