Example #1
0
int uffs_stat(const char *name, struct uffs_stat *buf)
{
    uffs_Object *obj;
    int ret = 0;
    int err = 0;
    URET result;

    obj = uffs_GetObject();
    if (obj) {
        if (*name && name[strlen(name) - 1] == '/') {
            result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR);
        } else {
            if ((result = uffs_OpenObject(obj, name, UO_RDONLY)) != U_SUCC)	// try file
                result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR);	// then try dir
        }
        if (result == U_SUCC) {
            ret = do_stat(obj, buf);
            uffs_CloseObject(obj);
        } else {
            err = uffs_GetObjectErr(obj);
            ret = -1;
        }
        uffs_PutObject(obj);
    } else {
        err = UENOMEM;
        ret = -1;
    }

    uffs_set_error(-err);
    return ret;
}
Example #2
0
uffs_DIR * uffs_opendir(const char *path)
{
    int err = 0;
    uffs_DIR *ret = NULL;
    uffs_DIR *dirp = GetDirEntry();

    if (dirp) {
        dirp->obj = uffs_GetObject();
        if (dirp->obj) {
            if (uffs_OpenObject(dirp->obj, path, UO_RDONLY | UO_DIR) == U_SUCC) {
                if (uffs_FindObjectOpen(&dirp->f, dirp->obj) == U_SUCC) {
                    ret = dirp;
                    goto ext;
                } else {
                    uffs_CloseObject(dirp->obj);
                }
            } else {
                err = uffs_GetObjectErr(dirp->obj);
            }
            uffs_PutObject(dirp->obj);
            dirp->obj = NULL;
        } else {
            err = UEMFILE;
        }
        PutDirEntry(dirp);
    } else {
        err = UEMFILE;
    }
ext:
    uffs_set_error(-err);
    return ret;
}
int uffs_mkdir(const char *name, ...)
{
	uffs_Object *obj;
	int ret = 0;
	int err = 0;

	uffs_GlobalFsLockLock();

	obj = uffs_GetObject();
	if (obj) {
		if (uffs_CreateObject(obj, name, UO_CREATE|UO_DIR) != U_SUCC) {
			err = obj->err;
			ret = -1;
		}
		else {
			uffs_CloseObject(obj);
			ret = 0;
		}
		uffs_PutObject(obj);
	}
	else {
		err = UEMFILE;
		ret = -1;
	}

	uffs_set_error(-err);
	uffs_GlobalFsLockUnlock();

	return ret;
}
int uffs_open(const char *name, int oflag, ...)
{
	uffs_Object *obj;
	int ret = 0;

	uffs_GlobalFsLockLock();

	obj = uffs_GetObject();
	if (obj == NULL) {
		uffs_set_error(-UEMFILE);
		ret = -1;
	}
	else {
		if (uffs_OpenObject(obj, name, oflag) == U_FAIL) {
			uffs_set_error(-uffs_GetObjectErr(obj));
			uffs_PutObject(obj);
			ret = -1;
		}
		else {
			ret = OBJ2FD(obj);
		}
	}

	uffs_GlobalFsLockUnlock();

	return ret;
}
Example #5
0
/*
 * 函数功能: 创建一个文件
 * 输入参数: 文件名称
 * 返回参数: 
 */
int uffs_mkfile(const char *name)
{
	uffs_Object *fp;
	int ret = 0;
	int err = 0;

	fp = uffs_GetObject();	

	if(fp != NULL) 
	{
		if(uffs_CreateObject(fp, name, UO_CREATE) != U_SUCC) 
		{
			err = fp->err;
			ret = -1;
			uffs_Perror(UFFS_ERR_NORMAL, "Create %s fail, err: %d", name, uffs_get_error());
		}
		else 
		{
			uffs_Perror(UFFS_ERR_NORMAL, "Create %s succ.", name);
			uffs_CloseObject(fp);
			ret = 0;
		}
		uffs_PutObject(fp);
	}
	else 
	{
		err = UEMFILE;
		ret = -1;
	}
	
	uffs_set_error(-err);
	return ret;
}
Example #6
0
File: uffs_fs.c Project: mazj/uffs
/**
 * \brief rename(move) file or dir.
 * \return U_SUCC if success, otherwise return U_FAIL and set error code to *err.
 * \note rename/move file between different mount point is not allowed.
 */
URET uffs_RenameObject(const char *old_name, const char *new_name, int *err)
{
	uffs_Object *obj = NULL, *new_obj = NULL;
	URET ret = U_FAIL;
	int oflag;

	obj = uffs_GetObject();
	new_obj = uffs_GetObject();

	if (obj == NULL || new_obj == NULL) {
		if (err) 
			*err = UEINVAL;
		goto ext;
	}

	oflag = UO_RDONLY;
	if (uffs_OpenObject(new_obj, new_name, oflag) == U_SUCC) {
		uffs_CloseObject(new_obj);
		uffs_Perror(UFFS_MSG_NOISY, "new object already exist!");
		if (err)
			*err = UEEXIST;
		goto ext;
	}
	oflag |= UO_DIR;
	if (uffs_OpenObject(new_obj, new_name, oflag) == U_SUCC) {
		uffs_CloseObject(new_obj);
		uffs_Perror(UFFS_MSG_NOISY, "new object already exist!");
		if (err)
			*err = UEEXIST;
		goto ext;
	}

	if (uffs_ParseObject(new_obj, new_name) != U_SUCC) {
		uffs_Perror(UFFS_MSG_NOISY, "parse new name fail !");
		if (err)
			*err = UENOENT;
		goto ext;
	}

	if (new_obj->name_len == 0) {
		uffs_Perror(UFFS_MSG_NOISY, "invalid new name");
		if (err)
			*err = UEINVAL;
		goto ext;
	}

	oflag = UO_RDONLY;
	if (uffs_OpenObject(obj, old_name, oflag) != U_SUCC) {
		oflag |= UO_DIR;
		if (uffs_OpenObject(obj, old_name, oflag) != U_SUCC) {
			uffs_Perror(UFFS_MSG_NOISY, "Can't open old object !");
			if (err)
				*err = UEACCES;
			goto ext;
		}
	}

	if (obj->dev != new_obj->dev) {
		uffs_Perror(UFFS_MSG_NOISY,
					"Can't move object between different mount point");
		if (err)
			*err = UEACCES;
	}
	else {
		ret = uffs_MoveObjectEx(obj, new_obj->parent,
									new_obj->name, new_obj->name_len);
		if (ret == U_FAIL && err)
			*err = obj->err;
	}

	uffs_CloseObject(obj);

ext:
	if (obj) uffs_PutObject(obj);
	if (new_obj) {
		do_ReleaseObjectResource(new_obj);
		uffs_PutObject(new_obj);
	}

	return ret;
}
Example #7
0
File: uffs_fs.c Project: mazj/uffs
/**
 * \brief delete uffs object
 *
 * \param[in] name full name of object
 * \param[out] err return error code
 *
 * \return U_SUCC if object is deleted successfully. 
 *	return U_FAIL if error happen, error code is set to *err.
 */
