Example #1
0
File: proc.c Project: yonatana/OS
int
kernel_unlink(char* path)
{
  struct inode *ip, *dp;
  struct dirent de;
  char name[DIRSIZ];
  uint off;

//   if(argstr(0, &path) < 0)
//     return -1;
  if((dp = nameiparent(path, name)) == 0)
    return -1;

  begin_trans();

  ilock(dp);

  // Cannot unlink "." or "..".
  if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0)
    goto bad;

  if((ip = dirlookup(dp, name, &off)) == 0)
    goto bad;
  ilock(ip);

  if(ip->nlink < 1)
    panic("unlink: nlink < 1");
  /*
  if(ip->type == T_DIR && !isdirempty(ip)){
    iunlockput(ip);
    goto bad;
  }
*/
  memset(&de, 0, sizeof(de));
  if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
    panic("unlink: writei");
  if(ip->type == T_DIR){
    dp->nlink--;
    iupdate(dp);
  }
  iunlockput(dp);

  ip->nlink--;
  iupdate(ip);
  iunlockput(ip);

  commit_trans();

  return 0;

bad:
  iunlockput(dp);
  commit_trans();
  return -1;
}
Example #2
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 #3
0
// Truncate inode (discard contents).
// Only called when the inode has no links
// to it (no directory entries referring to it)
// and has no in-memory reference to it (is
// not an open file or current directory).
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp;
  uint *a;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }
  
  if(ip->addrs[NDIRECT]){
    bp = bread(ip->dev, ip->addrs[NDIRECT]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j])
        bfree(ip->dev, a[j]);
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT]);
    ip->addrs[NDIRECT] = 0;
  }

  ip->size = 0;
  iupdate(ip);
}
Example #4
0
/* 
 * release an inode.
 * decrease the reference count, write updates to disk if nessary.
 * also check the link count, if zero, trucate it.
 * */
void iput(struct inode *ip){
    ushort dev;

    if(ip==NULL)
        panic("bad struct inode*");
    ip->i_flag |= I_LOCK;
    if (ip->i_count > 0) {
        ip->i_count--;
    }
    if (ip->i_count==0){
        if (ip->i_nlink==0) {
            itrunc(ip);
            ifree(ip->i_dev, ip->i_num);
        }
        // if it's a device file, the dev number is stored in zone[0].
        dev = ip->i_zone[0];
        switch (ip->i_mode & S_IFMT) {
            case S_IFBLK:
                (*bdevsw[MAJOR(dev)].d_close)(dev);
                break;
            case S_IFCHR:
                (*cdevsw[MAJOR(dev)].d_close)(dev);
                break;
        }
        iupdate(ip);
        ip->i_flag = 0;
        ip->i_num = 0;
    }
    unlk_ino(ip);
}
Example #5
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 #6
0
File: fs.c Project: squallee/CS537
// Truncate inode (discard contents).
// Only called after the last dirent referring
// to this inode has been erased on disk.
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp;
  uint *a;
  
  if(ip->type != T_SMALLFILE) { // for all not small file, clear the blocks
    for(i = 0; i < NDIRECT; i++){
      if(ip->addrs[i]){
        bfree(ip->dev, ip->addrs[i]);
        ip->addrs[i] = 0;
      }
    }    
    if(ip->addrs[NDIRECT]){
      bp = bread(ip->dev, ip->addrs[NDIRECT]);
      a = (uint*)bp->data;
      for(j = 0; j < NINDIRECT; j++){
        if(a[j])
          bfree(ip->dev, a[j]);
      }
      brelse(bp);
      bfree(ip->dev, ip->addrs[NDIRECT]);
      ip->addrs[NDIRECT] = 0;
    }
  }

  ip->size = 0;
  iupdate(ip);
}
Example #7
0
/* truncate inode 
 * only called when the inode has no links to it 
 * and not any in-memory ref to it
 */
static void itrunc(struct inode *ip) {
    uint32_t i, j;
    struct buf *bp;
    uint16_t *zone2;
    
    /* free DIRECT block */
    for (i = 0; i < NDIRECT; i++) {
        if (ip->zone[i]) {
            bfree(ip->dev, ip->zone[i]);
            ip->zone[i] = 0;
        }
    }

    /* free INDIRECT block */
    if (ip->zone[NDIRECT]) {
        bp = bread(ip->dev,ip->zone[NDIRECT]);
        zone2 = (uint16_t *)bp->data;
        for (j = 0; j < NINDIRECT; j++) {
            if (zone2[j]) {
                bfree(ip->dev, zone2[j]);
                zone2[j] = 0;
            }
        }
        brelse(bp);
        bfree(ip->dev, ip->zone[NDIRECT]);
        ip->zone[NDIRECT] = 0;
    }

    /* DAUL INDIRECT block is unused*/

    ip->size = 0;
    iupdate(ip);
}
Example #8
0
// 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 0;
    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 #9
