Skip to content

Commit 850f63c

Browse files
Consolidate some of the logic for removals of folders
This routine checks that the folder is empty before removing and is found in two places. We can consolidate this for changes to the logic.
1 parent e20482a commit 850f63c

File tree

1 file changed

+62
-75
lines changed

1 file changed

+62
-75
lines changed

lfs.c

Lines changed: 62 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3894,6 +3894,63 @@ struct lfs_remove_state
38943894
};
38953895
#endif
38963896

3897+
#ifndef LFS_READONLY
3898+
static int lfs_dir_prep_removal(lfs_t *lfs, struct lfs_remove_state *p) {
3899+
lfs_stag_t res = lfs_dir_get(lfs, &p->cwd, LFS_MKTAG(0x700, 0x3ff, 0),
3900+
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(p->tag), 8), p->dir_head);
3901+
if (res < 0) {
3902+
return (int)res;
3903+
}
3904+
lfs_pair_fromle32(p->dir_head);
3905+
3906+
int err = lfs_dir_fetch(lfs, &p->dir.m, p->dir_head);
3907+
if (err) {
3908+
return err;
3909+
}
3910+
3911+
if (p->dir.m.count > 0 || p->dir.m.split) {
3912+
return LFS_ERR_NOTEMPTY;
3913+
}
3914+
3915+
// mark fs as orphaned
3916+
err = lfs_fs_preporphans(lfs, +1);
3917+
if (err) {
3918+
return err;
3919+
}
3920+
3921+
// I know it's crazy but yes, dir can be changed by our parent's
3922+
// commit (if predecessor is child)
3923+
p->dir.type = 0;
3924+
p->dir.id = 0;
3925+
lfs->mlist = &p->dir;
3926+
3927+
return 0;
3928+
}
3929+
#endif
3930+
3931+
#ifndef LFS_READONLY
3932+
static int lfs_dir_finish_removal(lfs_t *lfs, struct lfs_remove_state *p)
3933+
{
3934+
// fix orphan
3935+
int err = lfs_fs_preporphans(lfs, -1);
3936+
if (err) {
3937+
return err;
3938+
}
3939+
3940+
err = lfs_fs_pred(lfs, p->dir.m.pair, &p->cwd);
3941+
if (err) {
3942+
return err;
3943+
}
3944+
3945+
err = lfs_dir_drop(lfs, &p->cwd, &p->dir.m);
3946+
if (err) {
3947+
return err;
3948+
}
3949+
3950+
return 0;
3951+
}
3952+
#endif
3953+
38973954
#ifndef LFS_READONLY
38983955
static int lfs_remove_(lfs_t *lfs, const char *path) {
38993956
// deorphan if we haven't yet, needed at most once after poweron
@@ -3910,34 +3967,10 @@ static int lfs_remove_(lfs_t *lfs, const char *path) {
39103967

39113968
s.dir.next = lfs->mlist;
39123969
if (lfs_tag_type3(s.tag) == LFS_TYPE_DIR) {
3913-
// must be empty before removal
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);
3916-
if (res < 0) {
3917-
return (int)res;
3918-
}
3919-
lfs_pair_fromle32(s.dir_head);
3920-
3921-
err = lfs_dir_fetch(lfs, &s.dir.m, s.dir_head);
3922-
if (err) {
3923-
return err;
3924-
}
3925-
3926-
if (s.dir.m.count > 0 || s.dir.m.split) {
3927-
return LFS_ERR_NOTEMPTY;
3928-
}
3929-
3930-
// mark fs as orphaned
3931-
err = lfs_fs_preporphans(lfs, +1);
3932-
if (err) {
3970+
err = lfs_dir_prep_removal(lfs, &s);
3971+
if (err < 0) {
39333972
return err;
39343973
}
3935-
3936-
// I know it's crazy but yes, dir can be changed by our parent's
3937-
// commit (if predecessor is child)
3938-
s.dir.type = 0;
3939-
s.dir.id = 0;
3940-
lfs->mlist = &s.dir;
39413974
}
39423975

39433976
// delete the entry
@@ -3950,18 +3983,7 @@ static int lfs_remove_(lfs_t *lfs, const char *path) {
39503983

39513984
lfs->mlist = s.dir.next;
39523985
if (lfs_tag_type3(s.tag) == LFS_TYPE_DIR) {
3953-
// fix orphan
3954-
err = lfs_fs_preporphans(lfs, -1);
3955-
if (err) {
3956-
return err;
3957-
}
3958-
3959-
err = lfs_fs_pred(lfs, s.dir.m.pair, &s.cwd);
3960-
if (err) {
3961-
return err;
3962-
}
3963-
3964-
err = lfs_dir_drop(lfs, &s.cwd, &s.dir.m);
3986+
err = lfs_dir_finish_removal(lfs, &s);
39653987
if (err) {
39663988
return err;
39673989
}
@@ -4027,34 +4049,10 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40274049
// we're renaming to ourselves??
40284050
return 0;
40294051
} 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);
4032-
if (res < 0) {
4033-
return (int)res;
4034-
}
4035-
lfs_pair_fromle32(n.dir_head);
4036-
4037-
// must be empty before removal
4038-
err = lfs_dir_fetch(lfs, &n.dir.m, n.dir_head);
4039-
if (err) {
4040-
return err;
4041-
}
4042-
4043-
if (n.dir.m.count > 0 || n.dir.m.split) {
4044-
return LFS_ERR_NOTEMPTY;
4045-
}
4046-
4047-
// mark fs as orphaned
4048-
err = lfs_fs_preporphans(lfs, +1);
4052+
err = lfs_dir_prep_removal(lfs, &n);
40494053
if (err) {
40504054
return err;
40514055
}
4052-
4053-
// I know it's crazy but yes, dir can be changed by our parent's
4054-
// commit (if predecessor is child)
4055-
n.dir.type = 0;
4056-
n.dir.id = 0;
4057-
lfs->mlist = &n.dir;
40584056
}
40594057

40604058
if (!samepair) {
@@ -4092,18 +4090,7 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40924090
lfs->mlist = n.dir.next;
40934091
if (n.tag != LFS_ERR_NOENT
40944092
&& lfs_tag_type3(n.tag) == LFS_TYPE_DIR) {
4095-
// fix orphan
4096-
err = lfs_fs_preporphans(lfs, -1);
4097-
if (err) {
4098-
return err;
4099-
}
4100-
4101-
err = lfs_fs_pred(lfs, n.dir.m.pair, &n.cwd);
4102-
if (err) {
4103-
return err;
4104-
}
4105-
4106-
err = lfs_dir_drop(lfs, &n.cwd, &n.dir.m);
4093+
err = lfs_dir_finish_removal(lfs, &n);
41074094
if (err) {
41084095
return err;
41094096
}

0 commit comments

Comments
 (0)