Example #1
0
/* 
 * read data from a locked inode.
 * returns -1 on error.
 * */
int readi(struct inode *ip, char *buf, uint off, uint cnt){
    struct buf *bp;
    uint tot=0, m=0, bn=0;

    // file size limit 
    if ((off > ip->i_size) || (off+cnt < off)){
        cu->p_error = E2BIG;
        return -1;
    }
    if (off+cnt > ip->i_size) {
        cnt = ip->i_size - off;
    }
    // read
    for(tot=0; tot<cnt; tot+=m, off+=m, buf+=m){
        m = min(cnt - tot, BLK - off%BLK);
        bn = bmap(ip, off/BLK, 0);
        if (bn == 0) {
            memset(bp->b_data + off%BLK, 0, m);
        }
        else {
            bp = bread(ip->i_dev, bn);
            memcpy(buf, bp->b_data + off%BLK, m);
            brelse(bp);
        }
    }
    return cnt;
}
// Look for a directory entry in a directory.
// If found, set *poff to byte offset of entry.
// Caller must have already locked dp.
struct inode*
dirlookup(struct inode *dp, char *name, uint *poff)
{
  uint off, inum;
  struct buf *bp;
  struct dirent *de;

  if(dp->type != T_DIR)
    panic("dirlookup not DIR");

  for(off = 0; off < dp->logical_size; off += BSIZE){
    bp = bread(dp->dev, bmap(dp, off / BSIZE));
    for(de = (struct dirent*)bp->data;
        de < (struct dirent*)(bp->data + BSIZE);
        de++){
      if(de->inum == 0)
        continue;
      if(namecmp(name, de->name) == 0){
        // entry matches path element
        if(poff)
          *poff = off + (uchar*)de - bp->data;
        inum = de->inum;
        brelse(bp);
        return iget(dp->dev, inum);
      }
    }
    brelse(bp);
  }
  return 0;
}
Example #3
0
// PAGEBREAK!
// Read data from inode.
int readi(struct inode* ip, char* dst, uint off, uint n)
{
    uint tot, m;
    struct buf* bp;
    struct superblock sb;
    //      cprintf("readi \n");
    sb = sbs[ip->part->number];
    if (ip->type == T_DEV) {
        if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read)
            return -1;
        return devsw[ip->major].read(ip, dst, n);
    }

    if (off > ip->size || off + n < off)
        return -1;
    if (off + n > ip->size)
        n = ip->size - off;

    for (tot = 0; tot < n; tot += m, off += m, dst += m) {
        uint bmapOut = bmap(ip, off / BSIZE);
        // cprintf("bout %d \n",bmapOut);
        bp = bread(ip->dev, sb.offset + bmapOut);
        m = min(n - tot, BSIZE - off % BSIZE);
        memmove(dst, bp->data + off % BSIZE, m);
        brelse(bp);
    }
    return n;
}
Example #4
0
void BitmapImage::checkForSolidColor()
{
    m_checkedForSolidColor = true;
    if (frameCount() > 1) {
        m_isSolidColor = false;
        return;
    }

    CGImageRef image = frameAtIndex(0);
    
    // Currently we only check for solid color in the important special case of a 1x1 image.
    if (image && CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) {
        unsigned char pixel[4]; // RGBA
        static CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
        RetainPtr<CGContextRef> bmap(AdoptCF, CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), space,
            kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
        if (!bmap)
            return;
        GraphicsContext(bmap.get()).setCompositeOperation(CompositeCopy);
        CGRect dst = { {0, 0}, {1, 1} };
        CGContextDrawImage(bmap.get(), dst, image);
        if (pixel[3] == 0)
            m_solidColor = Color(0, 0, 0, 0);
        else
            m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]);
        m_isSolidColor = true;
    }
}
Example #5
0
/*
 * get next entry in a directory.
 */
