📄 ffs.c
字号:
return EFFS_OK;
// TASKEND
}
effs_t ffs_remove(const char *pathname)
{
FFS_BLOCKING_CALL_BEGIN();
result = ffs_remove_b(pathname, 0, &fb);
FFS_BLOCKING_CALL_END();
return result;
}
req_id_t ffs_remove_nb(const char *pathname, T_RV_RETURN *cp)
{
return ffs_remove_b(pathname, cp, 0);
}
req_id_t ffs_fcontrol_b(const char *pathname, int8 action, int param,
T_RV_RETURN *cp, struct ffs_blocking_s *fb)
{
iref_t i;
tw(tr(TR_FUNC, TrApi, "ffs_fcontrol('%s', %d, 0x%x) ?\n",
pathname, action, param));
ttw(ttr(TTrApi, "ffs_fcontrol('%s', %d, 0x%x) ?" NL,
pathname, action, param));
// TASKBEGIN effs_t FCONTROL(path=pathname, value16=action, size=param) iref_t i;
if (fs.initerror)
return fs.initerror;
if (pathname == NULL)
return EFFS_BADNAME;
if ((i = ffs_strcmp(pathname, "/dev/ffs")) != 0)
{
if ((i = object_lookup_once(pathname, 0, 0)) < 0)
return i;
if ((i = is_readonly(i, pathname)) < 0)
return i;
}
if ((i = object_control(i, action, param)) < 0)
return i;
tw(tr_bstat());
return EFFS_OK;
// TASKEND
}
effs_t ffs_fcontrol(const char *pathname, int8 action, int param)
{
FFS_BLOCKING_CALL_BEGIN();
result = ffs_fcontrol_b(pathname, action, param, 0, &fb);
FFS_BLOCKING_CALL_END();
return result;
}
req_id_t ffs_fcontrol_nb(const char *pathname, int8 action, int param,
T_RV_RETURN *cp)
{
return ffs_fcontrol_b(pathname, action, param, cp, 0);
}
req_id_t ffs_rename_b(const char *pathname, const char *newname,
T_RV_RETURN *cp, struct ffs_blocking_s *fb)
{
iref_t i, oldi, dir;
char *name;
struct inode_s *ip;
tw(tr(TR_FUNC, TrApi, "ffs_rename('%s', '%s') ?\n", pathname, newname));
ttw(ttr(TTrApi, "ffs_rename('%s', '%s') ?" NL, pathname, newname));
// TASKBEGIN effs_t RENAME(path=pathname, src=newname) iref_t i, oldi, dir; char *name; struct inode_s *ip;
if (fs.initerror)
return fs.initerror;
// pathname MUST exist, not be open and MUST be writable
if ((oldi = object_lookup_once(pathname, 0, 0)) < 0)
return oldi;
if ((oldi = is_readonly(oldi, pathname)) < 0)
return oldi;
if (get_fdi(oldi) >= 0)
return EFFS_LOCKED;
journal_begin(oldi);
if ((i = object_lookup_once(newname, &name, &dir)) < 0) {
if (i != EFFS_NOTFOUND)
return i;
}
else { // newname obj exist
ip = inode_addr(oldi);
if (is_object(ip, OT_FILE)) { // is old obj a file?
if ((i = is_readonly(i, newname)) < 0)
return i;
ip = inode_addr(i);
if (!is_object(ip, OT_FILE)) // newname MUST be a file
return EFFS_NOTAFILE;
fs.journal.repli = i;
}
else
return EFFS_EXISTS;
}
if ((i = object_rename(oldi, name, -dir)) < 0)
return i;
journal_end(0);
tw(tr_bstat());
return EFFS_OK;
// TASKEND
}
effs_t ffs_rename(const char *pathname, const char *newname)
{
FFS_BLOCKING_CALL_BEGIN();
result = ffs_rename_b(pathname, newname, 0, &fb);
FFS_BLOCKING_CALL_END();
return result;
}
req_id_t ffs_rename_nb(const char *pathname, const char *newname,
T_RV_RETURN *cp)
{
return ffs_rename_b(pathname, newname, cp, 0);
}
/******************************************************************************
* Directory Operations
******************************************************************************/
// All directory operations are more or less similar to unix
// semantics.
req_id_t ffs_mkdir_b(const char *pathname, T_RV_RETURN *cp,
struct ffs_blocking_s *fb)
{
iref_t i, dir;
char *name;
tw(tr(TR_FUNC, TrApi, "ffs_mkdir('%s')\n", pathname));
ttw(ttr(TTrApi, "ffs_mkdir('%s') ?" NL, pathname));
// TASKBEGIN effs_t MKDIR(path=pathname) iref_t i, dir; char *name;
if (fs.initerror)
return fs.initerror;
i = object_lookup(pathname, &name, &dir);
if (i > 0)
return EFFS_EXISTS;
if (i != EFFS_NOTFOUND)
return i;
journal_begin(0);
if ((i = object_create(name, 0, 0, -dir)) < 0)
return i;
journal_end(OT_DIR);
tw(tr_bstat());
return EFFS_OK;
// TASKEND
}
effs_t ffs_mkdir(const char *pathname)
{
FFS_BLOCKING_CALL_BEGIN();
result = ffs_mkdir_b(pathname, 0, &fb);
FFS_BLOCKING_CALL_END();
return result;
}
req_id_t ffs_mkdir_nb(const char *pathname, T_RV_RETURN *cp)
{
return ffs_mkdir_b(pathname, cp, 0);
}
int ffs_opendir(const char *name, struct dir_s *dir)
{
int i;
tw(tr(TR_FUNC, TrApi, "ffs_opendir('%s', ?)\n", name));
ttw(ttr(TTrApi, "ffs_opendir('%s', ?) ?" NL, name));
if (dir == NULL)
return EFFS_INVALID;
if ((i = ffs_begin()) == EFFS_OK)
{
if ((i = dir_open(name)) >= 0)
{
dir->this = i;
dir->index = i;
// Now count the number of entries in the directory
dir_traverse(-i, (iref_t *) &i);
}
}
return ffs_end(i);
}
int ffs_readdir(struct dir_s *dir, char *name, int size)
{
iref_t i;
tw(tr(TR_BEGIN, TrApi, "ffs_readdir(?, ?, ?) {\n"));
ttw(ttr(TTrApi, "ffs_readdir(?, ?, ?) ?" NL));
if (dir == NULL || name == NULL || size < 0) {
tw(tr(TR_END, TrApi, "} %d\n", EFFS_INVALID));
return EFFS_INVALID;
}
if ((i = ffs_begin()) == EFFS_OK)
{
if ((i = dir_next(dir->this, dir->index, name, size)))
dir->index = i;
}
tw(tr(TR_END, TrApi, "} ('%s') %d\n", name, i));
return ffs_end(i);
}
/******************************************************************************
* Preformat and Format
******************************************************************************/
// Note that we do NOT call ffs_begin() because it will just return
// EFFS_NOFORMAT!
req_id_t ffs_format_b(const char *name, uint16 magic, T_RV_RETURN *cp,
struct ffs_blocking_s *fb)
{
effs_t i;
tw(tr(TR_BEGIN, TrApi, "ffs_format('%s', 0x%x) {\n", name, magic));
ttw(ttr(TTrApi, "ffs_format('%s', 0x%x) ?" NL, name, magic));
// TASKBEGIN effs_t FORMAT(path=name, size=magic) iref_t i;
if (magic != 0x2BAD) {
tw(tr(TR_END, TrApi, "} %d\n", EFFS_INVALID));
return EFFS_INVALID;
}
if (name == NULL) {
// The following line is automatically expanded by the revision control
// system to make a default drive label.
//$Format: "name = \"/ffs-$ProjectMajorVersion$.$ProjectMinorVersion$\";"$
name = "/ffs-5.53";
}
if (*name != '/') {
tw(tr(TR_END, TrApi, "} %d\n", EFFS_BADNAME));
return EFFS_BADNAME;
}
if ((i = is_formattable(1)) < 0) {
tw(tr(TR_END, TrApi, "} %d\n", i));
return i;
}
if ((i = fs_format(name)) < 0)
return i;
tw(tr(TR_END, TrApi, "} %d\n", i));
tw(tr_bstat());
return EFFS_OK;
// TASKEND
}
effs_t ffs_format(const char *name, uint16 magic)
{
FFS_BLOCKING_CALL_BEGIN();
result = ffs_format_b(name, magic, 0, &fb);
FFS_BLOCKING_CALL_END();
return result;
}
req_id_t ffs_format_nb(const char *name, uint16 magic, T_RV_RETURN *cp)
{
return ffs_format_b(name, magic, cp, 0);
}
req_id_t ffs_preformat_b(uint16 magic, T_RV_RETURN *cp,
struct ffs_blocking_s *fb)
{
effs_t i;
tw(tr(TR_BEGIN, TrApi, "ffs_preformat(0x%x) {\n", magic));
ttw(ttr(TTrApi, "ffs_preformat(0x%x) ?" NL, magic));
// TASKBEGIN effs_t PREFORMAT(path="/", size=magic) effs_t i;
if (magic != 0xDEAD) {
tw(tr(TR_END, TrApi, "} %d\n", EFFS_INVALID));
return EFFS_INVALID;
}
if (!ffs_is_modifiable("")) {
tw(tr(TR_END, TrApi, "} %d\n", EFFS_ACCESS));
return EFFS_ACCESS;
}
if ((i = is_formattable(0)) < 0) {
tw(tr(TR_END, TrApi, "} %d\n", i));
return i;
}
if ((i = fs_preformat()) < 0)
return i;
tw(tr(TR_END, TrApi, "} %d\n", i));
tw(tr_bstat());
return EFFS_OK;
// TASKEND
}
effs_t ffs_preformat(uint16 magic)
{
FFS_BLOCKING_CALL_BEGIN();
result = ffs_preformat_b(magic, 0, &fb);
FFS_BLOCKING_CALL_END();
return result;
}
req_id_t ffs_preformat_nb(uint16 magic, T_RV_RETURN *cp)
{
return ffs_preformat_b(magic, cp, 0);
}
/******************************************************************************
* Open, Read, Write, Close
******************************************************************************/
req_id_t ffs_open_b(const char *pathname, ffs_options_t option,
T_RV_RETURN *cp, struct ffs_blocking_s *fb)
{
iref_t i, dir, dummy;
char *name;
fd_t other_fdi, fdi = 0;
int error;
struct inode_s *ip;
tw(tr(TR_FUNC, TrApi, "ffs_open('%s', 0x%x) ?\n", pathname, option));
ttw(ttr(TTrApi, "ffs_open('%s', 0x%x) ?" NL, pathname, option));
// TASKBEGIN fd_t OPEN(path=pathname, value16=option) iref_t i, dir, dummy; char *name; fd_t other_fdi, fdi = 0; int error; struct inode_s *ip;
if (fs.initerror)
return fs.initerror;
// Minimum one of the flags RD or WR must be specifyed
if (!is_open_option(option, FFS_O_RDONLY) &&
!is_open_option(option, FFS_O_WRONLY))
return EFFS_INVALID;
// RDONLY must not be combined with any other options if not together
// with WR!
if (is_open_option(option, FFS_O_RDONLY) &&
!is_open_option(option, FFS_O_WRONLY))
if (!(option == FFS_O_RDONLY))
return EFFS_INVALID;
for (fdi = 0; fdi < fs.fd_max; fdi++) { // Find free fd
if (fs.fd[fdi].options == 0) {
break;
}
}
if (fdi >= fs.fd_max)
return EFFS_NUMFD; // Too many open files in system
i = object_lookup(pathname, &name, &dir);
if (i < 0 && i != EFFS_NOTFOUND)
return i;
// Open one file several times in RD is okay but only one time in WR
if (i != EFFS_NOTFOUND && (other_fdi = get_fdi(i)) >= 0) {
if (is_open_option(fs.fd[other_fdi].options, FFS_O_WRONLY) ||
is_open_option(option, FFS_O_WRONLY))
return EFFS_LOCKED;
}
// Init default values
fs.fd[fdi].fp = fs.fd[fdi].size = fs.fd[fdi].wfp = fs.fd[fdi].dirty = 0;
if (i == EFFS_NOTFOUND) {
if (is_open_option(option, (FFS_O_CREATE | FFS_O_WRONLY))) {
if ((error = is_filename(name)) < 0)
return error;
// Create segmenthead
journal_begin(0);
if ((i = object_create(name, 0, 0, -dir)) < 0)
return i;
journal_end(OT_FILE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -