Ejemplo n.º 1
0
/* advances the slot of the path to the next item
 * (walking the tree and freeing the path as necessary).
 * returns 0 for success,
 * or on failure frees path and returns 1 if no next item or negative errno
 */
PUBLIC int step_to_next_slot(struct path *p) {
	struct cache *node;
	struct header *hdr;
	blocknr_t b;
	int slot;
	int level = 0;	/* starting at leaf */
	while (TRUE) {
		node = p->nodes[level];
		hdr = &node->u.node.header; 
		slot = ++(p->slots[level]);	/* advance the slot */
		if (slot < hdr->nritems) {	/* found the next slot */
			while (level) {			/* go back down to the leaf */
				b = ptr_for(node, slot);
				node = get_block(b);
				if (!node) {
					free_path_from(p, level);
					return -errno;
				}
				p->nodes[--level] = node;
				slot = 0; /* get the 0 slot all the way down to the leaf */
				hdr = &node->u.node.header; 
				assert(slot < hdr->nritems);
			}
			return KEY_FOUND;	/* on the next slot */
		}
		assert(slot >= hdr->nritems);	/* node is out of slots, */
		p->nodes[level] = NULL;		/* so take it off the path */
		put_block(node);			/* and free it from the path */
		p->slots[level] = 0;		/* this level will use the first slot */
		if(is_root_level(level, p)) {	/* can't go any higher */
			return KEY_NOT_FOUND;	/* there is no next item */
		}
		level++; 					/* look at next level up */
	}
}
Ejemplo n.º 2
0
int32_t enter_map(struct map *m,struct aoi_object *o)
{
	struct map_block *block = get_block_by_point(m,&o->current_pos);
	if(!block)
		return -1;
	double_link_push(&block->aoi_objs,&o->block_node);
	m->all_aoi_objects[o->aoi_object_id] = o;
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
	{
		radius = o->view_radius;
		double_link_push(&m->super_aoi_objs,&o->super_node);
	}
	uint32_t x1,y1,x2,y2;
	cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2);
	uint32_t y = y1;
	uint32_t x;
	for( ; y <= y2; ++y)
	{
		for(x=x1 ; x <= x2; ++x)
		{
			block_process_enter(m,get_block(m,y,x),o);
		}		
	}
	o->last_update_tick = GetCurrentMs();
	o->is_leave_map = 0;
	
}
Ejemplo n.º 3
0
void Uploader::request_block(std::shared_ptr<RemoteFolder> origin, const blob& ct_hash, uint32_t offset, uint32_t size) {
	try {
		origin->post_block(ct_hash, offset, get_block(ct_hash, offset, size));
	}catch(AbstractFolder::no_such_chunk& e){
		log_->warn() << log_tag() << "Requested nonexistent block";
	}
}
Ejemplo n.º 4
0
int valid_address(void *ptr){
  if (base && ptr > base && ptr < sbrk(0)) {
    return (ptr == get_block(ptr)->raw);
  } else {
    return 0;
  }
}
//frees dynamic allocated memory
void free(void *p){
    t_block block;
    if(valid_addr(p)){
        block = get_block(p);
        block->block_free = 1;
        //merge with previous if possible
        if(block->prev && block->prev->block_free){
            block = merge(block->prev);
        }
        //merge with next if possible
        if(block->next){
            if(block->next->block_free){
                merge(block);
            }
        } else {
            //free the end of the heap
            if(block->prev){
                //block->prev->next = 0x0;
            } else {
                // brk(block);
                // base = 0x0;
            }

        }

        //no more blocks
        if(!block->next && !block->prev){
            brk(block);
            base = 0x0;
        }
    }
}
Ejemplo n.º 6
0
int search(INODE *ip, char *name)
{
    int i;
    char *cp;
    DIR *dp;
    char buf[BLKSIZE];
    char temp[256];

    // For DIR inodes, assume that (the number of entries is small so that) only has
    // 12 DIRECT data blocks. Therefore, search only the direct blocks for name[0].
    for (i = 0; i < 12; i++)
    {
        //printf("iblock[%d] = %d\n", i, ip->i_block[i]);
        if (ip->i_block[i] == 0)
            break;

        get_block(fd, ip->i_block[i], buf);
        dp = (DIR *)buf;
        cp = buf;

        while (cp < buf + BLKSIZE)
        {
            strncpy(temp, dp->name, dp->name_len);
            temp[dp->name_len] = 0;

            if (strcmp(name, temp) == 0)
                return dp->inode;

            cp += dp->rec_len;
            dp = (DIR *)cp;
        }
    }

    return 0;    
}
Ejemplo n.º 7
0
/* Increment the link count to inode n */
void
incr_link(ino_t n)
{
  int off;
  static int enter = 0;
  static struct inode *inodes = NULL;
  block_t b;

  if (enter++) pexit("internal error: recursive call to incr_link()");

  b = ((n - 1) / inodes_per_block) + inode_offset;
  off = (n - 1) % inodes_per_block;
  {
	assert(sizeof(*inodes) * inodes_per_block == block_size);
	if(!inodes && !(inodes = alloc_block()))
		err(1, "couldn't allocate a block of inodes");

	get_block(b, inodes);
	inodes[off].i_nlinks++;
	/* Check overflow (particularly on V1)... */
	if (inodes[off].i_nlinks <= 0)
		pexit("Too many links to a directory");
	put_block(b, inodes);
  }
  enter = 0;
}
Ejemplo n.º 8
0
struct map *create_map(struct point2D *top_left,struct point2D *bottom_right,callback_ enter_callback,callback_ leave_callback)
{
	//����block�����
	uint32_t length = abs(top_left->x - bottom_right->x);
	uint32_t width = abs(top_left->y - bottom_right->y);
	