0
// Truncate inode (discard contents).
// Only called when the inode has no links
// to it (no directory entries referring to it)
// and has no in-memory reference to it (is
// not an open file or current directory).
static void itrunc(struct inode* ip)
{
    //     cprintf("itrunc \n");

    int i, j;
    struct buf* bp;
    uint* a;
    struct superblock sb;
    sb = sbs[ip->part->number];
    for (i = 0; i < NDIRECT; i++) {
        if (ip->addrs[i]) {
            bfree(ip->dev, ip->addrs[i], ip->part->number);
            ip->addrs[i] = 0;
        }
    }

    if (ip->addrs[NDIRECT]) {
        bp = bread(ip->dev, sb.offset + ip->addrs[NDIRECT]);
        a = (uint*)bp->data;
        for (j = 0; j < NINDIRECT; j++) {
            if (a[j])
                bfree(ip->dev, a[j], ip->part->number);
        }
        brelse(bp);
        bfree(ip->dev, ip->addrs[NDIRECT], ip->part->number);
        ip->addrs[NDIRECT] = 0;
    }

    ip->size = 0;
    iupdate(ip);
}
Example #10
0
File: fs.c Project: SilunWang/xv6
// Truncate inode (discard contents).
// Only called when the inode has no links
// to it (no directory entries referring to it)
// and has no in-memory reference to it (is
// not an open file or current directory).
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp;
  uint *a;
  uint* addr_ptr, *temp;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }
  addr_ptr = &(ip->addrs[NDIRECT]);
  while(*addr_ptr)
  {
    bp = bread(ip->dev, *addr_ptr);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT - 1; j++){
      if(a[j])
        bfree(ip->dev, a[j]);
    }
    temp = &(a[NINDIRECT - 1]);
    brelse(bp);
    bfree(ip->dev, *addr_ptr);
    *addr_ptr = 0;
    addr_ptr = temp;
  }

  ip->size = 0;
  iupdate(ip);
}
Example #11
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 #12
0
// PAGEBREAK!
// Write data to inode.
int
writei(struct inode *ip, char *src, uint off, uint n)
{
  uint tot, m;
  struct buf *bp;
//cprintf("inside writei: type=%x major=%x, func addr: %x\n", ip->type, ip->major, devsw[ip->major].write);
  if(ip->type == T_DEV){
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
      return -1;
//cprintf("before calling consolewrite: major=%x, func addr: %x\n", ip->major, devsw[ip->major].write);
    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 #13
0
/*
 *  get an inode into the cache.  if no inode exists for this qid, create one
 *  from an unused qid/inode map.
 */
Ibuf *
iget(Icache *ic, Qid qid)
{
	Imap *m, *me;
	Ibuf *b;

	/*
	 *  find map entry with same qid.path
	 */
	for(m = ic->map, me = &ic->map[ic->nino]; m < me; m++)
		if(m->inuse && m->qid.path==qid.path){
			if(m->qid.vers != qid.vers){
				/*
				 *  our info is old, forget it
				 */
				DPRINT(2, "updating old file %llu.%lu\n",
					qid.path, qid.vers);
				m->qid = qid;
				iupdate(ic, m - ic->map, qid);
			}
			break;
		}

	/*
 	 *  if an already existing inode, just get it
	 */
	if(m != me)
		return iread(ic, m - ic->map);

	/*
	 *  create a new inode, throw out the least recently used inode
	 *  if necessary
	 */
	m = (Imap*)ic->mlru.lnext;
	if(m->inuse){
		DPRINT(2, "superceding file %llu.%ld by %llu.%ld\n",
			m->qid.path, m->qid.vers, qid.path, qid.vers);
		if(iremove(ic, m - ic->map) < 0)
			return 0;
	}

	if(statson)
		cfsstat.ninsert++;
	/*
	 *  init inode and write to disk
	 */
	DPRINT(2, "new file %llu.%ld ino %ld\n",
		qid.path, qid.vers, m - ic->map);
	b = ialloc(ic, m - ic->map);
	b->inode.inuse = m->inuse = 1;
	b->inode.qid = qid;
	b->inode.length = 0x7fffffffffffffffLL;
	m->qid = qid;
	b->inode.ptr.bno = Notabno;
	iwrite(ic, b);
	return b;
}
Example #14
0
File: bmap.c Project: gyao/fleurix
/*
 * Discard inode's content.
 * Called from routines like open(), iput(). 
 * */
int itrunc(struct inode *ip){
    int i,j; 
    ushort dev;
    struct buf *bp, *bp2;
    char *zmap, *zmap2;

    // only regular file but not directory can be truncated
    if (!(ip->i_mode & S_IFREG) || (ip->i_mode & S_IFDIR)) {
        return -1;
    }
    
    dev = ip->i_dev;
    for (i=0; i<7; i++){
        if (ip->i_zone[i]!=0){
            bfree(dev, ip->i_zone[i]);
            ip->i_flag |= I_DIRTY;
            ip->i_zone[i] = 0;
        }
    }
    /* -------------------------- */
    if (ip->i_zone[7] != 0){
        bp = bread(dev, ip->i_zone[7]);
        zmap = bp->b_data;
        for (i=0; i<NINDBLK; i++){
            if(zmap[i] != 0){
                bfree(dev, zmap[i]);
            }
        }
        bfree(dev, ip->i_zone[7]);
        ip->i_zone[7] = 0;
        brelse(bp);
    }
    /* -------------------------- */
    if (ip->i_zone[8] != 0){
        bp = bread(dev, ip->i_zone[8]);
        zmap = bp->b_data;
        for (i=0; i<NINDBLK; i++) {
            if (zmap[i] != 0){
                bp2 = bread(dev, zmap[i]);
                zmap2 = bp2->b_data;
                for (j=0; j<NINDBLK; j++) {
                    if (zmap2[j] != 0){
                        bfree(dev, zmap2[j]);
                    }
                }
                brelse(bp2);
                bfree(dev, zmap[i]);
            }
        }
        brelse(bp);
        bfree(dev, ip->i_zone[8]);
        ip->i_zone[8] = 0;
    }
    ip->i_size = 0;
    iupdate(ip);
    return 0;
}
Example #15
0
File: proc.c Project: yonatana/OS
struct inode*
kernel_create(char *path, short type, short major, short minor)
{
  uint off;
  struct inode *ip, *dp;
  char name[DIRSIZ];
   //cprintf("nameiparent path: %s\n",path);
  if((dp = nameiparent(path, name)) == 0)
    return 0;
  
  ilock(dp);
  
  if((ip = dirlookup(dp, name, &off)) != 0){
    iunlockput(dp);
    ilock(ip);
    if(type == T_FILE && ip->type == T_FILE)
      return ip;
    iunlockput(ip);
    return 0;
  }
  
  if((ip = ialloc(dp->dev, type)) == 0)
    panic("create: ialloc");

  ilock(ip);
  ip->major = major;
  ip->minor = minor;
  ip->nlink = 1;
  iupdate(ip);
  if(type == T_DIR){  // Create . and .. entries.
    dp->nlink++;  // for ".."
    iupdate(dp);
    // No ip->nlink++ for ".": avoid cyclic ref count.
    if(dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0)
      panic("create dots");
  }

  if(dirlink(dp, name, ip->inum) < 0)
    panic("create: dirlink");

  iunlockput(dp);
  return ip;
}
Example #16
0
// Truncate inode (discard contents).
// Only called when the inode has no links
// to it (no directory entries referring to it)
// and has no in-memory reference to it (is
// not an open file or current directory).
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp;
  struct buf *bp2;
  uint *a;
  uint *b;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }
  
  if(ip->addrs[NDIRECT]){
    bp = bread(ip->dev, ip->addrs[NDIRECT]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j])
        bfree(ip->dev, a[j]);
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT]);
    ip->addrs[NDIRECT] = 0;
  }

  // part 1 delete files
  if(ip->addrs[NDIRECT+1]) {
    bp = bread(ip->dev, ip->addrs[NDIRECT+1]);
    a = (uint*)bp->data;
    for(i = 0; i < NINDIRECT; i++){
        if(a[i]) {
            bp2 = bread(ip->dev, a[i]);
            b = (uint*)bp2->data;
            for(j = 0; j < NINDIRECT; j++) {
                if(b[j])
                    bfree(ip->dev, b[j]);
            }
            brelse(bp2);
            bfree(ip->dev, a[i]);
            a[i] = 0;
        }
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT+1]);
    ip->addrs[NDIRECT+1] = 0;
  }

  ip->size = 0;
  iupdate(ip);
}
Example #17
0
File: fs.c Project: bitc/3
// Truncate inode (discard contents).
// Only called when the inode has no links
// to it (no directory entries referring to it)
// and has no in-memory reference to it (is
// not an open file or current directory).
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp, *bp2;
  uint *a, *a2;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }
  
  if(ip->addrs[NDIRECT]){
    bp = bread(ip->dev, ip->addrs[NDIRECT]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j])
        bfree(ip->dev, a[j]);
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT]);
    ip->addrs[NDIRECT] = 0;
  }

/*vvv  TASK 1.1  vvv*/
  if(ip->indirect2){
    bp = bread(ip->dev, ip->indirect2);
    a = (uint*)bp->data;
    for(i = 0; i < NINDIRECT; i++){
      if(a[i]){
        bp2 = bread(ip->dev, a[i]);
        a2 = (uint*)bp2->data;
        for(j = 0; j < NINDIRECT; j++){
          if(a2[j])
            bfree(ip->dev, a2[j]);
        }
        brelse(bp2);
        bfree(ip->dev, a[i]);
      }
    }
    brelse(bp);
    bfree(ip->dev, ip->indirect2);
    ip->indirect2 = 0;
  }
/*^^^^^^^^^^^^^^^^^^*/

  ip->size = 0;
  iupdate(ip);
}
Example #18
0
/*
 * open a file. flag indicated opened type like O_RDONLY, O_TRUNC, O_CREAT and blah. And 
 * mode only used in the O_CREAT scenary, indicated the file (inode) type.
 *
 * each proc has got one user file table(p_ofile[NOFILE]), it's each entry is also a number,
 * indicated the number in the system file table(file[NFILE]). when user opened a file, it 
 * first allocate a user file table entry(aka. file descriptor), then attach it with a system
 * file table entry. It's reference count is increased in fork() or dup().
 * */
