loff_t yaffs_get_file_size(struct yaffs_obj *obj)
{
	YCHAR *alias = NULL;
	obj = yaffs_get_equivalent_obj(obj);

	switch (obj->variant_type) {
	case YAFFS_OBJECT_TYPE_FILE:
		return obj->variant.file_variant.file_size;
	case YAFFS_OBJECT_TYPE_SYMLINK:
		alias = obj->variant.symlink_variant.alias;
		if (!alias)
			return 0;
		return yaffs_strnlen(alias, YAFFS_MAX_ALIAS_LENGTH);
	default:
		return 0;
	}
}
Example #2
0
static struct yaffs_obj *h_follow_link(struct yaffs_obj *obj, const char **out_of_fs)
{
	if(obj)
		obj = yaffs_get_equivalent_obj(obj);

	while(obj && obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
		YCHAR *alias = obj->variant.symlink_variant.alias;

		if(is_path_divider(*alias))
			/* Starts with a /, need to scan from root up */
			obj = h_find_object(obj->my_dev, NULL, alias, out_of_fs);
		else
			/* Relative to here, so use the parent of the symlink as a start */
			obj = h_find_object(obj->my_dev, obj->parent, alias, out_of_fs);
	}
	return obj;
}
Example #3
0
static ssize_t ycb_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
{
	struct yaffs_obj *obj;
	struct yaffs_dev *dev;
	struct dirent *de = (struct dirent *)buffer;
	size_t i;
	size_t maxcount;
	struct list_head *next;
	ssize_t readlen;
	
	obj = (struct yaffs_obj *)iop->pathinfo.node_access;
	dev = obj->my_dev;
	maxcount = count / sizeof(struct dirent);

	ylock(dev);
	
	if(iop->offset == 0) {
		if(list_empty(&obj->variant.dir_variant.children))
			iop->data1 = NULL;
		else
			iop->data1 = list_entry(obj->variant.dir_variant.children.next, struct yaffs_obj, siblings);
	}
	
	i = 0;
	while((i < maxcount) && (iop->data1 != NULL)) {
		de[i].d_ino = (long)yaffs_get_equivalent_obj((struct yaffs_obj *)iop->data1)->obj_id;
		de[i].d_off = 0;
		yaffs_get_obj_name((struct yaffs_obj *)iop->data1, de[i].d_name, NAME_MAX);
		de[i].d_reclen = sizeof(struct dirent);
		de[i].d_namlen = (unsigned short)strnlen(de[i].d_name, NAME_MAX);
		
		i++;
		next = ((struct yaffs_obj *)iop->data1)->siblings.next;
		if(next == &obj->variant.dir_variant.children)
			iop->data1 = NULL; /* end of list */
		else
			iop->data1 = list_entry(next, struct yaffs_obj, siblings);
	}
	
	readlen = (ssize_t)(i * sizeof(struct dirent));
	iop->offset = iop->offset + readlen;

	yunlock(dev);
	
	return readlen;
}
Example #4
0
static int ycb_utime(rtems_filesystem_location_info_t *pathloc, time_t actime, time_t modtime)
{
	struct yaffs_obj *obj;
	struct yaffs_dev *dev;

	obj = pathloc->node_access;
	dev = obj->my_dev;
	
	ylock(dev);
	obj = yaffs_get_equivalent_obj(obj);
	if(obj != NULL) {
		obj->dirty = 1;
		obj->yst_atime = obj->yst_ctime = (u32)actime;
		obj->yst_mtime = (u32)modtime;
	}
	yunlock(dev);
	return 0;
}
Example #5
0
static int ycb_fstat(rtems_filesystem_location_info_t *loc, struct stat *buf)
{
	struct yaffs_obj *obj;
	struct yaffs_dev *dev;
	
	obj = (struct yaffs_obj *)loc->node_access;
	dev = (struct yaffs_dev *)obj->my_dev;

	ylock(dev);
	
	obj = yaffs_get_equivalent_obj(obj);

	buf->st_ino = obj->obj_id;
	buf->st_mode = obj->yst_mode & ~(unsigned)S_IFMT; /* clear out file type bits */

	if(obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
		buf->st_mode |= S_IFDIR;
	else if(obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK)
		buf->st_mode |= S_IFLNK;
	else if(obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
		buf->st_mode |= S_IFREG;

	buf->st_rdev = 0ll;
	buf->st_nlink = (nlink_t)yaffs_get_obj_link_count(obj);
	buf->st_uid = 0;
	buf->st_gid = 0;
	buf->st_rdev = obj->yst_rdev;
	buf->st_size = yaffs_get_obj_length(obj);
	buf->st_blksize = obj->my_dev->data_bytes_per_chunk;
	buf->st_blocks = (blkcnt_t)((buf->st_size + buf->st_blksize -1)/buf->st_blksize);
	buf->st_atime = (time_t)obj->yst_atime;
	buf->st_ctime = (time_t)obj->yst_ctime;
	buf->st_mtime = (time_t)obj->yst_mtime;

	yunlock(dev);
	
	return 0;
}
Example #6
0
static int ycb_fchmod(rtems_filesystem_location_info_t *loc, mode_t mode)
{
	struct yaffs_obj *obj;
	struct yaffs_dev *dev;
	int result;

	if(mode & ~(0777u)){
		errno = EINVAL;
		return -1;
	}
	
	obj = loc->node_access;
	if(obj->my_dev->read_only) {
		errno = EROFS;
		return -1;
	}

	dev = obj->my_dev;

	ylock(dev);

	obj = yaffs_get_equivalent_obj(obj);

	result = YAFFS_FAIL;
	if(obj) {
		obj->yst_mode = (obj->yst_mode & ~0777u) | mode;
		obj->dirty = 1;
		result = yaffs_flush_file(obj, 0, 0);
	}
	if(result != YAFFS_OK) {
		yunlock(dev);
		errno = EIO;
		return -1;
	}
	yunlock(dev);
	return 0;
}