コード例 #1
0
ファイル: sys.c プロジェクト: UnitedMarsupials/kame
int
readit(char *buffer, int count)
{
    int logno, off, size;
    int cnt2, bnum2;
    struct fs *fs_copy;
    int n = 0;

    if (poff + count > inode.i_size)
	count = inode.i_size - poff;
    while (count > 0 && poff < inode.i_size) {
	fs_copy = fs;
	off = blkoff(fs_copy, poff);
	logno = lblkno(fs_copy, poff);
	cnt2 = size = blksize(fs_copy, &inode, logno);
	bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
	if (	(!off)  && (size <= count)) {
	    devread(buffer, bnum2, cnt2);
	} else {
	    size -= off;
	    if (size > count)
		size = count;
	    devread(iobuf, bnum2, cnt2);
	    bcopy(iobuf+off, buffer, size);
	}
	buffer += size;
	count -= size;
	poff += size;
	n += size;
    }
    return n;
}
コード例 #2
0
ファイル: sys.c プロジェクト: UnitedMarsupials/kame
static int
find(char *path)
{
    char *rest, ch;
    int block, off, loc, ino = ROOTINO;
    struct dirent *dp;
    char list_only;

    list_only = (path[0] == '?' && path[1] == '\0');
 loop:
    devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
    bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
	  (void *)&inode.i_din,
	  sizeof (struct dinode));
    if (!*path)
	return 1;
    while (*path == '/')
	path++;
    if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
	return 0;
    for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
    *rest = 0;
    loc = 0;
    do {
	if (loc >= inode.i_size) {
	    if (list_only) {
		putchar('\n');
		return -1;
	    } else {
		return 0;
	    }
	}
	if (!(off = blkoff(fs, loc))) {
	    block = lblkno(fs, loc);
	    devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
		    blksize(fs, &inode, block));
	}
	dp = (struct dirent *)(iobuf + off);
	loc += dp->d_reclen;
	if (dp->d_fileno && list_only) {
	    puts(dp->d_name);
	    putchar(' ');
	}
    } while (!dp->d_fileno || strcmp(path, dp->d_name));
    ino = dp->d_fileno;
    *(path = rest) = ch;
    goto loop;
}
コード例 #3
0
/*
 * Parse the DOS partition table to set the bounds of the slice we
 * are writing to. 
 */
int
readmbr(int slice)
{
	struct doslabel doslabel;
	int		cc;

	if (slice < 1 || slice > 4) {
		fprintf(stderr, "Slice must be 1, 2, 3, or 4\n");
 		return 1;
	}

	if ((cc = devread(outfd, doslabel.pad2, DOSPARTSIZE)) < 0) {
		perror("Could not read DOS label");
		return 1;
	}
	if (cc != DOSPARTSIZE) {
		fprintf(stderr, "Could not get the entire DOS label\n");
 		return 1;
	}
	if (doslabel.magic != BOOT_MAGIC) {
		fprintf(stderr, "Wrong magic number in DOS partition table\n");
 		return 1;
	}

	outputminsec  = doslabel.parts[slice-1].dp_start;
	outputmaxsec  = doslabel.parts[slice-1].dp_start +
		        doslabel.parts[slice-1].dp_size;
	outputmaxsize = (long long)sectobytes(outputmaxsec - outputminsec);

	if (debug) {
		fprintf(stderr, "Slice Mode: S:%d min:%ld max:%ld size:%qd\n",
			slice, outputminsec, outputmaxsec, outputmaxsize);
	}
	return 0;
}
コード例 #4
0
static struct dir_entry *
vstafs_nextdir (void)
{
  if (current_direntry > 15)
    {
      current_direntry = 0;
      if (++current_blockpos > (a1[curr_ext].a_len - 1))
	{
	  current_blockpos = 0;
	  curr_ext++;
	}

      if (curr_ext < FILE_INFO->extents)
	{
            devread (a1[curr_ext].a_start + current_blockpos, 0,
                     512, (char *) DIRECTORY_BUF);
	}
      else
	{
            /* errnum =ERR_FILE_NOT_FOUND; */
            return NULL;
	}
    }

  return &DIRECTORY_BUF[current_direntry++];
}
コード例 #5
0
ファイル: fworm.c プロジェクト: 99years/plan9
int
fwormread(Device *d, Off b, void *c)
{
	Iobuf *p;
	Device *fdev;
	Devsize l;

	if(DEBUG)
		print("fworm read  %lld\n", (Wideoff)b);
	fdev = FDEV(d);
	l = devsize(fdev);
	l -= l/(BUFSIZE*8) + 1;
	if(b >= l)
		panic("fworm: rbounds %lld", (Wideoff)b);
	l += b/(BUFSIZE*8);

	p = getbuf(fdev, l, Brd|Bres);
	if(!p || checktag(p, Tvirgo, l))
		panic("fworm: checktag %lld", (Wideoff)l);
	l = b % (BUFSIZE*8);
	if(!(p->iobuf[l/8] & (1<<(l%8)))) {
		putbuf(p);
		print("fworm: read %lld\n", (Wideoff)b);
		return 1;
	}
	putbuf(p);
	return devread(fdev, b, c);
}
コード例 #6
0
ファイル: hsfs.c プロジェクト: andreiw/polaris
static int
opendir(ino_t inode, struct iob *io)
{
	struct hs_direct hsdep;
	uint_t i;
	int retval;

	/* Set up the saio request */
	io->i_offset = 0;
	io->i_bn = hdbtodb(inode);
	io->i_cc = ISO_SECTOR_SIZE;

	if ((retval = devread(&io->i_si)) != ISO_SECTOR_SIZE)
		return (0);

	io->i_offset = 0;
	io->i_bn = hdbtodb(inode);

	if (inode != root_ino)
	    return (0);

	if (parse_dir(io, 0, &hsdep) > 0) {
		register struct inode *ip = &io->i_ino;

		bzero(io->i_ino, sizeof (struct inode));
		ip->i_size = hsdep.hs_dir.ext_size;
		ip->i_smode = hsdep.hs_dir.mode;
		ip->i_number = inode;
		return (0);
	}
	return (1);
}
コード例 #7
0
ファイル: hsfs.c プロジェクト: andreiw/polaris
/*
 * get next entry in a directory.
 */
