Skip to content

Commit e20482a

Browse files
Remove/rename: Create a common structure for some of the data manipulated
This is in preparation of the next commit for it to be able to consolidate some of the logic between the two functions.
1 parent 0494ce7 commit e20482a

File tree

1 file changed

+66
-54
lines changed

1 file changed

+66
-54
lines changed

lfs.c

Lines changed: 66 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3877,6 +3877,23 @@ static int lfs_stat_(lfs_t *lfs, const char *path, struct lfs_info *info) {
38773877
return lfs_dir_getinfo(lfs, &cwd, lfs_tag_id(tag), info);
38783878
}
38793879

3880+
#ifndef LFS_READONLY
3881+
struct lfs_remove_state
3882+
{
3883+
// File to be removed pointer (cwd and tag)
3884+
lfs_mdir_t cwd;
3885+
lfs_stag_t tag;
3886+
3887+
// Directory that needs to be removed from linked list pointer
3888+
struct lfs_mlist dir;
3889+
3890+
// First block-pair in the directory to be removed; this gets
3891+
// destroyed in lfs_mlist below as it traverses the splits in
3892+
// the directory.
3893+
lfs_block_t dir_head[2];
3894+
};
3895+
#endif
3896+
38803897
#ifndef LFS_READONLY
38813898
static int lfs_remove_(lfs_t *lfs, const char *path) {
38823899
// deorphan if we haven't yet, needed at most once after poweron
@@ -3885,30 +3902,28 @@ static int lfs_remove_(lfs_t *lfs, const char *path) {
38853902
return err;
38863903
}
38873904

3888-
lfs_mdir_t cwd;
3889-
lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
3890-
if (tag < 0 || lfs_tag_id(tag) == 0x3ff) {
3891-
return (tag < 0) ? (int)tag : LFS_ERR_INVAL;
3905+
struct lfs_remove_state s;
3906+
s.tag = lfs_dir_find(lfs, &s.cwd, &path, NULL);
3907+
if (s.tag < 0 || lfs_tag_id(s.tag) == 0x3ff) {
3908+
return (s.tag < 0) ? (int)s.tag : LFS_ERR_INVAL;
38923909
}
38933910

3894-
struct lfs_mlist dir;
3895-
dir.next = lfs->mlist;
3896-
if (lfs_tag_type3(tag) == LFS_TYPE_DIR) {
3911+
s.dir.next = lfs->mlist;
3912+
if (lfs_tag_type3(s.tag) == LFS_TYPE_DIR) {
38973913
// must be empty before removal
3898-
lfs_block_t pair[2];
3899-
lfs_stag_t res = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x700, 0x3ff, 0),
3900-
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair);
3914+
lfs_stag_t res = lfs_dir_get(lfs, &s.cwd, LFS_MKTAG(0x700, 0x3ff, 0),
3915+
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(s.tag), 8), s.dir_head);
39013916
if (res < 0) {
39023917
return (int)res;
39033918
}
3904-
lfs_pair_fromle32(pair);
3919+
lfs_pair_fromle32(s.dir_head);
39053920

3906-
err = lfs_dir_fetch(lfs, &dir.m, pair);
3921+
err = lfs_dir_fetch(lfs, &s.dir.m, s.dir_head);
39073922
if (err) {
39083923
return err;
39093924
}
39103925

3911-
if (dir.m.count > 0 || dir.m.split) {
3926+
if (s.dir.m.count > 0 || s.dir.m.split) {
39123927
return LFS_ERR_NOTEMPTY;
39133928
}
39143929

@@ -3920,33 +3935,33 @@ static int lfs_remove_(lfs_t *lfs, const char *path) {
39203935

39213936
// I know it's crazy but yes, dir can be changed by our parent's
39223937
// commit (if predecessor is child)
3923-
dir.type = 0;
3924-
dir.id = 0;
3925-
lfs->mlist = &dir;
3938+
s.dir.type = 0;
3939+
s.dir.id = 0;
3940+
lfs->mlist = &s.dir;
39263941
}
39273942

39283943
// delete the entry
3929-
err = lfs_dir_commit(lfs, &cwd, LFS_MKATTRS(
3930-
{LFS_MKTAG(LFS_TYPE_DELETE, lfs_tag_id(tag), 0), NULL}));
3944+
err = lfs_dir_commit(lfs, &s.cwd, LFS_MKATTRS(
3945+
{LFS_MKTAG(LFS_TYPE_DELETE, lfs_tag_id(s.tag), 0), NULL}));
39313946
if (err) {
3932-
lfs->mlist = dir.next;
3947+
lfs->mlist = s.dir.next;
39333948
return err;
39343949
}
39353950

3936-
lfs->mlist = dir.next;
3937-
if (lfs_tag_type3(tag) == LFS_TYPE_DIR) {
3951+
lfs->mlist = s.dir.next;
3952+
if (lfs_tag_type3(s.tag) == LFS_TYPE_DIR) {
39383953
// fix orphan
39393954
err = lfs_fs_preporphans(lfs, -1);
39403955
if (err) {
39413956
return err;
39423957
}
39433958

3944-
err = lfs_fs_pred(lfs, dir.m.pair, &cwd);
3959+
err = lfs_fs_pred(lfs, s.dir.m.pair, &s.cwd);
39453960
if (err) {
39463961
return err;
39473962
}
39483963

3949-
err = lfs_dir_drop(lfs, &cwd, &dir.m);
3964+
err = lfs_dir_drop(lfs, &s.cwd, &s.dir.m);
39503965
if (err) {
39513966
return err;
39523967
}
@@ -3972,21 +3987,20 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
39723987
}
39733988

39743989
// find new entry
3975-
lfs_mdir_t newcwd;
3990+
struct lfs_remove_state n;
39763991
uint16_t newid;
3977-
lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid);
3978-
if ((prevtag < 0 || lfs_tag_id(prevtag) == 0x3ff) &&
3979-
!(prevtag == LFS_ERR_NOENT && lfs_path_islast(newpath))) {
3980-
return (prevtag < 0) ? (int)prevtag : LFS_ERR_INVAL;
3992+
n.tag = lfs_dir_find(lfs, &n.cwd, &newpath, &newid);
3993+
if ((n.tag < 0 || lfs_tag_id(n.tag) == 0x3ff) &&
3994+
!(n.tag == LFS_ERR_NOENT && lfs_path_islast(newpath))) {
3995+
return (n.tag < 0) ? (int)n.tag : LFS_ERR_INVAL;
39813996
}
39823997

39833998
// if we're in the same pair there's a few special cases...
3984-
bool samepair = (lfs_pair_cmp(oldcwd.pair, newcwd.pair) == 0);
3999+
bool samepair = (lfs_pair_cmp(oldcwd.pair, n.cwd.pair) == 0);
39854000
uint16_t newoldid = lfs_tag_id(oldtag);
39864001

3987-
struct lfs_mlist prevdir;
3988-
prevdir.next = lfs->mlist;
3989-
if (prevtag == LFS_ERR_NOENT) {
4002+
n.dir.next = lfs->mlist;
4003+
if (n.tag == LFS_ERR_NOENT) {
39904004
// if we're a file, don't allow trailing slashes
39914005
if (lfs_path_isdir(newpath)
39924006
&& lfs_tag_type3(oldtag) != LFS_TYPE_DIR) {
@@ -4005,30 +4019,28 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40054019
if (samepair && newid <= newoldid) {
40064020
newoldid += 1;
40074021
}
4008-
} else if (lfs_tag_type3(prevtag) != lfs_tag_type3(oldtag)) {
4009-
return (lfs_tag_type3(prevtag) == LFS_TYPE_DIR)
4022+
} else if (lfs_tag_type3(n.tag) != lfs_tag_type3(oldtag)) {
4023+
return (lfs_tag_type3(n.tag) == LFS_TYPE_DIR)
40104024
? LFS_ERR_ISDIR
40114025
: LFS_ERR_NOTDIR;
40124026
} else if (samepair && newid == newoldid) {
40134027
// we're renaming to ourselves??
40144028
return 0;
4015-
} else if (lfs_tag_type3(prevtag) == LFS_TYPE_DIR) {
4016-
// must be empty before removal
4017-
lfs_block_t prevpair[2];
4018-
lfs_stag_t res = lfs_dir_get(lfs, &newcwd, LFS_MKTAG(0x700, 0x3ff, 0),
4019-
LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair);
4029+
} else if (lfs_tag_type3(n.tag) == LFS_TYPE_DIR) {
4030+
lfs_stag_t res = lfs_dir_get(lfs, &n.cwd, LFS_MKTAG(0x700, 0x3ff, 0),
4031+
LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), n.dir_head);
40204032
if (res < 0) {
40214033
return (int)res;
40224034
}
4023-
lfs_pair_fromle32(prevpair);
4035+
lfs_pair_fromle32(n.dir_head);
40244036

40254037
// must be empty before removal
4026-
err = lfs_dir_fetch(lfs, &prevdir.m, prevpair);
4038+
err = lfs_dir_fetch(lfs, &n.dir.m, n.dir_head);
40274039
if (err) {
40284040
return err;
40294041
}
40304042

4031-
if (prevdir.m.count > 0 || prevdir.m.split) {
4043+
if (n.dir.m.count > 0 || n.dir.m.split) {
40324044
return LFS_ERR_NOTEMPTY;
40334045
}
40344046

@@ -4040,18 +4052,18 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40404052

40414053
// I know it's crazy but yes, dir can be changed by our parent's
40424054
// commit (if predecessor is child)
4043-
prevdir.type = 0;
4044-
prevdir.id = 0;
4045-
lfs->mlist = &prevdir;
4055+
n.dir.type = 0;
4056+
n.dir.id = 0;
4057+
lfs->mlist = &n.dir;
40464058
}
40474059

40484060
if (!samepair) {
40494061
lfs_fs_prepmove(lfs, newoldid, oldcwd.pair);
40504062
}
40514063

40524064
// move over all attributes
4053-
err = lfs_dir_commit(lfs, &newcwd, LFS_MKATTRS(
4054-
{LFS_MKTAG_IF(prevtag != LFS_ERR_NOENT,
4065+
err = lfs_dir_commit(lfs, &n.cwd, LFS_MKATTRS(
4066+
{LFS_MKTAG_IF(n.tag != LFS_ERR_NOENT,
40554067
LFS_TYPE_DELETE, newid, 0), NULL},
40564068
{LFS_MKTAG(LFS_TYPE_CREATE, newid, 0), NULL},
40574069
{LFS_MKTAG(lfs_tag_type3(oldtag),
@@ -4060,7 +4072,7 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40604072
{LFS_MKTAG_IF(samepair,
40614073
LFS_TYPE_DELETE, newoldid, 0), NULL}));
40624074
if (err) {
4063-
lfs->mlist = prevdir.next;
4075+
lfs->mlist = n.dir.next;
40644076
return err;
40654077
}
40664078

@@ -4072,26 +4084,26 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40724084
err = lfs_dir_commit(lfs, &oldcwd, LFS_MKATTRS(
40734085
{LFS_MKTAG(LFS_TYPE_DELETE, lfs_tag_id(oldtag), 0), NULL}));
40744086
if (err) {
4075-
lfs->mlist = prevdir.next;
4087+
lfs->mlist = n.dir.next;
40764088
return err;
40774089
}
40784090
}
40794091

4080-
lfs->mlist = prevdir.next;
4081-
if (prevtag != LFS_ERR_NOENT
4082-
&& lfs_tag_type3(prevtag) == LFS_TYPE_DIR) {
4092+
lfs->mlist = n.dir.next;
4093+
if (n.tag != LFS_ERR_NOENT
4094+
&& lfs_tag_type3(n.tag) == LFS_TYPE_DIR) {
40834095
// fix orphan
40844096
err = lfs_fs_preporphans(lfs, -1);
40854097
if (err) {
40864098
return err;
40874099
}
40884100

4089-
err = lfs_fs_pred(lfs, prevdir.m.pair, &newcwd);
4101+
err = lfs_fs_pred(lfs, n.dir.m.pair, &n.cwd);
40904102
if (err) {
40914103
return err;
40924104
}
40934105

4094-
err = lfs_dir_drop(lfs, &newcwd, &prevdir.m);
4106+
err = lfs_dir_drop(lfs, &n.cwd, &n.dir.m);
40954107
if (err) {
40964108
return err;
40974109
}

0 commit comments

Comments
 (0)