fixup for 5c87b6864
Move the logic for determining if we should support split directories into a helper function. This permits compiled outputs that do not utilize this to drop this code easily at the linker level. Additionally, drop the default behavior.
This commit is contained in:
@@ -3190,32 +3190,12 @@ static int lfs_rawstat(lfs_t *lfs, const char *path, struct lfs_info *info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_prep_removal(lfs_t *lfs, struct lfs_mlist *dir,
|
typedef int (*lfs_dir_prep_helper_t)(lfs_t *, struct lfs_mlist *, lfs_gstate_t *);
|
||||||
lfs_mdir_t *newcwd, uint16_t newid, lfs_block_t *pair,
|
|
||||||
lfs_gstate_t *tmp_gstate, bool allow_nonempty_folder)
|
static int lfs_dir_prep_remove_nonempty_folders(lfs_t *lfs, struct lfs_mlist *dir,
|
||||||
|
lfs_gstate_t *tmp_gstate)
|
||||||
{
|
{
|
||||||
lfs_gstate_t split_gstate;
|
lfs_gstate_t split_gstate;
|
||||||
lfs_stag_t res = lfs_dir_get(lfs, newcwd, LFS_MKTAG(0x700, 0x3ff, 0),
|
|
||||||
LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), pair);
|
|
||||||
if (res < 0) {
|
|
||||||
return (int)res;
|
|
||||||
}
|
|
||||||
lfs_pair_fromle32(pair);
|
|
||||||
|
|
||||||
memset(tmp_gstate, 0, sizeof(*tmp_gstate));
|
|
||||||
|
|
||||||
int err = lfs_dir_fetch(lfs, &dir->m, pair);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir->m.count > 0 || dir->m.split) {
|
|
||||||
// Normal POSIX behavior wouldn't allow a non-empty
|
|
||||||
// folder to be removed/renamed into in this manner
|
|
||||||
if (!allow_nonempty_folder) {
|
|
||||||
return LFS_ERR_NOTEMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t id = 0;
|
uint16_t id = 0;
|
||||||
|
|
||||||
// Walk tags stored in this directory and check for any directory
|
// Walk tags stored in this directory and check for any directory
|
||||||
@@ -3236,7 +3216,7 @@ static int lfs_dir_prep_removal(lfs_t *lfs, struct lfs_mlist *dir,
|
|||||||
lfs_dir_getgstate(lfs, &dir->m, &split_gstate);
|
lfs_dir_getgstate(lfs, &dir->m, &split_gstate);
|
||||||
lfs_gstate_xor(tmp_gstate, &split_gstate);
|
lfs_gstate_xor(tmp_gstate, &split_gstate);
|
||||||
|
|
||||||
err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail);
|
int err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -3257,6 +3237,39 @@ static int lfs_dir_prep_removal(lfs_t *lfs, struct lfs_mlist *dir,
|
|||||||
|
|
||||||
id += 1;
|
id += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lfs_dir_prep_removal(lfs_t *lfs, struct lfs_mlist *dir,
|
||||||
|
lfs_mdir_t *newcwd, uint16_t newid, lfs_block_t *pair,
|
||||||
|
lfs_gstate_t *tmp_gstate, lfs_dir_prep_helper_t helper)
|
||||||
|
{
|
||||||
|
lfs_stag_t res = lfs_dir_get(lfs, newcwd, LFS_MKTAG(0x700, 0x3ff, 0),
|
||||||
|
LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), pair);
|
||||||
|
if (res < 0) {
|
||||||
|
return (int)res;
|
||||||
|
}
|
||||||
|
lfs_pair_fromle32(pair);
|
||||||
|
|
||||||
|
memset(tmp_gstate, 0, sizeof(*tmp_gstate));
|
||||||
|
|
||||||
|
int err = lfs_dir_fetch(lfs, &dir->m, pair);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir->m.count > 0 || dir->m.split) {
|
||||||
|
// Normal POSIX behavior wouldn't allow a non-empty
|
||||||
|
// folder to be removed/renamed into in this manner
|
||||||
|
if (NULL == helper) {
|
||||||
|
return LFS_ERR_NOTEMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = helper(lfs, dir, tmp_gstate);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark fs as orphaned
|
// mark fs as orphaned
|
||||||
@@ -3276,7 +3289,7 @@ static int lfs_dir_prep_removal(lfs_t *lfs, struct lfs_mlist *dir,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
static int lfs_rawremove(lfs_t *lfs, const char *path, bool allow_nonempty_folder) {
|
static int lfs_rawremove(lfs_t *lfs, const char *path, lfs_dir_prep_helper_t helper) {
|
||||||
// deorphan if we haven't yet, needed at most once after poweron
|
// deorphan if we haven't yet, needed at most once after poweron
|
||||||
int err = lfs_fs_forceconsistency(lfs);
|
int err = lfs_fs_forceconsistency(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -3296,7 +3309,7 @@ static int lfs_rawremove(lfs_t *lfs, const char *path, bool allow_nonempty_folde
|
|||||||
if (lfs_tag_type3(tag) == LFS_TYPE_DIR) {
|
if (lfs_tag_type3(tag) == LFS_TYPE_DIR) {
|
||||||
// must be empty before removal to prevent orphans
|
// must be empty before removal to prevent orphans
|
||||||
err = lfs_dir_prep_removal(lfs, &dir, &cwd, lfs_tag_id(tag),
|
err = lfs_dir_prep_removal(lfs, &dir, &cwd, lfs_tag_id(tag),
|
||||||
pair, &tmp_gstate, allow_nonempty_folder);
|
pair, &tmp_gstate, helper);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -3339,7 +3352,7 @@ static int lfs_rawremove(lfs_t *lfs, const char *path, bool allow_nonempty_folde
|
|||||||
|
|
||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
static int lfs_rawrename(lfs_t *lfs, const char *oldpath,
|
static int lfs_rawrename(lfs_t *lfs, const char *oldpath,
|
||||||
const char *newpath, bool allow_nonempty_folder) {
|
const char *newpath, lfs_dir_prep_helper_t helper) {
|
||||||
// deorphan if we haven't yet, needed at most once after poweron
|
// deorphan if we haven't yet, needed at most once after poweron
|
||||||
int err = lfs_fs_forceconsistency(lfs);
|
int err = lfs_fs_forceconsistency(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -3391,7 +3404,7 @@ static int lfs_rawrename(lfs_t *lfs, const char *oldpath,
|
|||||||
} else if (lfs_tag_type3(prevtag) == LFS_TYPE_DIR) {
|
} else if (lfs_tag_type3(prevtag) == LFS_TYPE_DIR) {
|
||||||
// must be empty before removal to prevent orphans
|
// must be empty before removal to prevent orphans
|
||||||
err = lfs_dir_prep_removal(lfs, &prevdir, &newcwd, newid,
|
err = lfs_dir_prep_removal(lfs, &prevdir, &newcwd, newid,
|
||||||
dir_pair, &tmp_gstate, allow_nonempty_folder);
|
dir_pair, &tmp_gstate, helper);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -5046,7 +5059,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||||||
}
|
}
|
||||||
LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path);
|
LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path);
|
||||||
|
|
||||||
err = lfs_rawremove(lfs, path, false);
|
err = lfs_rawremove(lfs, path, NULL);
|
||||||
|
|
||||||
LFS_TRACE("lfs_remove -> %d", err);
|
LFS_TRACE("lfs_remove -> %d", err);
|
||||||
LFS_UNLOCK(lfs->cfg);
|
LFS_UNLOCK(lfs->cfg);
|
||||||
@@ -5062,7 +5075,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
}
|
}
|
||||||
LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath);
|
LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath);
|
||||||
|
|
||||||
err = lfs_rawrename(lfs, oldpath, newpath);
|
err = lfs_rawrename(lfs, oldpath, newpath, NULL);
|
||||||
|
|
||||||
LFS_TRACE("lfs_rename -> %d", err);
|
LFS_TRACE("lfs_rename -> %d", err);
|
||||||
LFS_UNLOCK(lfs->cfg);
|
LFS_UNLOCK(lfs->cfg);
|
||||||
|
|||||||
Reference in New Issue
Block a user