static struct hs_direct *
readdir(struct dirstuff *dirp)
{
	static struct hs_direct hsdep;
	register struct direct *udp = &hsdep.hs_ufs_dir;
	struct inode *ip;
	struct iob *io;
	daddr_t lbn, d;
	int off;

	io = dirp->io;
	ip = &io->i_ino;
	for (;;) {
		if (dirp->loc >= ip->i_size) {
			return (NULL);
		}
		off = dirp->loc & ((1 << ISO_SECTOR_SHIFT) - 1);
		if (off == 0) {
			lbn = hdbtodb(dirp->loc >> ISO_SECTOR_SHIFT);
			io->i_bn = lbn + hdbtodb(ip->i_number);
			io->i_ma = io->i_buf;
			io->i_cc = ISO_SECTOR_SIZE;
			if (devread(&io->i_si) != io->i_cc) {
				return (NULL);
			}
		}
		dirp->loc += parse_dir(io, off, &hsdep);
		if (udp->d_reclen == 0 && dirp->loc <= ip->i_size) {
			dirp->loc = roundup(dirp->loc, ISO_SECTOR_SIZE);
			continue;
		}
		return (&hsdep);
	}
コード例 #8
0
ファイル: sub.c プロジェクト: npe9/harvey
int
devread(Device *d, Off b, void *c)
{
	int e;

	for (;;)
		switch(d->type) {
		case Devcw:
			return cwread(d, b, c);

		case Devjuke:
			d = d->j.m;
			break;

		case Devro:
			return roread(d, b, c);

		case Devwren:
			return wrenread(d, b, c);

		case Devworm:
		case Devlworm:
			return wormread(d, b, c);

		case Devfworm:
			return fwormread(d, b, c);

		case Devmcat:
			return mcatread(d, b, c);

		case Devmlev:
			return mlevread(d, b, c);

		case Devmirr:
			return mirrread(d, b, c);

		case Devpart:
			return partread(d, b, c);

		case Devswab:
			e = devread(d->swab.d, b, c);
			if(e == 0)
				swab(c, 0);
			return e;

		case Devnone:
			print("read from device none(%lld)\n", (Wideoff)b);
			return 1;
		default:
			panic("illegal device in devread: %Z %lld",
				d, (Wideoff)b);
			return 1;
		}
}
コード例 #9
0
ファイル: sys.c プロジェクト: UnitedMarsupials/kame
static int
block_map(int file_block)
{
	int bnum;
	if (file_block < NDADDR)
		return(inode.i_db[file_block]);
	if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
		devread(mapbuf, bnum, fs->fs_bsize);
		mapblock = bnum;
	}
	return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
}
コード例 #10
0
ファイル: bootp.c プロジェクト: AustenConrad/plan-9
int
etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
{
	int n;

	for (;;) {
		n = devread(ctlrno, (uchar*)pkt, sizeof(*pkt), 0);
		if (n >= 0)
			return n;
		if (timo-- < 0)
			return -1;
	}
}
コード例 #11
0
int
vstafs_mount (void)
{
  int retval = 1;

  if( (((current_drive & 0x80) || (current_slice != 0))
       && current_slice != PC_SLICE_TYPE_VSTAFS)
      ||  ! devread (0, 0, BLOCK_SIZE, (char *) FSYS_BUF)
      ||  FIRST_SECTOR->fs_magic != 0xDEADFACE)
    retval = 0;

  return retval;
}
コード例 #12
0
ファイル: sys.c プロジェクト: aosm/boot
static int getch(int fdesc)
{
	register struct iob *io;
	struct fs *fs;
	char *p;
	int c, lbn, off, size, diff;

	if ((io = iob_from_fdesc(fdesc)) == 0) {
		return (-1);
	}
	p = io->i_ma;
	if (io->i_cc <= 0) {
		if ((io->i_flgs & F_FILE) != 0) {
			diff = io->i_ino.i_size - io->i_offset;
			if (diff <= 0)
				return (-1);
			fs = io->i_fs;
			lbn = lblkno(fs, io->i_offset);
			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
			off = blkoff(fs, io->i_offset);
			size = blksize(fs, &io->i_ino, lbn);
		} else {
			diff = 0;
#ifndef	SMALL
			io->i_bn = io->i_offset / DEV_BSIZE;
			off = 0;
			size = DEV_BSIZE;
#endif	SMALL
		}
		io->i_ma = io->i_buf;
		io->i_cc = size;
		if (devread(io) < 0) {
			return (-1);
		}
		if ((io->i_flgs & F_FILE) != 0) {
			if (io->i_offset - off + size >= io->i_ino.i_size)
				io->i_cc = diff + off;
			io->i_cc -= off;
		}
		p = &io->i_buf[off];
	}
	io->i_cc--;
	io->i_offset++;
	c = (unsigned)*p++;
	io->i_ma = p;
	return (c);
}
コード例 #13
0
int
ffs_mount (void)
{
  int retval = 1;

  if ((((current_drive & 0x80) || (current_slice != 0))
       && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
      || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE))
      || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK)
      || SUPERBLOCK->fs_magic != FS_MAGIC)
    retval = 0;

  mapblock = -1;
  mapblock_offset = -1;
  
  return retval;
}
コード例 #14
0
ファイル: installboot.c プロジェクト: appleorange1/bitrig
static void
sbread(int fd, daddr_t poffset, struct fs **fs)
{
	int i;
	daddr_t sboff;

	for (i = 0; sbtry[i] != -1; i++) {
		sboff = sbtry[i] / DEV_BSIZE;
		devread(fd, sblock, poffset + sboff, SBSIZE, "superblock");
		*fs = (struct fs *)sblock;
		if (sbchk(*fs, sbtry[i]))
			break;
	}

	if (sbtry[i] == -1)
		errx(1, "couldn't find ffs superblock");
}
コード例 #15
0
ファイル: fsys_ufs2.c プロジェクト: HappyBasher/LINBOv3
static grub_int64_t
block_map (int file_block)
{
  int bnum, offset, bsize;
  
  if (file_block < NDADDR)
    return (INODE_UFS2->di_db[file_block]);
  
  /* If the blockmap loaded does not include FILE_BLOCK,
     load a new blockmap.  */

  if ((bnum = fsbtodb (SUPERBLOCK, INODE_UFS2->di_ib[0])) != mapblock
      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
    {
      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
	{
	  offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
	  bsize = MAPBUF_LEN;
	  
	  if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
	    offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
	}
      else
	{
	  bsize = SUPERBLOCK->fs_bsize;
	  offset = 0;
	}
      
      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF, 0xedde0d90))
	{
	  mapblock = -1;
	  mapblock_bsize = -1;
	  mapblock_offset = -1;
	  errnum = ERR_FSYS_CORRUPT;
	  return -1;
	}
      
      mapblock = bnum;
      mapblock_bsize = bsize;
      mapblock_offset = offset;
    }
  
  return (((grub_int64_t *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
				    - mapblock_offset]);
}
コード例 #16
0
static struct dir_entry *
vstafs_readdir (long sector)
{
  get_file_info (sector);
  if (FILE_INFO->type != 2)
    {
      errnum = ERR_FILE_NOT_FOUND;
      return 0;
    }
  
  a = FILE_INFO->blocks;
  curr_ext = 0;
  devread (a[curr_ext].a_start, 0, 512, (char *) DIRECTORY_BUF);
  current_direntry = 11;
  current_blockpos = 0;
  
  return &DIRECTORY_BUF[10];
}
コード例 #17
0
static struct dir_entry *
vstafs_readdir (long sector)
{
  /*
   * Get some information from the current directory
   */
  get_file_info (sector);
  if (FILE_INFO->type != 2)
    {
      errnum = ERR_FILE_NOT_FOUND;
      return NULL;
    }

  a1 = FILE_INFO->blocks;
  curr_ext = 0;
  devread (a1[curr_ext].a_start, 0, 512, (char *) DIRECTORY_BUF);
  current_direntry = 11;
  current_blockpos = 0;

  return &DIRECTORY_BUF[10];
}
コード例 #18
0
ファイル: fsys_ufs2.c プロジェクト: HappyBasher/LINBOv3
int
ufs2_mount (void)
{
  int retval = 0;
  int i;

  sblockloc = -1;
  type = 0;
  
//  if (! (((current_drive & 0x80) || (current_slice != 0))
//	 && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS)))
    {
      for (i = 0; sblock_try[i] != -1; ++i)
	{
	  if (! ((unsigned long)part_length < (sblock_try[i] + (SBLOCKSIZE / DEV_BSIZE))
		 || ! devread (0, sblock_try[i], SBLOCKSIZE, (char *) SUPERBLOCK, 0xedde0d90)))
	    {
	      if (SUPERBLOCK->fs_magic == FS_UFS2_MAGIC /* &&
							   (SUPERBLOCK->fs_sblockloc == sblockloc ||
						     (SUPERBLOCK->fs_old_flags & FS_FLAGS_UPDATED) == 0)*/)
		{
		  type = 2;
		}
	      else
		{
		  continue;
		}
	      
	      retval = 1;
	      sblockloc = sblock_try[i];
	      break;
	    }
	}
    }
  
  mapblock = -1;
  mapblock_offset = -1;
  
  return retval;
}
コード例 #19
0
int
fixmbr(int slice, int dtype)
{
	struct doslabel doslabel;
	int		cc;

	if (lseek(outfd, (off_t)0, SEEK_SET) < 0) {
		perror("Could not seek to DOS label");
		return 1;
	}
	if ((cc = devread(outfd, doslabel.pad2, DOSPARTSIZE)) < 0) {
		perror("Could not read DOS label");
		return 1;
	}
	if (cc != DOSPARTSIZE) {
		fprintf(stderr, "Could not get the entire DOS label\n");
 		return 1;
	}
	if (doslabel.magic != BOOT_MAGIC) {
		fprintf(stderr, "Wrong magic number in DOS partition table\n");
 		return 1;
	}

	if (doslabel.parts[slice-1].dp_typ != dostype) {
		doslabel.parts[slice-1].dp_typ = dostype;
		if (lseek(outfd, (off_t)0, SEEK_SET) < 0) {
			perror("Could not seek to DOS label");
			return 1;
		}
		cc = write(outfd, doslabel.pad2, DOSPARTSIZE);
		if (cc != DOSPARTSIZE) {
			perror("Could not write DOS label");
			return 1;
		}
		fprintf(stderr, "Set type of DOS partition %d to %d\n",
			slice, dostype);
	}
	return 0;
}
コード例 #20
0
ファイル: fsys_ufs2.c プロジェクト: HappyBasher/LINBOv3
unsigned long
ufs2_read (char *buf, unsigned long len, unsigned long write)
{
  unsigned long logno, off, size, ret = 0;
  grub_int64_t map;

  while (len && !errnum)
    {
      off = blkoff (SUPERBLOCK, filepos);
      logno = lblkno (SUPERBLOCK, filepos);
      size = blksize (SUPERBLOCK, INODE_UFS2, logno);

      if ((map = block_map (logno)) < 0)
	  break; 

      size -= off;

      if (size > len)
	  size = len;

      disk_read_func = disk_read_hook;

      devread (fsbtodb (SUPERBLOCK, map), off, size, buf, write);

      disk_read_func = NULL;

      if (buf)
	buf += size;
      len -= size;	/* len always >= 0 */
      filepos += size;
      ret += size;
    }

  if (errnum)
    ret = 0;

  return ret;
}
コード例 #21
0
ファイル: installboot.c プロジェクト: MarginC/kame
int
load_prep_partition(int devfd, struct mbr_partition *ppp)
{
    char mbr[512];
    struct mbr_partition *mbrp;
    int i;

    if (devread(devfd, mbr, MBR_BBSECTOR, DEV_BSIZE, "MBR") != 0)
        return 1;
    if (*(u_int16_t *)&mbr[MBR_MAGICOFF] != htole16(MBR_MAGIC)) {
        warn("no MBR_MAGIC");
        return 1;
    }

    mbrp = (struct mbr_partition *)&mbr[MBR_PARTOFF];
    for (i = 0; i < NMBRPART; i++) {
        if (mbrp[i].mbrp_typ == MBR_PTYPE_PREP)
            break;
    }
    if (i == NMBRPART) {
        warn("no PReP partition.");
        return 1;
    }

    if (verbose) {
        printf("PReP partition: start = %d, size = %d\n",
               le32toh(mbrp[i].mbrp_start), le32toh(mbrp[i].mbrp_size));
    }

    if (ppp) {
        *ppp = mbrp[i];
        ppp->mbrp_start = le32toh(ppp->mbrp_start);
        ppp->mbrp_size = le32toh(ppp->mbrp_size);
    }

    return 0;
}
コード例 #22
0
ファイル: sys.c プロジェクト: aosm/boot
static int
openi(int n, struct iob *io)
{
	struct dinode *dp;
	int cc;
#if ICACHE
	struct icommon *ip;
	
	if (icache == 0) {
	    icache = cacheInit(ICACHE_SIZE, sizeof(struct icommon));
	}
#endif ICACHE
	io->i_offset = 0;
	io->i_bn = fsbtodb(io->i_fs, itod(io->i_fs, n)) + io->i_boff;
	io->i_cc = io->i_fs->fs_bsize;
	io->i_ma = io->i_buf;

#if ICACHE
	if (cacheFind(icache, n, 0, (char **)&ip) == 1) {
		io->i_ino.i_ic = *ip;
		cc = 0;
	} else {
#endif ICACHE
	    cc = devread(io);
	    dp = (struct dinode *)io->i_buf;
#if	BIG_ENDIAN_FS
	    byte_swap_inode_in(&dp[itoo(io->i_fs, n)].di_ic, &io->i_ino.i_ic);
#else
	    io->i_ino.i_ic = dp[itoo(io->i_fs, n)].di_ic;
#endif	BIG_ENDIAN_FS
#if ICACHE
	    *ip = io->i_ino.i_ic;
	}
#endif ICACHE
	io->i_ino.i_number = n;
	return (cc);
}
コード例 #23
0
int
ufs2_read (char *buf, int len)
{
  int logno, off, size, ret = 0;
  grub_int64_t map;

  while (len && !errnum)
    {
      off = blkoff (SUPERBLOCK, filepos);
      logno = lblkno (SUPERBLOCK, filepos);
      size = blksize (SUPERBLOCK, INODE_UFS2, logno);

      if ((map = block_map (logno)) < 0)
	break; 

      size -= off;

      if (size > len)
	size = len;

      disk_read_func = disk_read_hook;

      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);

      disk_read_func = NULL;

      buf += size;
      len -= size;
      filepos += size;
      ret += size;
    }

  if (errnum)
    ret = 0;

  return ret;
}
コード例 #24
0
ファイル: sys.c プロジェクト: aosm/boot
int
read(int fdesc, char *buf, int count)
{
	int i, size;
	register struct iob *file;
	struct fs *fs;
	int lbn, off;

	if ((file = iob_from_fdesc(fdesc)) == 0) {
		return (-1);
	}
	if ((file->i_flgs&F_READ) == 0) {
		return (-1);
	}
#ifndef	SMALL
	if ((file->i_flgs & F_FILE) == 0) {
		file->i_cc = count;
		file->i_ma = buf;
		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
		i = devread(file);
		file->i_offset += count;
		return (i);
	}
#endif	SMALL
	if (file->i_offset+count > file->i_ino.i_size)
		count = file->i_ino.i_size - file->i_offset;
	if ((i = count) <= 0)
		return (0);
	/*
	 * While reading full blocks, do I/O into user buffer.
	 * Anything else uses getc().
	 */
	fs = file->i_fs;
	while (i) {
		off = blkoff(fs, file->i_offset);
		lbn = lblkno(fs, file->i_offset);
		size = blksize(fs, &file->i_ino, lbn);
		if (off == 0 && size <= i) {
			file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
			    file->i_boff;
			file->i_cc = size;
			file->i_ma = buf;
			if (devread(file) < 0) {
				return (-1);
			}
			file->i_offset += size;
			file->i_cc = 0;
			buf += size;
			i -= size;
		} else {
			size -= off;
			if (size > i)
				size = i;
			i -= size;
			do {
				*buf++ = getch(fdesc);
			} while (--size);
		}
	}
	return (count);
}
コード例 #25
0
ファイル: sys.c プロジェクト: aosm/boot
int
open(char *str, int how)
{
	register char *cp;
	register struct iob *file;
	int i, fdesc;

#if CHECK_CAREFULLY	/* iob[] is in BSS, so it is guaranteed to be zero. */
	if (open_init == 0) {
		for (i = 0; i < NFILES; i++)
			iob[i].i_flgs = 0;
		open_init = 1;
	}
#endif

	for (fdesc = 0; fdesc < NFILES; fdesc++)
		if (iob[fdesc].i_flgs == 0)
			goto gotfile;
 	stop("Out of file descriptor slots");

gotfile:
	(file = &iob[fdesc])->i_flgs |= F_ALLOC;

	if ((cp = xx(str, file)) == (char *) -1)
	{
		close(fdesc);
		return -1;
	}

	if (*cp == '\0') {
		file->i_flgs |= how+1;
		file->i_cc = 0;
		file->i_offset = 0;
		return (fdesc);
	}
	file->i_cc = SBSIZE;
	file->i_bn = (SBLOCK / DEV_BSIZE) + file->i_boff;
	file->i_offset = 0;

	if (file->i_fs == 0) {
		if (fs_block == 0) {
		    fs_block = (struct fs *)malloc(SBSIZE);
		}
		if (fs_block_valid == 0) {
		    file->i_ma = (char *)fs_block;
		    if (devread(file) < 0) {
#ifndef SMALL
			    error(SUPERBLOCK_ERROR, 1);
#endif
			    close(fdesc);
			    return (-1);
		    }
		    byte_swap_superblock(fs_block);
		    fs_block_valid = 1;
		}
		file->i_fs = fs_block;
		file->i_buf = malloc(MAXBSIZE);
	}
#if	BIG_ENDIAN_FS

	if (file->i_fs->fs_magic != FS_MAGIC) {
		error(SUPERBLOCK_ERROR, 2);
		close(fdesc);
		return (-1);
	}
	/*
	 *  The following is a gross hack to boot disks that have an actual
	 *  blocksize of 512 bytes but were written with a theoretical 1024
	 *  byte blocksize (fsbtodb == 0).
	 *
	 *  We can make this assumption because we can only boot disks with
	 *  a 512 byte sector size.
	 */
	if (file->i_fs->fs_fsize == 0) {
		error(SUPERBLOCK_ERROR,3);
		close(fdesc);
		return (-1);
	}
	file->i_fs->fs_fsbtodb = ffs(file->i_fs->fs_fsize / DEV_BSIZE) - 1;
#endif	BIG_ENDIAN_FS

	if ((i = find(cp, file)) == 0) {
		close(fdesc);
		return (-1);
	}
#if	CHECK_CAREFULLY
	if (how != 0) {
		error("Can't write files\n");
		close(fdesc);
		return (-1);
	}
#endif	CHECK_CAREFULLY

	if (openi(i, file) < 0) {
		close(fdesc);
		return (-1);
	}
	file->i_offset = 0;
	file->i_cc = 0;
	file->i_flgs |= F_FILE | (how+1);

	return (fdesc);
}
コード例 #26
0
int
vstafs_read (char *addr, int len)
{
  struct alloc *a2;
  int size, ret = 0, offset, curr_len = 0;
  int curr_ext2;
  char extent;
  int ext_size;
  char *curr_pos;

  get_file_info (f_sector);
  size = FILE_INFO->len-VSTAFS_START_DATA;
  a2 = FILE_INFO->blocks;

  if (filepos > 0)
    {
      if (filepos < a2[0].a_len * 512 - VSTAFS_START_DATA)
	{
	  offset = filepos + VSTAFS_START_DATA;
	  extent = 0;
          curr_len = a2[0].a_len * 512 - offset - filepos;
	}
      else
	{
          ext_size = a2[0].a_len * 512 - VSTAFS_START_DATA;
	  offset = filepos - ext_size;
	  extent = 1;
	  do
	    {
	      curr_len -= ext_size;
	      offset -= ext_size;
              ext_size = a2[extent+1].a_len * 512;
	    }
	  while (extent < FILE_INFO->extents && offset>ext_size);
	}
    }
  else
    {
      offset = VSTAFS_START_DATA;
      extent = 0;
      curr_len = a2[0].a_len * 512 - offset;
    }

  curr_pos = addr;
  if (curr_len > len)
    curr_len = len;

  for (curr_ext2=extent;
       curr_ext2 < FILE_INFO->extents;
       curr_len = a2[curr_ext].a_len * 512, curr_pos += curr_len, curr_ext2++)
    {
      ret += curr_len;
      size -= curr_len;
      if (size < 0)
	{
	  ret += size;
	  curr_len += size;
	}

      devread (a2[curr_ext2].a_start,offset, curr_len, curr_pos);
      offset = 0;
    }

  return ret;
}
コード例 #27
0
ファイル: sys.c プロジェクト: aosm/boot
/*
 * get next entry in a directory.
 */