struct direct *
dreaddir(struct dirstuff *dirp)
{
	struct direct *dp;
	diskaddr_t lbn, d;

	for (;;) {
		if (dirp->loc >= (int)dirp->ip->di_size)
			return (NULL);
		if (blkoff(&sblock, dirp->loc) == 0) {
			lbn = lblkno(&sblock, dirp->loc);
			d = bmap(lbn);
			if (d == 0)
				return (NULL);
			bread(fsbtodb(&sblock, d), dirp->dbuf,
			    (int)dblksize(&sblock, dirp->ip, (int)lbn));
		}
		dp = (struct direct *)
		    (dirp->dbuf + blkoff(&sblock, dirp->loc));
		dirp->loc += dp->d_reclen;
		if (dp->d_ino == 0)
			continue;
		return (dp);
	}
}
Example #6
0
File: fs.c Project: SilunWang/xv6
//PAGEBREAK!
// Read data from inode.
int
readi(struct inode *ip, char *dst, uint off, uint n)
{
  uint tot, m;
  struct buf *bp;

  if(ip->type == T_DEV){
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read)
      return -1;
    return devsw[ip->major].read(ip, dst, n);
  }

  if(off > ip->size || off + n < off)
    return -1;
  if(off + n > ip->size)
    n = ip->size - off;

  for(tot=0; tot<n; tot+=m, off+=m, dst+=m){
    bp = bread(ip->dev, bmap(ip, off/BSIZE));
    m = min(n - tot, BSIZE - off%BSIZE);
    memmove(dst, bp->data + off%BSIZE, m);
    brelse(bp);
  }
  return n;
}
Example #7
0
int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
{
	int left,chars,nr;
	struct buffer_head * bh;

	if ((left=count)<=0)
		return 0;
	while (left) {
		if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) {
			if (!(bh=bread(inode->i_dev,nr)))
				break;
		} else
			bh = NULL;
		nr = filp->f_pos % BLOCK_SIZE;
		chars = MIN( BLOCK_SIZE-nr , left );
		filp->f_pos += chars;
		left -= chars;
		if (bh) {
			char * p = nr + bh->b_data;
			while (chars-->0)
				put_fs_byte(*(p++),buf++);
			brelse(bh);
		} else {
			while (chars-->0)
				put_fs_byte(0,buf++);
		}
	}
	inode->i_atime = CURRENT_TIME;
	return (count-left)?(count-left):-ERROR;
}
Example #8
0
// PAGEBREAK!
// Write data to inode.
int writei(struct inode* ip, char* src, uint off, uint n)
{
    // cprintf("writei \n");

    uint tot, m;
    struct buf* bp;
    struct superblock sb;
    sb = sbs[ip->part->number];

    if (ip->type == T_DEV) {
        if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
            return -1;
        return devsw[ip->major].write(ip, src, n);
    }

    if (off > ip->size || off + n < off)
        return -1;
    if (off + n > MAXFILE * BSIZE)
        return -1;

    for (tot = 0; tot < n; tot += m, off += m, src += m) {
        uint bmapOut = bmap(ip, off / BSIZE);
        bp = bread(ip->dev, sb.offset + bmapOut);
        m = min(n - tot, BSIZE - off % BSIZE);
        memmove(bp->data + off % BSIZE, src, m);
        log_write(bp, ip->part->number);
        brelse(bp);
    }

    if (n > 0 && off > ip->size) {
        ip->size = off;
        iupdate(ip);
    }
    return n;
}
Example #9
0
/*
 * write data to a regular file.
 * */