	uint32_t x_count = length % BLOCK_LENGTH == 0 ? length/BLOCK_LENGTH : length/BLOCK_LENGTH + 1;
	uint32_t y_count = width % BLOCK_LENGTH == 0 ? width/BLOCK_LENGTH : width/BLOCK_LENGTH + 1;
	
	struct map *m = calloc(1,x_count*y_count*sizeof(struct map_block)+sizeof(struct map));
	m->top_left = *top_left;
	m->bottom_right = *bottom_right;
	m->x_count = x_count;
	m->y_count = y_count;
	uint32_t x,y;
	for(y = 0; y < y_count; ++y)
		for(x = 0; x < x_count; ++x)
		{
			struct map_block * b = get_block(m,y,x);
			double_link_clear(&b->aoi_objs);
			b->x = x;
			b->y = y;
		}
	double_link_clear(&m->super_aoi_objs);
	m->enter_callback = enter_callback;
	m->leave_callback = leave_callback;
	return m;
}
Ejemplo n.º 9
0
// Return a pointer to an inode given its number. In a real filesystem, this
// would require finding the correct block group, rather than assuming it's in
// the first.
struct ext2_inode * _ref_get_inode(void * fs, __u32 inode_num) {
    struct ext2_group_desc * bgd = get_block_group(fs, 0);
    __u32 inode_table_block = bgd->bg_inode_table;
    struct ext2_inode * inode_table = get_block(fs, inode_table_block);
    // Since inode 0 doesn't ever exist, the table starts from 1.
    return inode_table + inode_num - 1;
}
Ejemplo n.º 10
0
// Given the inode for a directory and a filename, return the inode number of
// that file inside that directory, or 0 if it doesn't exist.
// 
// name should be a single component - "foo.txt", not "/files/foo.txt".
__u32 _ref_get_inode_from_dir(void * fs, struct ext2_inode * dir, 
        char * name) {
    assert(LINUX_S_ISDIR(dir->i_mode));

    // Iterate over each entry of the directory, looking for a match for name.
    __u32 block_size = get_block_size(fs);
    void * dir_block = get_block(fs, dir->i_block[0]);
    struct ext2_dir_entry * entry = (struct ext2_dir_entry *) dir_block;
    void * limit = ((void *) entry) + block_size;

    __u32 target_inode = 0;
    while ((void *) entry < limit) {
        // Skip unused entries.
        if (entry->inode == 0) {
            continue;
        }

        if (strlen(name) == (unsigned char) (entry->name_len) &&
            strncmp(name, entry->name, strlen(name)) == 0) {
            target_inode = entry->inode;
        }

        // Advance to the next entry.
        entry = (struct ext2_dir_entry *) (((void *) entry) + entry->rec_len);
    }

    if (target_inode != 0) {
        return target_inode;
    } else {
        return 0;
    }
}
Ejemplo n.º 11
0
// Return a pointer to the first block group descriptor in a filesystem. Real
// ext2 filesystems will have several of these, but, for simplicity, we will
// assume there is only one.
struct ext2_group_desc * _ref_get_block_group(void * fs, __u32 block_group_num) {
    // The first block group descriptor is in the first full block after the
    // superblock.
    __u32 block_size = get_block_size(fs);
    __u32 bgd_block = (SUPERBLOCK_OFFSET / block_size) + 1;
    return (struct ext2_group_desc *) get_block(fs, bgd_block); 
}
Ejemplo n.º 12
0
static void fill_indirect_block(u32 *ind_block, int len, struct block_allocation *alloc)
{
	int i;
	for (i = 0; i < len; i++) {
		ind_block[i] = get_block(alloc, i);
	}
}
Ejemplo n.º 13
0
uint8 *csi_get_block(struct csi *csi)
{
    if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0)
        return NULL;

    return get_block(csi->vol->fd, _csi_to_block_(csi), csi->vol->bytes_per_sector);
}
Ejemplo n.º 14
0
int search_inode_in_folder(int folder_number, const char *node_name)
{
    int result = -1;
    if (folder_number >= 0 && node_name != NULL)
    {
        inode_t *folder = (inode_t *)get_block(folder_number);
        if (folder != NULL)
        {
            if (folder->status == BLOCK_STATUS_FOLDER)
            {
                char name[NODE_NAME_MAX_SIZE];
                int *start = (int *)folder->content;
                int *end = (int *)((void *)folder + size_of_block);
                while (start < end)
                {
                    if (*start > 0 && get_inode_name(*start, name) == 0 && strcmp(node_name, name) == 0)
                    {
                        result = *start;
                        break;
                    }
                    start++;
                }
            }
            destroy_block(folder);
        }
    }
    return result;
}
Ejemplo n.º 15
0
/* Increment the file-size in inode n */
void
incr_size(ino_t n, size_t count)
{
  block_t b;
  int off;

  b = ((n - 1) / inodes_per_block) + inode_offset;
  off = (n - 1) % inodes_per_block;
  {
	struct inode *inodes;

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

	get_block(b, inodes);
	/* Check overflow; avoid compiler spurious warnings */
	if (inodes[off].i_size+(int)count < inodes[off].i_size ||
	    inodes[off].i_size > MAX_MAX_SIZE-(int)count)
		pexit("File has become too big to be handled by MFS");
	inodes[off].i_size += count;
	put_block(b, inodes);
	free(inodes);
  }
}
Ejemplo n.º 16
0
static inline tick_super_object(struct map *m,struct aoi_object *o)
{
	uint32_t now = GetCurrentMs();
	if(now - o->last_update_tick >= UPDATE_INTERVAL)
	{ 
		//remove out of view object first
		uint32_t i = 0;
		for( ; i < MAX_BITS; ++i)
		{
			if(o->self_view_objs.bits[i] > 0)
			{
				uint32_t j = 0;
				for( ; j < sizeof(uint32_t); ++j)
				{
					if(o->self_view_objs.bits[i] & (1 << j))
					{
						uint32_t aoi_object_id = i*sizeof(uint32_t) + j;
						if(aoi_object_id != o->aoi_object_id)
						{
							struct aoi_object *other = m->all_aoi_objects[aoi_object_id];
							if(other->is_leave_map)
								leave_me(m,o,other);
							else
							{
								uint64_t distance = cal_distance_2D(&o->current_pos,&other->current_pos);
								if(distance > o->view_radius)
									leave_me(m,o,other);
							}
						}
					}
				}
			}
		}
		//process enter view
		uint32_t x1,y1,x2,y2;
		cal_blocks(m,&o->current_pos,o->view_radius,&x1,&y1,&x2,&y2);
		uint32_t y = y1;
		uint32_t x;
		for( ; y <= y2; ++y)
		{
			for( x=x1; x <= x2; ++x)
			{
				struct map_block *bl = get_block(m,y,x);
				struct aoi_object *cur = (struct aoi_object*)bl->aoi_objs.head.next;
				while(cur != (struct aoi_object*)&bl->aoi_objs.tail)
				{
					if(is_set(&o->self_view_objs,cur->aoi_object_id) == 0)
					{
						uint64_t distance = cal_distance_2D(&o->current_pos,&cur->current_pos);
						if(o->view_radius >= distance)
							enter_me(m,o,cur);
					}
					cur = (struct aoi_object *)cur->block_node.next;
				}
			}		
		}		
		o->last_update_tick = now;	
	}
	
}
Ejemplo n.º 17
0
/* Insert one bit into the bitmap */
void
insert_bit(block_t map, bit_t bit)
{
  int boff, w, s;
  unsigned int bits_per_block;
  block_t map_block;
  bitchunk_t *buf;

  buf = alloc_block();

  bits_per_block = FS_BITS_PER_BLOCK(block_size);
  map_block = map + bit / bits_per_block;
  if (map_block >= inode_offset)
	pexit("insertbit invades inodes area - this cannot happen");
  boff = bit % bits_per_block;

  assert(boff >=0);
  assert(boff < FS_BITS_PER_BLOCK(block_size));
  get_block(map_block, buf);
  w = boff / FS_BITCHUNK_BITS;
  s = boff % FS_BITCHUNK_BITS;
  buf[w] |= (1 << s);
  put_block(map_block, buf);

  free(buf);
}
Ejemplo n.º 18
0
/*
* print_blocks - for each logical block consumed by the file
* associated with fd, prints to standard out the tuple
* "(logical block, physical block)"
*/
void print_blocks(int fd)
{
	int nr_blocks, i;
	nr_blocks = get_nr_blocks(fd);
	if (nr_blocks < 0) {
		fprintf(stderr, "get_nr_blocks failed!\n");
		return;
	}
	if (nr_blocks == 0) {
		printf("no allocated blocks\n");
		return;
	} else if (nr_blocks == 1)
		printf("1 block\n\n");
	else
		printf("%d blocks\n\n", nr_blocks);
	for (i = 0; i < nr_blocks; i++) {
		int phys_block;
		phys_block = get_block(fd, i);
		if (phys_block < 0) {
			fprintf(stderr, "get_block failed!\n");
			return;
		}
		if (!phys_block)
			continue;
		printf("(%u, %u) ", i, phys_block);
	}
	putchar('\n');
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
/*
 * ShmemDynAlloc
 */
void *
ShmemDynAlloc(Size size)
{
	void *block = NULL;
	Size padded_size;

	size = Max(ALIGN(size), MIN_ALLOC_SIZE);
	for (padded_size = 1; padded_size < size && padded_size <= 1024; padded_size *= 2);
	size = Max(size, padded_size);

	block = get_block(size);

	if (block == NULL)
	{
		/*
		 * Don't request fewer than 1k from ShmemAlloc.
		 * The more contiguous memory we have, the better we
		 * can combat fragmentation.
		 */
		Size alloc_size = Max(size, MIN_SHMEM_ALLOC_SIZE);
		block = ShmemAlloc(BLOCK_SIZE(alloc_size));

		memset(block, 0, BLOCK_SIZE(alloc_size));
		block = (void *) ((intptr_t) block + sizeof(Header));
		init_block(block, alloc_size, true);
		mark_allocated(block);
	}

	if (get_size(block) - size >= MIN_BLOCK_SIZE)
		split_block(block, size);

	Assert(is_allocated(block));

	return block;
}
Ejemplo n.º 21
0
int32_t leave_map(struct map *m,struct aoi_object *o)
{
	struct map_block *block = get_block_by_point(m,&o->current_pos);
	if(!block)
		return -1;
	dlist_remove(&o->block_node);
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
	{
		radius = o->view_radius;
		dlist_remove(&o->super_node);
	}	
	uint32_t x1,y1,x2,y2;
	x1 = y1 = x2 = y2 = 0;
	cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2);
	uint32_t y = y1;
	uint32_t x;
	for( ; y <= y2; ++y)
	{
		for( x=x1; x <= x2; ++x)
		{
			block_process_leave(m,get_block(m,y,x),o,1);
		}		
	}
	o->is_leave_map = 1;

	//自己离开自己的视野
	leave_me(m,o,o);
	return 0;			
}
Ejemplo n.º 22
0
// --------------------------------------------------------------------------
int DecoderPE::run(BlockStore &bs)
{
	while (get_block(bs) == VT_OK) {
	}

	return VT_OK;
}
Ejemplo n.º 23
0
int findino(MINODE *mip, int *myino, int *parent)
{
    int device = 0;
    INODE* ip = NULL;

    if(!mip)
    {
        fprintf(stderr, "findino: null mip\n");
        return FAILURE;
    }

    device = mip->device;
    ip = &mip->inode;

    //Check that mip is a directory
    if (!S_ISDIR(ip->i_mode))
    {
        fprintf(stderr, "findino: Not a directory\n");
        return FAILURE;
    }

    u8* block = get_block(device, ip->i_block[0]);
    u8* cp = block; 
    DIR* dp = (DIR*)block;

    *myino = dp->inode;

    cp += dp->rec_len;       // advance cp by rec_len BYTEs
    dp = (DIR*)cp;           // pull dp along to the next record

    *parent = dp->inode;

    free(block);
    return SUCCESS;
}
Ejemplo n.º 24
0
/*===========================================================================*
 *                             fs_rdlink                                     *
 *===========================================================================*/
PUBLIC int fs_rdlink()
{
  block_t b;                   /* block containing link text */
  struct buf *bp;              /* buffer containing link text */
  register struct inode *rip;  /* target inode */
  register int r;              /* return value */
  size_t copylen;
  
  copylen = min( (size_t) fs_m_in.REQ_MEM_SIZE, UMAX_FILE_POS);

  /* Temporarily open the file. */
  if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
	  return(EINVAL);

  if(!S_ISLNK(rip->i_mode))
	  r = EACCES;
  else if ((b = read_map(rip, (off_t) 0)) == NO_BLOCK)
	r = EIO;
  else {
	/* Passed all checks */
	/* We can safely cast to unsigned, because copylen is guaranteed to be
	   below max file size */
	copylen = min( copylen, (unsigned) rip->i_size);
	bp = get_block(rip->i_dev, b, NORMAL);
	r = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
			   (vir_bytes) 0, (vir_bytes) bp->b_data,
	  		   (size_t) copylen, D);
	put_block(bp, DIRECTORY_BLOCK);
	if (r == OK)
		fs_m_out.RES_NBYTES = copylen;
  }
  
  put_inode(rip);
  return(r);
}
Ejemplo n.º 25
0
int sfs_open(char *pathname){
  int dNum;
  int parentINumber;
  int inumber = parsePathname(pathname, &parentINumber, dNum);
  char* tmp_buffer[MAX_IO_LENGTH+1];
  if (inumber<0){
    return -1;
  }
  OpenFileTable[inumber][0]+=1;
  if(fileCount<4){
    if(OpenFileTable[inumber][1]==NULL){
      OpenFileTable[inumber][1]=fileCount;
      get_block(inode[inumber][3],RAM[OpenFileTable[inumber][1]]);
      //edit for file size of 512 here
      fileCount++;
    }else{
      OpenFileTable[inumber][0]++;
    }
  }else if(OpenFileTable[inumber][1]!=NULL){
     OpenFileTable[inumber][0]++;
  }else{
     return -1;
  }
  return 1;
}
Ejemplo n.º 26
0
void free(void *ptr){
  sum_frees++;
  num_allocated--;

  block_t current;
  if (valid_address(ptr)){
    current = get_block(ptr);
    current->free = 1;
    if(current->prev && current->prev->free){
      //merge with prev block if works
      current = merge_block(current->prev);
    }
    if (current->next){
      //merge with next
      merge_block(current);
    } else {
      if (current->prev){
        current->prev->next = NULL;
      } else {
        //no more blocks
        base = NULL;
      }
      brk(current);
    }
  } else {
    perror("invalid ptr at free");
  }
}
Ejemplo n.º 27
0
int32_t leave_map(struct map *m,struct aoi_object *o)
{
	struct map_block *block = get_block_by_point(m,&o->current_pos);
	if(!block)
		return -1;
	double_link_remove(&o->block_node);
	uint32_t radius = STAND_RADIUS;	
	if(o->view_radius > STAND_RADIUS)
	{
		radius = o->view_radius;
		double_link_remove(&o->super_node);
	}	
	uint32_t x1,y1,x2,y2;
	cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2);
	uint32_t y = y1;
	uint32_t x;
	for( ; y <= y2; ++y)
	{
		for( x=x1; x <= x2; ++x)
		{
			block_process_leave(m,get_block(m,y,x),o,1);
		}		
	}
	o->is_leave_map = 1;
	if(--o->watch_me_count == 0)
		m->all_aoi_objects[o->aoi_object_id] = NULL;			
}
Ejemplo n.º 28
0
int remove_node_from_folder(int folder_number, int node_number)
{
    int result = -1;
    if (folder_number >= 0 && node_number > 0)
    {
        inode_t *folder = (inode_t *)get_block(folder_number);
        if (folder != NULL)
        {
            if (folder->status == BLOCK_STATUS_FOLDER)
            {
                int *start = (int *)folder->content;
                int *end = (int *)((void *)folder + size_of_block);
                while (start < end)
                {
                    if (*start == node_number)
                    {
                        *start = 0;
                        break;
                    }
                    start++;
                }
                if (start < end)
                {
                    result = write_block(folder_number, folder);
                }
                else
                {
                    result = 0;
                }
            }
            destroy_block(folder);
        }
    }
    return result;
}
Ejemplo n.º 29
0
//mount root file system, establish / and CWDs
mount_root(char device_name[64])
{
	char buf[1024];
	//open device for RW
	dev = open(device_name, O_RDWR);

	//check if open() worked
	if(dev < 0)
	{
		printf("ERROR: failed cannot open %s\n", device_name);
		exit(0);
	}

	//read super block to verify it's an EXT2 FS
	get_block(dev, SUPERBLOCK, buf);
	sp = (SUPER *)buf;
	//verify if it's an EXT2 FS
	if(sp->s_magic != 0xEF53)
	{
		printf("NOT AN EXT2 FS\n");
		exit(1);
	}

	//set some vars
	ninodes = sp->s_inodes_count;
	nblocks = sp->s_blocks_count;

	//read group block for info
	get_block(dev, GDBLOCK, buf);
	gp = (GD *)buf;

	imap = gp->bg_inode_bitmap;
	bmap = gp->bg_block_bitmap;

	inodeBeginBlock = gp->bg_inode_table;

	//get root inode
	root = iget(dev, 2);

	//let cwd of both p0 and p1 point at the root minode (refCount=3)
	proc[0].cwd = root;
	proc[1].cwd = root;

	root->refCount = 3;

	printf("%s mounted\n", device_name);
}
void
do_ls()
{
    int dev;
    u32 ino;
    MINODE* mip;
    char buf[BLOCK_SIZE];
    char temp[BLOCK_SIZE];
    char* cp;
    int i;

    if (0 == pathName[0])
    {
        printf("ls : current working directory");
        ino = running->cwd->ino;
        dev = running->cwd->dev;
    }
    else if (0 == strcmp(pathName, "/"))
    {
        printf("ls : root directory");
        ino = root->ino;
        dev = root->dev;
    }
    else
    {
        printf("ls : ");
        ino = getino(&dev, pathName);
    }

    if ((u32)-1 == ino)
    {
        err_printf("ls : it is not a directory\n");
        return;
    }
    printf("\n");

    mip = iget(dev, ino);

    for (i = 0; i < 12 &&  (mip->INODE).i_block[i]; i++)
    {
        get_block(mip->dev, (mip->INODE).i_block[i], buf);
        cp = buf;
        dp = (DIR*)buf;
        //printf("i_block is %i\n", (int) (mip->INODE).i_block[i]);
        while (cp < buf + BLOCK_SIZE && dp->rec_len)
        {
            if (0 == dp->rec_len) break;
            strncpy(temp, dp->name, dp->name_len);
            temp[dp->name_len] = 0;
            file_info(dev, dp->inode);
            //printf("%3u %s\n", dp->inode, temp); // with inode
            printf("%s\n", temp);
            cp += dp->rec_len;
            dp = (DIR*)cp;
        }
    }

    iput(mip);
}