URET uffs_DeleteObject(const char * name, int *err)
{
	uffs_Object *obj, *work;
	TreeNode *node, *d_node;
	uffs_Device *dev = NULL;
	u16 block;
	u16 serial, parent, last_serial;
	UBOOL bad = U_FALSE;
	URET ret = U_FAIL;

	obj = uffs_GetObject();
	if (obj == NULL) {
		if (err)
			*err = UEMFILE;
		goto ext_unlock;
	}

	if (uffs_OpenObject(obj, name, UO_RDWR|UO_DIR) == U_FAIL) {
		if (uffs_OpenObject(obj, name, UO_RDWR) == U_FAIL) {
			if (err)
				*err = UENOENT;
			goto ext_unlock;
		}
	}

	dev = obj->dev;

	// working throught object pool see if the object is opened ...
	uffs_ObjectDevLock(obj);
	work = NULL;
	while ((work = (uffs_Object *)uffs_PoolFindNextAllocated(&_object_pool, work)) != NULL) {
		if (work != obj && 
			work->dev &&
			work->dev == obj->dev &&
			work->node &&
			work->node == obj->node) {
			// this object is opened, can't delete it.
			if (err)
				*err = UEACCES;
			goto ext_lock;
		}
	}

	if (obj->type == UFFS_TYPE_DIR) {
		// if the dir is not empty, can't delete it.
		node = uffs_TreeFindDirNodeWithParent(dev, obj->serial);
		if (node != NULL) {
			if (err)
				*err = UEACCES;
			goto ext_lock;  //have sub dirs ?
		}

		node = uffs_TreeFindFileNodeWithParent(dev, obj->serial);
		if (node != NULL) {
			if (err)
				*err = UEACCES;
			goto ext_lock;  //have sub files ?
		}
	}

	// before erase the block, we need to take care of the buffer ...
	uffs_BufFlushAll(dev);

	if (_CheckObjBufRef(obj) > 0) {
		if (err)
			*err = UEACCES;
		goto ext_lock;
	}

	node = obj->node;

	// ok, now we are safe to erase DIR/FILE block :-)
	block = GET_BLOCK_FROM_NODE(obj);
	parent = obj->serial;
	last_serial = (obj->type == UFFS_TYPE_FILE && node->u.file.len > 0 ? GetFdnByOfs(obj, node->u.file.len - 1) : 0);

	uffs_BreakFromEntry(dev, obj->type, node);
	uffs_FlashEraseBlock(dev, block);
	node->u.list.block = block;
	node->u.list.u.serial = obj->serial;

	// From now on, the object is gone physically,
	// but we need to 'suspend' this node so that no one will re-use
	// the serial number during deleting the reset part of object.

	if (HAVE_BADBLOCK(dev)) {
		uffs_BadBlockProcessSuspend(dev, node);
		bad = U_TRUE;  // will be put into 'bad' list later
	}
	else {
		uffs_TreeSuspendAdd(dev, node);
		bad = U_FALSE;	// will be put into erased list later
	}

	// now erase DATA blocks
	if (obj->type == UFFS_TYPE_FILE && last_serial > 0) {
		for (serial = 1; serial <= last_serial; serial++) {

			uffs_ObjectDevUnLock(obj);
			; // yield CPU to improve responsive when deleting large file.
			uffs_ObjectDevLock(obj);

			d_node = uffs_TreeFindDataNode(dev, parent, serial);
			if (uffs_Assert(d_node != NULL, "Can't find DATA node parent = %d, serial = %d\n", parent, serial)) {
				uffs_BreakFromEntry(dev, UFFS_TYPE_DATA, d_node);
				block = d_node->u.data.block;
				uffs_FlashEraseBlock(dev, block);
				d_node->u.list.block = block;
				if (HAVE_BADBLOCK(dev))
					uffs_BadBlockProcess(dev, d_node);
				else
					uffs_TreeInsertToErasedListTail(dev, d_node);
			}
		}
	}
	
	// now process the suspend node
	uffs_TreeRemoveSuspendNode(dev, node);
	if (bad)
		uffs_TreeInsertToBadBlockList(dev, node);
	else
		uffs_TreeInsertToErasedListTail(dev, node);

	ret = U_SUCC;

ext_lock:
	uffs_ObjectDevUnLock(obj);
ext_unlock:
	do_ReleaseObjectResource(obj);

	uffs_PutObject(obj);

	return ret;
}
Example #8
0
/**
 * \brief delete uffs object
 *
 * \param[in] name full name of object
 * \param[out] err return error code
 *
 * \return U_SUCC if object is deleted successfully. 
 *	return U_FAIL if error happen, error code is set to *err.
 */