int do_open(char *path, uint flag, uint mode){
    struct inode *ip;
    struct file *fp;
    ushort dev;
    int fd;

    // on create a new file.
    if (flag & O_CREAT){
        ip = namei(path, 1);
        // if file is not existing yet.
        if (ip->i_nlink==0) {
            ip->i_mode = mode;
            ip->i_uid = cu->p_euid;
            ip->i_gid = cu->p_egid;
            ip->i_mtime = time();
            ip->i_nlink = 1;
            iupdate(ip);
        }
    }
    // an existing file.
    else {
        ip = namei(path, 0);
        if (ip == NULL){
            syserr(ENFILE);
            return -1;
        }
        // TODO: check access 
        // if it's a device file, the dev number is stored in zone[0].
        dev = ip->i_zone[0];
        switch(ip->i_mode & S_IFMT) {
            case S_IFBLK:
                (*bdevsw[MAJOR(dev)].d_open)(dev);
                break;
            case S_IFCHR:
                (*cdevsw[MAJOR(dev)].d_open)(dev);
                break;
        }
    } 
    if (((fd=ufalloc())<0) || (fp=falloc(fd))==NULL) {
        iput(ip);
        return -1;
    }
    if (flag & O_TRUNC){
        itrunc(ip);
    }
    unlk_ino(ip);
    fp->f_oflag = flag;
    fp->f_ino = ip;
    cu->p_fdflag[fd] = FD_CLOEXEC;
    return fd;
}
Example #19
0
// Truncate inode (discard contents).
static void
itrunc(struct inode *ip)
{
  int i, j, k;
  struct buf *bp, *bp2;
  uint *a;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }
  
  if(ip->addrs[INDIRECT]){
    bp = bread(ip->dev, ip->addrs[INDIRECT]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j])
        bfree(ip->dev, a[j]);
    }
    brelse(bp);
    ip->addrs[INDIRECT] = 0;
  }

  //free double indirect blocks -- NEW CODE
  if(ip->addrs[DINDIRECT]){
	  bp = bread(ip->dev, ip->addrs[DINDIRECT]);
	      a = (uint*)bp->data;
	      for(j = 0; j < NINDIRECT; j++){
	        if(a[j]){
	          bp2 = bread(ip->dev, a[j]);
	          uint* b = (uint*)bp2->data;
	          for(k = 0; k < NINDIRECT; k++){
	        	  if(b[k]){
	        		  bfree(ip->dev, b[k]);
	        	  }

	          }
	          bfree(ip->dev, a[j]);
	        }
	      }
	      brelse(bp);
	      ip->addrs[DINDIRECT] = 0;
  }

  ip->size = 0;
  iupdate(ip);
}
Example #20
0
/*
 * Drop a reference to an in-memory inode. If that was the last reference, the
 * inode cache entry can be recycled.
 *
 * If that was the last reference and the inode has no links to it, free the
 * inode (and its content) on disk.
 */