int writei(struct inode *ip, char *buf, uint off, uint cnt){
    struct buf *bp;
    uint tot=0, m=0, bn=0;

    if (off+cnt < off){
        return -1;
    }
    if (off+cnt > MAX_FILESIZ) {
        cnt = MAX_FILESIZ - off;
    }
    // do write.
    for(tot=0; tot<cnt; tot+=m, off+=m, buf+=m){
        m = min(cnt - tot, BLK - off%BLK);
        bn = bmap(ip, off/BLK, 1);
        if (bn==0) {
            panic("bad block.");
        }
        else {
            bp = bread(ip->i_dev, bn); // note here!
            memcpy(bp->b_data + off%BLK, buf, m);
            bwrite(bp);
            brelse(bp);
        }
    }
    // adjust the inode's file size
    if (cnt > 0 && off > ip->i_size) {
        ip->i_size = off;
        iupdate(ip);
    }
    return cnt;
}
Example #10
0
File: fs.c Project: SilunWang/xv6
// PAGEBREAK!
// Write data to inode.
int
writei(struct inode *ip, char *src, uint off, uint n)
{
  uint tot, m;
  struct buf *bp;

  if(ip->type == T_DEV){
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
      return -1;
    return devsw[ip->major].write(ip, src, n);
  }

  if(off > ip->size || off + n < off)
    return -1;
  if(off + n > MAXFILE*BSIZE)
    return -1;

  for(tot=0; tot<n; tot+=m, off+=m, src+=m){
    bp = bread(ip->dev, bmap(ip, off/BSIZE));
    m = min(n - tot, BSIZE - off%BSIZE);
    memmove(bp->data + off%BSIZE, src, m);
    log_write(bp);
    brelse(bp);
  }

  if(n > 0 && off > ip->size){
    ip->size = off;
    iupdate(ip);
  }
  return n;
}
Example #11
0
File: map.c Project: chobits/tinyos
struct block *bmap_block(struct inode *inode, int blk, int create)
{
	if ((blk = bmap(inode, blk, create)) < 0)
		return NULL;
	else if (blk == 0)
		return MINIX_ZERO_BLOCK;
	return minix_get_block(inode->i_sb, blk);
}
Example #12
0
// Check data from inode to see if it is in the buffer cache.
int
checki(struct inode *ip, int off)
{
	if(off > ip->size)
		return -1;
	//cprintf("checki: calling bcheck\n");
    return bcheck(ip->dev, bmap(ip, off/BSIZE, 0));

 }
Example #13
0
static int do_readahead(journal_t *journal, unsigned int start)
{
	int err;
	unsigned int max, nbufs, next, blocknr;
	struct buffer_head *bh;
	
	struct buffer_head * bufs[MAXBUF];
	
	/* Do up to 128K of readahead */
	max = start + (128 * 1024 / journal->j_blocksize);
	if (max > journal->j_maxlen)
		max = journal->j_maxlen;

	/* Do the readahead itself.  We'll submit MAXBUF buffer_heads at
	 * a time to the block device IO layer. */
	
	nbufs = 0;
	
	for (next = start; next < max; next++) {
		blocknr = next;
		if (journal->j_inode)
			blocknr = bmap(journal->j_inode, next);
		if (!blocknr) {
			printk (KERN_ERR "JFS: bad block at offset %u\n",
				next);
			err = -EIO;
			goto failed;
		}
		
		bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
		if (!bh) {
			err = -ENOMEM;
			goto failed;
		}

		if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
			bufs[nbufs++] = bh;
			if (nbufs == MAXBUF) {
				ll_rw_block(READ, nbufs, bufs);
				brelse_array(bufs, nbufs);
				nbufs = 0;
			}
		} else
			brelse(bh);
	}

	if (nbufs)
		ll_rw_block(READ, nbufs, bufs);
	err = 0;
	