URET uffs_DeleteObject(const char * name, int *err)
{
	uffs_Object *obj;
	TreeNode *node;
	uffs_Device *dev;
	u16 block;
	uffs_Buf *buf;
	URET ret = U_FAIL;

	obj = uffs_GetObject();
	if (obj == NULL) {
		if (err)
			*err = UEMFILE;
		goto err1;
	}

	if (uffs_OpenObject(obj, name, UO_RDWR|UO_DIR) == U_FAIL) {
		if (uffs_OpenObject(obj, name, UO_RDWR) == U_FAIL) {
			if (err)
				*err = UENOENT;
			goto err1;
		}
	}

	uffs_TruncateObject(obj, 0);

	uffs_ObjectDevLock(obj);
	dev = obj->dev;

	if (obj->type == UFFS_TYPE_DIR) 
	{
		// if the dir is not empty, can't delete it.
		node = uffs_TreeFindDirNodeWithParent(dev, obj->serial);
		if (node != NULL) 
		{
			if (err)
				*err = UEACCES;
			goto err;  //have sub dirs ?
		}

		node = uffs_TreeFindFileNodeWithParent(dev, obj->serial);
		if (node != NULL) 
		{
			if (err)
				*err = UEACCES;
			goto err;  //have sub files ?
		}
	}

	block = GET_BLOCK_FROM_NODE(obj);
	node = obj->node;

	// before erase the block, we need to take care of the buffer ...
	uffs_BufFlushAll(dev);

	if (HAVE_BADBLOCK(dev))
		uffs_BadBlockRecover(dev);

	buf = uffs_BufFind(dev, obj->parent, obj->serial, 0);

	if (buf) {
		//need to expire this buffer ...
		if (buf->ref_count != 0) {
			//there is other obj for this file still in use ?
			uffs_Perror(UFFS_ERR_NORMAL, "Try to delete object but still have buf referenced.");
			if (err)
				*err = UEACCES;
			goto err;
		}

		buf->mark = UFFS_BUF_EMPTY; //!< make this buffer expired.
	}

	//TODO: need to take care of other obj->node ?

	uffs_BreakFromEntry(dev, obj->type, node);
	uffs_FlashEraseBlock(dev, block);
	node->u.list.block = block;
	if (HAVE_BADBLOCK(dev))
		uffs_BadBlockProcess(dev, node);
	else
		uffs_TreeInsertToErasedListTail(dev, node);

	ret = U_SUCC;
err:
	uffs_ObjectDevUnLock(obj);
err1:
	do_ReleaseObjectResource(obj);

	uffs_PutObject(obj);

	return ret;
}
Example #9
0
int dfs_uffs_open(struct dfs_fd* fd)   
{
	if (fd->flags & DFS_O_DIRECTORY)
	{	/* directory */
		uffs_DIR* dirp;
		int oflag = UO_DIR;

		if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE;
		if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY;
		if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY;
		
		if (oflag & UO_CREATE)
		{	/* create directory right now */
			uffs_Object* fp = uffs_GetObject();
			if(fp == NULL) 
			{
				uffs_set_error(-UEMFILE);
				return U_FAIL;
			}
	
			if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC)
			{
				return U_FAIL;
			}
			/* release object hander */
			uffs_PutObject(fp);	
		}

		/* use directory handler */
		dirp = uffs_opendir(fd->path);
		if(dirp == NULL) 
		{
			uffs_set_error(-UEMFILE);
			return U_FAIL;
		}
		fd->data = dirp;

		return U_SUCC;
	}
	else
	{/* file */
		uffs_Object *fp;
		
		int mode = UO_RDONLY;

		if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY;
		if ((fd->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= UO_WRONLY;
		/* Opens the file, if it is existing. If not, a new file is created. */
		if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE;
		/* Creates a new file. If the file is existing, it is truncated and overwritten. */
		if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC;
		/* Creates a new file. The function fails if the file is already existing. */
		if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL;

		/* get an object hander */
		fp = uffs_GetObject();
		if(fp == NULL) 
		{
			uffs_set_error(-UEMFILE);
			return U_FAIL;
		}

		if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC)
		{
			struct uffs_stat stat_buf;

			uffs_stat(fd->path, &stat_buf);

			fd->pos  = fp->pos;
			fd->size = stat_buf.st_size;
			fd->data = fp;

			if(fd->flags & DFS_O_APPEND)
			{
				fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
			}
			return U_SUCC;
		}
		else
		{
			/* open failed, return */
			uffs_set_error(-uffs_GetObjectErr(fp));
			/* release object hander */
			uffs_PutObject(fp);
			return U_FAIL;
		}
	} 
}