void iput(struct inode *ip)
{
	acquire(&icache.lock);
	if (ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0) {
		/* inode has no links: truncate and free inode. */
		if (ip->flags & I_BUSY)
			panic("iput busy");
		ip->flags |= I_BUSY;
		release(&icache.lock);
		itrunc(ip);
		ip->type = 0;
		iupdate(ip);
		acquire(&icache.lock);
		ip->flags = 0;
		wakeup(ip);
	}
	ip->ref--;
	release(&icache.lock);
}
Example #21
0
// Drop a reference to an in-memory inode.
// If that was the last reference, the inode cache entry can
// be recycled.
// If that was the last reference and the inode has no links
// to it, free the inode (and its content) on disk.
// All calls to iput() must be inside a transaction in
// case it has to free the inode.
void iput(struct inode* ip)
{
    // cprintf("iput  %d \n",ip->inum);

    acquire(&icache.lock);
    if (ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0) {
        // inode has no links and no other references: truncate and free.
        if (ip->flags & I_BUSY)
            panic("iput busy");
        ip->flags |= I_BUSY;
        release(&icache.lock);
        itrunc(ip);
        ip->type = 0;
        iupdate(ip);
        acquire(&icache.lock);
        ip->flags = 0;
        wakeup(ip);
    }
    ip->ref--;
    release(&icache.lock);
}
// Truncate inode (discard contents).
// Only called after the last dirent referring
// to this inode has been erased on disk.
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp;
  uint *a;
  uint new_addr;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
    	new_addr=ip->addrs[i];
    	if(ip->type == T_CHECKED){
    	    		new_addr = ip->addrs[i] & 0x00ffffff;
    	    	}
      bfree(ip->dev, new_addr);
      ip->addrs[i] = 0;
    }
  }
  
  if(ip->addrs[NDIRECT]){
    bp = bread(ip->dev, ip->addrs[NDIRECT]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j]){
    	  new_addr = a[j];
    	      	if(ip->type == T_CHECKED){
    	      		new_addr = a[j] & 0x00ffffff;
    	      	}
        bfree(ip->dev, a[j]);
      }
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT]);
    ip->addrs[NDIRECT] = 0;
  }

  ip->size = 0;
  iupdate(ip);
}
Example #23
0
/* write data to inode */
int iwrite(struct inode *ip, char *src, 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]].write(ip, src, n);
    }

    if (off > ip->size || off + n < off ) {
        panic("iwrite: incorrect offset or read length\n");
        return ERROR;
    }

    if (off + n > MAXFILE*BSIZE) {
        panic("iwrite: size out of range\n");
        return ERROR;
    }

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

    /* if alloc new block to ip, update it's size */
    // n > 0 ?
    if (n > 0 && off > ip->size) {
        ip->size = off;
        iupdate(ip);
    }
    
    return n;
}
// Write data to inode.
//TODO
int
writei(struct inode *ip, char *src, uint off, uint n)
{
  uint tot, m;
  struct buf *bp, *bp2, *bp3;
  uint offset;
  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->logical_size || off + n < off)
    return -1;
  if(off + n > MAXFILE*BSIZE)
    n = MAXFILE*BSIZE - off;
  if(ip->type == T_MIRRORED){
	for(tot=0; tot<n; tot+=m, off+=m, src+=m){
					
			offset = off/BSIZE*3;
			/*			
			if((offset == 0)|| (offset%3 == 0))
				offset
			*/ 	
			cprintf("write off/BSIZE is  %d\n", off/BSIZE);	
			cprintf("write mirror0 is %d\n", mbmap(ip, offset, 0));			
			cprintf("write mirror1 is %d\n", mbmap(ip, offset, 1));
			cprintf("write mirror2 is %d\n", mbmap(ip, offset, 2));
			bp = bread(ip->dev, mbmap(ip, offset, 0));
	    		m = min(n - tot, BSIZE - off%BSIZE);
	    		memmove(bp->data + off%BSIZE, src, m);
			cprintf("bp is %s\n", &bp->data);
	    		bwrite(bp);
	    		brelse(bp);
			
			bp2 = bread(ip->dev, mbmap(ip, offset, 1));
	    		m = min(n - tot, BSIZE - off%BSIZE);
	    		memmove(bp2->data + off%BSIZE, src, m);

			cprintf("bp2 is %s\n", &bp2->data);
	    		bwrite(bp2);
	    		brelse(bp2);

			
			bp3 = bread(ip->dev, mbmap(ip, offset, 2));
	    		m = min(n - tot, BSIZE - off%BSIZE);
	    		memmove(bp3->data + off%BSIZE, src, m);
			cprintf("bp3 is %s\n", &bp->data);
	    		bwrite(bp3);
	    		brelse(bp3);
			//cprintf("i'm here to write\n");
		
  	}


	}