failed:	
	if (nbufs) 
		brelse_array(bufs, nbufs);
	return err;
}
Example #14
0
File: fs.c Project: aaronb/CS637
//return age of buffer containing data, or 0 if no buffer
int
agei(struct inode *ip, uint off)
{
  if (ip->type == T_DEV)
     return 0;

  if(off > ip->size)
    return 0;

   return bage(ip->dev, bmap(ip, off/BSIZE, 0));
}
Example #15
0
File: fs.c Project: squallee/CS537
// Write data to inode.
int
writei(struct inode *ip, char *src, uint off, uint n)
{
  uint tot, m;
  struct buf *bp;
  char *addr;

  if(ip->type == T_DEV){
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
      return -1;
    return devsw[ip->major].write(ip, src, n);
  }

  if(off > ip->size || off + n < off)
    return -1;

  if(ip->type == T_SMALLFILE){ // handle T_SMALLFILE
    // cprintf("before n in readi : %d\t off = %d\t size = %d\n", n, off, ip->size);
    if(off + n > 52)
      n = 52 - off;    
    addr = (char*)(ip->addrs); // get NDIRECT address
    memmove(addr + off, src, n);
    off += n;
    ip->size = off;
    iupdate(ip);    
    return n;
    // cprintf("after n in readi : %d\t off = %d\t size = %d\n", n, off, ip->size);
    // cprintf("write addr: %s\n", *(addr + off));

  } else { // handle T_FILE
    if(off + n > MAXFILE*BSIZE)
      n = MAXFILE*BSIZE - off;    
    for(tot=0; tot<n; tot+=m, off+=m, src+=m){
      uint sector_number = bmap(ip, off/BSIZE);
      if(sector_number == 0){ //failed to find block
        n = tot; //return number of bytes written so far
        break;
      }
      
      bp = bread(ip->dev, sector_number);
      m = min(n - tot, BSIZE - off%BSIZE);
      memmove(bp->data + off%BSIZE, src, m);
      bwrite(bp);
      brelse(bp);
    }
  }
  if(n > 0 && off > ip->size){
    ip->size = off;
    iupdate(ip);
    // cprintf("last n in readi : %d\t off = %d\t size = %d\n", n, off, ip->size);
  }
  return n;
}
Example #16
0
void
getblk(Ram *r, long bno, char *buf)
{
	long dbno;

	if ((dbno = bmap(r, bno)) == 0) {
		memset(buf, 0, BLSIZE);
		return;
	}
	seek(tapefile, dbno*BLSIZE, 0);
	if (read(tapefile, buf, BLSIZE) != BLSIZE)
		error("bad read");
}
Example #17
0
void pass3(struct dinode *ip)
{
	struct direct dbuf[NDIR];
	long doff;
	struct direct *dp;
	register i, j;
	int k;
	daddr_t d;
	ino_t kno;

	if((ip->di_mode&IFMT) != IFDIR)
		return;
	l4tol(iaddr, ip->di_addr, NADDR);
	doff = 0;
	for(i=0;; i++) {
		if(doff >= ip->di_size)
			break;
		d = bmap(i);
		if(d == 0)
			break;
		bread(d, (char *)dbuf, sizeof(dbuf));
		for(j=0; j<NDIR; j++) {
			if(doff >= ip->di_size)
				break;
			doff += sizeof(struct direct);
			dp = dbuf+j;
			kno = dp->d_ino;
			if(kno == 0)
				continue;
			if(aflg==0 && dotname(dp))
				continue;
			if(ilist[0] == 0)
				goto pr;
			for(k=0; ilist[k] != 0; k++)
				if(ilist[k] == kno)
					goto pr;
			continue;
		pr:
			printf("%u	", kno);
			pname(ino, 0);
			printf("/%.14s", dp->d_name);
			if (lookup(kno, 0))
				printf("/.");
			printf("\n");
		}
	}
}
Example #18
0
static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page)
{
	unsigned long offset;
	int zones[PAGE_SIZE/512];
	int zones_used;
	kdev_t dev = 0;
	int block_size;
	struct inode *swapf = 0;

	if (rw == READ) {
		ClearPageUptodate(page);
		kstat.pswpin++;
	} else
		kstat.pswpout++;

	get_swaphandle_info(entry, &offset, &dev, &swapf);
	if (dev) {
		zones[0] = offset;
		zones_used = 1;
		block_size = PAGE_SIZE;
	} else if (swapf) {
		int i, j;
		unsigned int block = offset
			<< (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);

		block_size = swapf->i_sb->s_blocksize;
		for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size)
			if (!(zones[i] = bmap(swapf,block++))) {
				printk("rw_swap_page: bad swap file\n");
				return 0;
			}
		zones_used = i;
		dev = swapf->i_dev;
	} else {
		return 0;
	}

 	/* block_size == PAGE_SIZE/zones_used */
 	brw_page(rw, page, dev, zones, block_size);

 	/* Note! For consistency we do all of the logic,
 	 * decrementing the page count, and unlocking the page in the
 	 * swap lock map - in the IO completion handler.
 	 */
	return 1;
}
Example #19
0
//// 文件读函数 - 根据i节点和文件结构,读取文件中数据。
// 由i节点我们可以知道设备号,由filp结构可以知道文件中当前读写指针位置。buf指定
// 用户空间中缓冲区位置,count是需要读取字节数。返回值是实际读取的字节数,或出错号(小于0).
int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
{
	int left,chars,nr;
	struct buffer_head * bh;

    // 首先判断参数的有效性。若需要读取的字节数count小于等于0,则返回0.若还需要读
    // 取的字节数不等于0,就循环执行下面操作,直到数据全部读出或遇到问题。在读循环
    // 操作过程中,我们根据i节点和文件表结构信息,并利用bmap()得到包含文件当前读写
    // 位置的数据块在设备上对应的逻辑块号nr。若nr不为0,则从i节点指定的设备上读取该
    // 逻辑块。如果读操作是吧则退出循环。若nr为0,表示指定的数据块不存在,置缓冲块
    // 指针为NULL。(filp->f_pos)/BLOCK_SIZE用于计算出文件当前指针所在的数据块号。
	if ((left=count)<=0)
		return 0;
	while (left) {
		if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) {
			if (!(bh=bread(inode->i_dev,nr)))
				break;
		} else
			bh = NULL;
        // 接着我们计算文件读写指针在数据块中的偏移值nr,则在该数据块中我们希望读取的
        // 字节数为(BLOCK_SIZE-nr)。然后和现在还需读取的字节数left做比较。其中小值
        // 即为本次操作需读取的字节数chars。如果(BLOCK_SIZE-nr) > left,则说明该块
        // 是需要读取的最后一块数据。反之还需要读取下一块数据。之后调整读写文件指针。
        // 指针前移此次将读取的字节数chars,剩余字节计数left相应减去chars。
		nr = filp->f_pos % BLOCK_SIZE;
		chars = MIN( BLOCK_SIZE-nr , left );
		filp->f_pos += chars;
		left -= chars;
        // 若上面从设备上读到了数据,则将p指向缓冲块中开始读取数据的位置,并且复制chars
        // 字节到用户缓冲区buf中。否则往用户缓冲区中填入chars个0值字节。
		if (bh) {
			char * p = nr + bh->b_data;
			while (chars-->0)
				put_fs_byte(*(p++),buf++);
			brelse(bh);
		} else {
			while (chars-->0)
				put_fs_byte(0,buf++);
		}
	}
    // 修改该i节点的访问时间为当前时间。返回读取的字节数,若读取字节数为0,则返回
    // 出错号。CURRENT_TIME是定义在include/linux/sched.h中的宏,用于计算UNIX时间。
    // 即从1970年1月1日0时0分0秒开始,到当前的时间,单位是秒。
	inode->i_atime = CURRENT_TIME;
	return (count-left)?(count-left):-ERROR;
}
Example #20
0
void pass1(struct dinode *ip)
{
	struct direct dbuf[NDIR];
	long doff;
	struct direct *dp;
	register i, j;
	int k;
	daddr_t d;
	ino_t kno;

	if((ip->di_mode&IFMT) != IFDIR)
		return;
	l4tol(iaddr, ip->di_addr, NADDR);
	doff = 0;
	for(i=0;; i++) {
		if(doff >= ip->di_size)
			break;
		d = bmap(i);
		if(d == 0)
			break;
		bread(d, (char *)dbuf, BSIZE);
		for(j=0; j<NDIR; j++) {
			if(doff >= ip->di_size)
				break;
			doff += sizeof(struct direct);
			dp = &dbuf[j];
			kno = dp->d_ino;
			if(kno == 0)
				continue;
			if(kno >= nfiles || kno < 0) {
				printf("%5u bad; %u/%.14s\n", kno, ino, dp->d_name);
				nerror++;
				continue;
			}
			for (k=0; ilist[k] != 0; k++)
				if (ilist[k]==kno) {
					printf("%5u arg; %u/%.14s\n", kno, ino, dp->d_name);
					nerror++;
				}
			ecount[kno]++;
			if (ecount[kno] == 0)
				ecount[kno] = (char) 0377;
		}
	}
}
Example #21
0
/*
* Used in mpage_readpages() fs/mpage.c
* Keeps a connection between block and its page
*/
void dedup_update_block_page(struct page *page)
{
	struct address_space *mapping = page->mapping;
	struct inode *inode = (mapping) ? page->mapping->host : NULL;

	if (inode != NULL) {
		// get the block number
		sector_t page_block = bmap(inode, page->index);

		// Check if the block is inside dedup range
		if (dedup_is_in_range(page_block)) {
			// Update block's page reference
			blocksArray.pages[page_block - start_block] = page;
		}
	}
	else
		printk("inode is NULL :(\n");
}
Example #22
0
main(int argc, char *argv[])
{ 
  int fd;

  if (argc > 1)
     device = argv[1];

  fd = open(device, O_RDONLY);
  if (fd < 0){
     printf("open %s failed\n", device);
     exit(1);
  }
  super(fd);
  gd(fd);
  bmap(fd);
  imap(fd);
  inode(fd);
  dir(fd);
}
Example #23
0
static int jread(struct buffer_head **bhp, journal_t *journal, 
		 unsigned int offset)
{
	unsigned int blocknr;
	struct buffer_head *bh;

	*bhp = NULL;

	J_ASSERT (offset < journal->j_maxlen);
			
	blocknr = offset;
	if (journal->j_inode)
		blocknr = bmap(journal->j_inode, offset);
	
	if (!blocknr) {
		printk (KERN_ERR "JFS: bad block at offset %u\n",
			offset);
		return -EIO;
	}
	
	bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
	if (!bh)
		return -ENOMEM;
	
	if (!buffer_uptodate(bh)) {
		/* If this is a brand new buffer, start readahead.
                   Otherwise, we assume we are already reading it.  */
		if (!buffer_req(bh))
			do_readahead(journal, offset);
		wait_on_buffer(bh);
	}
	
	if (!buffer_uptodate(bh)) {
		printk (KERN_ERR "JFS: Failed to read block at offset %u\n",
			offset);
		brelse(bh);
		return -EIO;
	}
		
	*bhp = bh;
	return 0;
}
Example #24
0
sector_t wrapfs_bmap(struct address_space *mapping, sector_t block)
{
	int err = -EINVAL;
	struct inode *inode, *lower_inode;
	sector_t (*bmap)(struct address_space *, sector_t);

	wrapfs_debug("");
	inode = (struct inode *)mapping->host;
	wrapfs_debug_aops(WRAPFS_SB(inode->i_sb)->wrapfs_debug_a_ops, "");
	lower_inode = wrapfs_lower_inode(inode);
	if (!lower_inode)
		goto out;
	bmap = lower_inode->i_mapping->a_ops->bmap;
	if (bmap)
		err = bmap(lower_inode->i_mapping, block);
out:
	wrapfs_debug_aops(WRAPFS_SB(inode->i_sb)->wrapfs_debug_a_ops,
				"err : %d", err);
	return err;
}
Example #25
0
void
getblk(Ram *r, long bno, char *buf)
{
	long dbno;

	if ((dbno = bmap(r, bno)) == 0) {
		memset(buf, 0, BLSIZE);
		return;
	}
	if ((vlong)(dbno+1)*BLSIZE > tapelen) {
		fprint(2, "read past end of tape: %lld\n", (vlong)dbno*BLSIZE);
		memset(buf, 0, BLSIZE);
		return;
	}
	seek(tapefile, dbno*BLSIZE, 0);
	if (readn(tapefile, buf, BLSIZE) != BLSIZE){
		fprint(2, "readn at %lld: %r\n", (vlong)dbno*BLSIZE);
		error("bad read");
	}
}
Example #26
0
void pass2(struct dinode *ip)
{
	struct direct dbuf[NDIR];
	long doff;
	struct direct *dp;
	register i, j;
	int k;
	struct htab *hp;
	daddr_t d;
	ino_t kno;

	if((ip->di_mode&IFMT) != IFDIR)
		return;
	l4tol(iaddr, ip->di_addr, NADDR);
	doff = 0;
	for(i=0;; i++) {
		if(doff >= ip->di_size)
			break;
		d = bmap(i);
		if(d == 0)
			break;
		bread(d, (char *)dbuf, sizeof(dbuf));
		for(j=0; j<NDIR; j++) {
			if(doff >= ip->di_size)
				break;
			doff += sizeof(struct direct);
			dp = dbuf+j;
			kno = dp->d_ino;
			if(kno == 0)
				continue;
			hp = lookup(kno, 0);
			if(hp == 0)
				continue;
			if(dotname(dp))
				continue;
			hp->h_pino = ino;
			for(k=0; k<DIRSIZ; k++)
				hp->h_name[k] = dp->d_name[k];
		}
	}
}
Example #27
0
/* read data from inode */
int iread(struct inode *ip, char *dest, uint32_t off, uint32_t n) {
    uint32_t tot, m;
    struct buf *bp;

    /* is a char device? */
    if (S_ISCHR(ip->mode)) {
        return dtable[ip->zone[0]].read(ip, dest, n);
    }

    /* 偏移过大 || 溢出*/
    if (off > ip->size || off + n < off) {
        panic("iread: incorrect offet");
        return -1;
    }

    if (off + n > ip->size) {
        n = ip->size - off;
    }

    /*  tot: 已读取的字节数
     *  n: 要读取的字节数
     *  off: 当前文件指针偏移
     *  m: 当次循环要读取的字节数
     */
    for (tot = 0; tot < n; tot += m, off += m, dest += m) {
        bp = bread(ip->dev, bmap(ip, off/BSIZE));
        /* 每个循环读取的数据可分两种情况:
         * - 从当前文件偏移读到该扇区结束
         * - 从当前文件偏移读到 *满足要读取的字节数*
         * 每次选择较小的那个
         */
        m = min(n - tot, BSIZE - off%BSIZE);
        /* 从当前偏移相对于该扇区的偏移处起开始读取
         * (在中间的循环这个值常常是0) 
         */
        memcpy(dest, bp->data + off%BSIZE, m);
        brelse(bp);
    }

    return n;
}
Example #28
0
void rw_swap_page(int rw, unsigned int nr, char * buf)
{
	unsigned int zones[4];
	int i;

	if (swap_device) {
		ll_rw_page(rw,swap_device,nr,buf);
		return;
	}
	if (swap_file) {
		nr <<= 2;
		for (i = 0; i < 4; i++)
			if (!(zones[i] = bmap(swap_file,nr++))) {
				printk("rw_swap_page: bad swap file\n");
				return;
			}
		ll_rw_swap_file(rw,swap_file->i_dev, zones,4,buf);
		return;
	}
	printk("ll_swap_page: no swap file or device\n");
}
Example #29
0
/*
 * Conversion of logical to physical block numbers for the journal
 *
 * On external journals the journal blocks are identity-mapped, so
 * this is a no-op.  If needed, we can use j_blk_offset - everything is
 * ready.
 */