struct direct *
readdir(struct dirstuff *dirp)
{
	struct direct *dp;
	register struct iob *io;
	daddr_t lbn, d;
	int off;
#if DCACHE
	char *bp;
	int dirblkno;

	if (dcache == 0)
		dcache = cacheInit(DCACHE_SIZE, DIRBLKSIZ);
#endif DCACHE
	io = dirp->io;
	for(;;)
	{
		if (dirp->loc >= io->i_ino.i_size)
			return (NULL);
		off = blkoff(io->i_fs, dirp->loc);
		lbn = lblkno(io->i_fs, dirp->loc);

#if DCACHE
		dirblkno = dirp->loc / DIRBLKSIZ;
		if (cacheFind(dcache, io->i_ino.i_number, dirblkno, &bp)) {
		    dp = (struct direct *)(bp + (dirp->loc % DIRBLKSIZ));
		} else
#else DCACHE
		if (io->dirbuf_blkno != lbn)
#endif DCACHE
		{
		    if((d = sbmap(io, lbn)) == 0)
			    return NULL;
		    io->i_bn = fsbtodb(io->i_fs, d) + io->i_boff;
		    io->i_ma = io->i_buf;
		    io->i_cc = blksize(io->i_fs, &io->i_ino, lbn);
		
		    if (devread(io) < 0)
		    {
#if	SYS_MESSAGES
			    error("bn %d: directory read error\n",
				    io->i_bn);
#endif
			    return (NULL);
		    }
#if	BIG_ENDIAN_FS
		    byte_swap_dir_block_in(io->i_buf, io->i_cc);
#endif	BIG_ENDIAN_FS
#if DCACHE
		    bcopy(io->i_buf + dirblkno * DIRBLKSIZ, bp, DIRBLKSIZ);
		    dp = (struct direct *)(io->i_buf + off);
#endif
		}
#if !DCACHE
		dp = (struct direct *)(io->i_buf + off);
#endif
		dirp->loc += dp->d_reclen;

		if (dp->d_ino != 0) return (dp);
	}
}
コード例 #28
0
ファイル: sys.c プロジェクト: aosm/boot
static daddr_t
sbmap(struct iob *io, daddr_t bn)
{
	register struct inode *ip;
	int i, j, sh;
	daddr_t nb, *bap;

	ip = &io->i_ino;

	if (ip->i_icflags & IC_FASTLINK)
	{
		error("fast symlinks unimplemented\n");
		return ((daddr_t)0);
	}

	if (bn < 0) {
#if	SYS_MESSAGES
		error("bn negative\n");
#endif
		return ((daddr_t)0);
	}

	/*
	 * blocks 0..NDADDR are direct blocks
	 */
	if(bn < NDADDR)
	{
		nb = ip->i_db[bn];
		return (nb);
	}

	/*
	 * addresses NIADDR have single and double indirect blocks.
	 * the first step is to determine how many levels of indirection.
	 */
	sh = 1;
	bn -= NDADDR;
	for (j = NIADDR; j > 0; j--) {
		sh *= NINDIR(io->i_fs);
		if (bn < sh)
			break;
		bn -= sh;
	}
	if (j == 0) {
#if	SYS_MESSAGES
		error("bn ovf %d\n", bn);
#endif
		return ((daddr_t)0);
	}

	/*
	 * fetch the first indirect block address from the inode
	 */
	nb = ip->i_ib[NIADDR - j];
	if (nb == 0) {
#if	SYS_MESSAGES
		error("bn void %d\n",bn);
#endif
		return ((daddr_t)0);
	}

	/*
	 * fetch through the indirect blocks
	 */
	for (; j <= NIADDR; j++) {
		if (blknos[j] != nb) {
			io->i_bn = fsbtodb(io->i_fs, nb) + io->i_boff;
			if (b[j] == (char *)0)
				b[j] = malloc(MAXBSIZE);
			io->i_ma = b[j];
			io->i_cc = io->i_fs->fs_bsize;
			if (devread(io) != io->i_fs->fs_bsize) {
#if	SYS_MESSAGES
				error("bn %d: read error\n", io->i_bn);
#endif
				return ((daddr_t)0);
			}
			blknos[j] = nb;
		}
		bap = (daddr_t *)b[j];
		sh /= NINDIR(io->i_fs);
		i = (bn / sh) % NINDIR(io->i_fs);
#if	BIG_ENDIAN_FS
#if 1
		// for now it is little endian FS for intel
		nb = bap[i];
#else
		nb = OSSwapBigToHostInt32(bap[i]);
#endif 1
#else	BIG_ENDIAN_FS
		nb = bap[i];
#endif	BIG_ENDIAN_FS
		if(nb == 0) {
#if	SYS_MESSAGES
			error("bn void %d\n",bn);
#endif
			return ((daddr_t)0);
		}
	}

	return (nb);
}
コード例 #29
0
static void
get_file_info (int sector)
{
  devread (sector, 0, BLOCK_SIZE, (char *) FILE_INFO);
}
コード例 #30
0
ファイル: installboot.c プロジェクト: lacombar/netbsd-alc
int
loadblocknums(char *boot, int devfd)
{
	int		i, fd;
	struct	stat	statbuf;
	struct	statvfs	statvfsbuf;
	struct fs	*fs;
	char		*buf;
	daddr_t		blk, *ap;
	struct ufs1_dinode *ip;
	int		ndb;

	/*
	 * Open 2nd-level boot program and record the block numbers
	 * it occupies on the filesystem represented by `devfd'.
	 */

	/* Make sure the (probably new) boot file is on disk. */
	sync(); sleep(1);

	if ((fd = open(boot, O_RDONLY)) < 0)
		err(1, "open: %s", boot);

	if (fstatvfs(fd, &statvfsbuf) != 0)
		err(1, "statfs: %s", boot);

	if (strncmp(statvfsbuf.f_fstypename, "ffs",
	    sizeof(statvfsbuf.f_fstypename)) &&
	    strncmp(statvfsbuf.f_fstypename, "ufs",
	    sizeof(statvfsbuf.f_fstypename))) {
		errx(1, "%s: must be on an FFS filesystem", boot);
	}

	if (fsync(fd) != 0)
		err(1, "fsync: %s", boot);

	if (fstat(fd, &statbuf) != 0)
		err(1, "fstat: %s", boot);

	close(fd);

	/* Read superblock */
	devread(devfd, sblock, (daddr_t)(BBSIZE / DEV_BSIZE),
	    SBLOCKSIZE, "superblock");
	fs = (struct fs *)sblock;

	/* Sanity-check super-block. */
	if (fs->fs_magic != FS_UFS1_MAGIC)
		errx(1, "Bad magic number in superblock, must be UFS1");
	if (fs->fs_inopb <= 0)
		err(1, "Bad inopb=%d in superblock", fs->fs_inopb);

	/* Read inode */
	if ((buf = malloc(fs->fs_bsize)) == NULL)
		errx(1, "No memory for filesystem block");

	blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));
	devread(devfd, buf, blk, fs->fs_bsize, "inode");
	ip = (struct ufs1_dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);

	/*
	 * Have the inode.  Figure out how many blocks we need.
	 */
	ndb = howmany(ip->di_size, fs->fs_bsize);
	if (ndb > maxblocknum)
		errx(1, "Too many blocks");
	*block_count_p = ndb;
	*block_size_p = fs->fs_bsize;
	if (verbose)
		printf("Will load %d blocks of size %d each.\n",
		    ndb, fs->fs_bsize);

	/*
	 * Get the block numbers; we don't handle fragments
	 */
	ap = ip->di_db;
	for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) {
		blk = fsbtodb(fs, *ap);
		if (verbose)
			printf("%d: %d\n", i, blk);
		block_table[i] = blk;
	}
	if (ndb == 0)
		return 0;

	/*
	 * Just one level of indirections; there isn't much room
	 * for more in the 1st-level bootblocks anyway.
	 */
	blk = fsbtodb(fs, ip->di_ib[0]);
	devread(devfd, buf, blk, fs->fs_bsize, "indirect block");
	/* XXX ondisk32 */
	ap = (int32_t *)buf;
	for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) {
		blk = fsbtodb(fs, *ap);
		if (verbose)
			printf("%d: %d\n", i, blk);
		block_table[i] = blk;
	}

	return 0;
}