else{	
  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);
    bwrite(bp);
    brelse(bp);
  }
}
iupdate(ip);

  if(n > 0 && off > ip->logical_size){
    ip->logical_size = off;
    iupdate(ip);
  }
  return n;
}
Example #25
0
void	bupdate(void) {
	static win_t	*lwin = NULL;
	int	waiting,
		widthx = secs_getvar_int("winlistchars"),
		M = widthx,
#ifdef ENABLE_FORCEASCII
		fascii = secs_getvar_int("forceascii"),
#endif
		bb, line = 0;
	conn_t	*conn = curconn;

	wbuddy_widthy = secs_getvar_int("winlistheight")*faimconf.wstatus.widthy/100;
	if (wbuddy_widthy > faimconf.wstatus.widthy)
		wbuddy_widthy = faimconf.wstatus.widthy;

#ifdef ENABLE_FORCEASCII
# define LINEDRAW(ch,as)	((fascii == 1) ? as : ch)
#else
# define LINEDRAW(ch,as)	ch
#endif
#define ACS_ULCORNER_C	LINEDRAW(ACS_ULCORNER,',')
#define ACS_LLCORNER_C	LINEDRAW(ACS_LLCORNER,'`')
#define ACS_URCORNER_C	LINEDRAW(ACS_URCORNER,'.')
#define ACS_LRCORNER_C	LINEDRAW(ACS_LRCORNER,'\'')
#define ACS_LTEE_C	LINEDRAW(ACS_LTEE,'+')
#define ACS_RTEE_C	LINEDRAW(ACS_RTEE,'+')
#define ACS_BTEE_C	LINEDRAW(ACS_BTEE,'+')
#define ACS_TTEE_C	LINEDRAW(ACS_TTEE,'+')
#define ACS_HLINE_C	LINEDRAW(ACS_HLINE,'-')
#define ACS_VLINE_C	LINEDRAW(ACS_VLINE,'|')
#define ACS_PLUS_C	LINEDRAW(ACS_PLUS,'+')
#define ACS_RARROW_C	LINEDRAW(ACS_RARROW,'>')

	nw_erase(&win_buddy);
	nw_vline(&win_buddy, ACS_VLINE_C | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS), wbuddy_widthy);
	bb = buddyc;
	buddyc = 0;

	if (conn == NULL)
		return;

	waiting = 0;

	if (inconn) {
		int	autoclose = getvar_int(curconn, "autoclose");

		assert(curconn->curbwin != NULL);
		if ((autoclose > 0) && (curconn->curbwin->et == BUDDY) && !USER_PERMANENT(curconn->curbwin->e.buddy) && (curconn->curbwin->waiting != 0))
			curconn->curbwin->closetime = now + 60*autoclose;
		curconn->curbwin->waiting = 0;
		if ((curconn->curbwin->et == CHAT) && curconn->curbwin->e.chat->isaddressed)
			curconn->curbwin->e.chat->isaddressed = 0;
	}

	do {
		buddywin_t	*bwin = conn->curbwin;
		char	*lastgroup = NULL;
		int	hidegroup = 0,
			autosort = getvar_int(conn, "autosort");

		assert(conn->winname != NULL);

		if (line < wbuddy_widthy) {
			nw_move(&win_buddy, line, 0);
			if (line == 0)
				nw_addch(&win_buddy, ACS_ULCORNER_C | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS));
			else
				nw_addch(&win_buddy, ACS_LTEE_C | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS));
			nw_hline(&win_buddy, ACS_HLINE_C | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS), widthx);

			nw_move(&win_buddy, line++, widthx-strlen(conn->winname));
			if (conn->online <= 0) {
				nw_printf(&win_buddy, C(WINLIST,BUDDY_OFFLINE), 1, " %s", conn->winname);
				if (line < wbuddy_widthy) {
					nw_move(&win_buddy, line++, 1);
					nw_printf(&win_buddy, C(WINLIST,TEXT), 1, "%s", " You are offline");
					buddyc++;
				}
			} else
				nw_printf(&win_buddy, C(WINLIST,TEXT), 1, " %s", conn->winname);
		}

		buddyc++;

		if (bwin == NULL)
			continue;
		if (autosort == 2) {
			if (bwin->et == BUDDY)
				STRREPLACE(lastgroup, USER_GROUP(bwin->e.buddy));
			else
				STRREPLACE(lastgroup, CHAT_GROUP);
		}

		bsort(conn);

		do {
			if ((inconn && (conn == curconn)) || bwin->waiting) {
				char	buf[256], *group;
				int	col = -1;

				assert(bwin->winname != NULL);
				buddyc++;

				if (bwin->et == BUDDY) {
					user_name(buf, sizeof(buf), conn, bwin->e.buddy);
					group = USER_GROUP(bwin->e.buddy);
				} else {
					snprintf(buf, sizeof(buf), "%s", bwin->winname);
					group = CHAT_GROUP;
				}

				if (autosort == 2) {
					if (strcmp(lastgroup, group) != 0) {
						if (line < wbuddy_widthy) {
							nw_move(&win_buddy, line++, widthx-strlen(group)-1);
							nw_printf(&win_buddy, C(WINLIST,TEXT), hidegroup?0:1, "%c%s%c",
								hidegroup?'<':'[', group, hidegroup?'>':']');
							buddyc++;
						}
						STRREPLACE(lastgroup, group);
					}
				}

				if (bwin->waiting && !waiting) {
					char	tmp[64];

					if (conn == curconn)
						snprintf(tmp, sizeof(tmp),
							" [Ctrl-N to %s]", buf);
					else
						snprintf(tmp, sizeof(tmp),
							" [Ctrl-N to %s:%s]", conn->winname, buf);
					secs_setvar("ifpending", tmp);
					waiting = 1;
				}
				if (printtitle && bwin->waiting && (waiting < 2) && ((bwin->et == BUDDY) || ((bwin->et == CHAT) && bwin->e.chat->isaddressed))) {
					nw_titlef("[%s:%s]", conn->winname, buf);
					waiting = 2;
				}

				if (line >= wbuddy_widthy)
					continue;

				if (strlen(buf) > M) {
					buf[M-1] = '>';
					buf[M] = 0;
				}

				if ((bwin->et == CHAT) && bwin->e.chat->isaddressed) {
					assert(bwin->waiting);
					col = C(WINLIST,BUDDY_ADDRESSED);
				} else if (bwin->waiting)
					if (bwin->et == BUDDY)
						col = C(WINLIST,BUDDY_ADDRESSED);
					else
						col = C(WINLIST,BUDDY_WAITING);
				else if (bwin->pouncec > 0)
					col = C(WINLIST,BUDDY_QUEUED);
				else
					switch (bwin->et) {
					  case BUDDY:
						if (bwin->e.buddy->tag != NULL)
							col = CI(WINLIST,BUDDY_TAGGED);
						else if (bwin->e.buddy->offline)
							col = C(WINLIST,BUDDY_OFFLINE);
						else if (bwin->e.buddy->ismobile)
							col = C(WINLIST,BUDDY_MOBILE);
						else if (bwin->e.buddy->isaway)
							col = C(WINLIST,BUDDY_AWAY);
						else if (bwin->e.buddy->isidle)
							col = C(WINLIST,BUDDY_IDLE);
						else
							col = C(WINLIST,BUDDY);
						break;
					  case CHAT:
						assert(bwin->e.chat != NULL);
						if (bwin->e.chat->offline)
							col = C(WINLIST,BUDDY_OFFLINE);
						else
							col = C(WINLIST,BUDDY);
						break;
					  case TRANSFER:
						col = C(WINLIST,BUDDY);
						break;
					}
				assert(col != -1);
				if (bwin == curconn->curbwin) {
					int	affect = col/COLOR_PAIRS,
						back;

#if 0
					if (faimconf.b[cIMWIN] == faimconf.b[cWINLIST])
						back = (faimconf.b[cIMWIN]+1)%nw_COLORS;
					else
						back = faimconf.b[cIMWIN];
#else
						back = faimconf.b[cWINLISTHIGHLIGHT];
#endif

					col %= nw_COLORS;
					col += nw_COLORS*back;
					col += affect*COLOR_PAIRS;
				}
				nw_move(&win_buddy, line, 1);
				if ((col >= 2*COLOR_PAIRS) || (col < COLOR_PAIRS))
					nw_printf(&win_buddy, col%COLOR_PAIRS, 1, "%*s", M, buf);
				else
					nw_printf(&win_buddy, col%COLOR_PAIRS, 0, "%*s", M, buf);
				if (bwin->waiting) {
					nw_move(&win_buddy, line, 0);
					nw_addch(&win_buddy, ACS_LTEE_C   | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS));
					nw_addch(&win_buddy, ACS_RARROW_C | A_BOLD | COLOR_PAIR(col%COLOR_PAIRS));
				}
				line++;
			}
			assert(buddyc < 1000);
		} while ((bwin = bwin->next) != conn->curbwin);

		if (autosort == 2) {
			free(lastgroup);
			lastgroup = NULL;
		} else
			assert(lastgroup == NULL);
	} while ((conn = conn->next) != curconn);

	nw_move(&win_buddy, line-1, 0);
	if (line != 1)
		nw_addch(&win_buddy, ACS_LLCORNER_C | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS));
	else
		nw_addch(&win_buddy, ACS_HLINE_C | A_BOLD | COLOR_PAIR(C(WINLIST,TEXT)%COLOR_PAIRS));

	if (printtitle && (waiting != 2))
		nw_titlef("");
	if (waiting)
		buddyc = -buddyc;
	else
		secs_setvar("ifpending", "");

	if (inconn)
		assert(curconn->curbwin != NULL);

	if ((buddyc != bb)
		||  (inconn && (&(curconn->curbwin->nwin) != lwin))
		|| (!inconn && (&(curconn->nwin) != lwin))) {
		if (inconn)
			lwin = &(curconn->curbwin->nwin);
		else
			lwin = &(curconn->nwin);
		bb = buddyc - bb;
		buddyc = buddyc - bb;
		bb = buddyc + bb;
		naim_changetime();
		buddyc = bb;
	}

	iupdate();
}
Example #26
0
File: bmap.c Project: gyao/fleurix
/*
 * Given an inode and a position within the corresponding file, locate the
 * block (not zone) number in which that position is to be found and return it.
 * returns 0 on error.
 * note: 
 * the first 7 entry of ip->zones[] are direct pointers, ip->zone[7] is an indirect 
 * pointer to a zone map, while ip->zone[8] is an double indirect pointer to a zone map.
 * note2: file extends only here.
 *
 * ip->i_size is adjusted in writei();
 *
 * TODO: maybe we can remove all the updatei and bwrite stuff, but sync() required first.
 */