int journal_bmap(journal_t *journal, unsigned long blocknr,
                 unsigned long *retp)
{
    int err = 0;
    unsigned long ret;

    if (journal->j_inode) {
        ret = (unsigned long)bmap(journal->j_inode, (sector_t)blocknr);
        if (ret)
            *retp = ret;
        else {
            printk(KERN_ALERT "%s: journal block not found "
                   "at offset %lu ...\n",
                   __FUNCTION__,
                   blocknr);
            err = -EIO;
            __journal_abort_soft(journal, err);
        }
    } else {
        *retp = blocknr; /* +journal->j_blk_offset */
    }
    return err;
}
Example #30
0
inoptr srch_dir(inoptr wd, char *compname)
{
    int curentry;
    blkno_t curblock;
    struct direct *buf;
    int nblocks;
    uint16_t inum;

    nblocks = (wd->c_node.i_size + BLKMASK) >> BLKSHIFT;

    for(curblock=0; curblock < nblocks; ++curblock) {
        buf = (struct direct *)bread(wd->c_dev, bmap(wd, curblock, 1), 0);
        for(curentry = 0; curentry < (512/DIR_LEN); ++curentry) {
            if(namecomp(compname, buf[curentry].d_name)) {
                inum = buf[curentry & 0x1f].d_ino;
                brelse(buf);
                return i_open(wd->c_dev, inum);
            }
        }
        brelse(buf);
    }
    return NULLINODE;
}