int bmap(struct inode *ip, ushort nr, uchar creat) {
    struct buf *bp, *bp2;
    short *zmap, *zmap2;
    ushort dev;

    if ((nr > MAX_FILESIZ) || ((nr > (ip->i_size/BLK) && (creat==0)))) {
        panic("blk nr too big.");
    }

    dev = ip->i_dev;
    if (nr<7){
        // if the create flag is set
        if (ip->i_zone[nr]==0 && creat){
            ip->i_zone[nr] = balloc(dev);
            ip->i_flag |= I_DIRTY;
            iupdate(ip);
        }
        return ip->i_zone[nr];
    }
    nr -= 7;
    /*----------------------------*/
    // read the indirect zone map
    if (nr<NINDBLK){
        if (ip->i_zone[7]==0) {
            if (creat==0) {
                return 0;
            }
            // if the indirect block is null and creat is set
            ip->i_zone[7] = balloc(dev);
            bzero(dev, ip->i_zone[7]);
            ip->i_flag |= I_DIRTY;
            iupdate(ip);
        }
        bp = bread(dev, ip->i_zone[7]);
        zmap = (short *)bp->b_data;
        if (zmap[nr]==0 && creat) {
            zmap[nr] = balloc(dev);
            bwrite(bp);
        }
        brelse(bp);
        return zmap[nr];
    }
    /*----------------------------*/
    nr -= NINDBLK;
    // the double indirect zone map.
    // read the middle indirect zone map.
    if (ip->i_zone[8]==0) {
        // if the first indirect block is null and creat is set
        if (creat == 0) {
            return 0;
        }
        ip->i_zone[8] = balloc(dev);
        bzero(dev, ip->i_zone[8]);
        ip->i_flag |= I_DIRTY;
        iupdate(ip);
    } 
    bp = bread(dev, ip->i_zone[8]);
    zmap = (short *)bp->b_data;
    if (zmap[nr/NINDBLK]==0) {
        if (creat==0) {
            brelse(bp);
            return 0;
        }
        // if the second indirect block is null and creat is set
        zmap[nr/NINDBLK] = balloc(dev);
        bzero(dev, zmap[nr/NINDBLK]);
        bwrite(bp);
    }
    // read the secondary indirect zone map.
    bp2 = bread(dev, zmap[nr/NINDBLK]);
    zmap2 = (short*)bp2->b_data;
    if ((zmap2[nr%NINDBLK]==0) & creat) {
        zmap2[nr%NINDBLK] = balloc(dev);
        bwrite(bp2);
    }
    brelse(bp);
    brelse(bp2);
    return zmap2[nr%NINDBLK];
}