@@ -888,7 +888,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
888
888
}
889
889
890
890
// check that entry has not been moved
891
- if (entry -> d .type & 0x80 ) {
891
+ if (! lfs -> moving && entry -> d .type & 0x80 ) {
892
892
int moved = lfs_moved (lfs , & entry -> d .u );
893
893
if (moved < 0 || moved ) {
894
894
return (moved < 0 ) ? moved : LFS_ERR_NOENT ;
@@ -1644,6 +1644,11 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
1644
1644
file -> pos = file -> size ;
1645
1645
}
1646
1646
1647
+ if (file -> pos + size > LFS_FILE_MAX ) {
1648
+ // larger than file limit?
1649
+ return LFS_ERR_FBIG ;
1650
+ }
1651
+
1647
1652
if (!(file -> flags & LFS_F_WRITING ) && file -> pos > file -> size ) {
1648
1653
// fill with zeros
1649
1654
lfs_off_t pos = file -> pos ;
@@ -1730,24 +1735,24 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
1730
1735
return err ;
1731
1736
}
1732
1737
1733
- // update pos
1738
+ // find new pos
1739
+ lfs_soff_t npos = file -> pos ;
1734
1740
if (whence == LFS_SEEK_SET ) {
1735
- file -> pos = off ;
1741
+ npos = off ;
1736
1742
} else if (whence == LFS_SEEK_CUR ) {
1737
- if (off < 0 && (lfs_off_t )- off > file -> pos ) {
1738
- return LFS_ERR_INVAL ;
1739
- }
1740
-
1741
- file -> pos = file -> pos + off ;
1743
+ npos = file -> pos + off ;
1742
1744
} else if (whence == LFS_SEEK_END ) {
1743
- if (off < 0 && (lfs_off_t )- off > file -> size ) {
1744
- return LFS_ERR_INVAL ;
1745
- }
1745
+ npos = file -> size + off ;
1746
+ }
1746
1747
1747
- file -> pos = file -> size + off ;
1748
+ if (npos < 0 || npos > LFS_FILE_MAX ) {
1749
+ // file position out of range
1750
+ return LFS_ERR_INVAL ;
1748
1751
}
1749
1752
1750
- return file -> pos ;
1753
+ // update pos
1754
+ file -> pos = npos ;
1755
+ return npos ;
1751
1756
}
1752
1757
1753
1758
int lfs_file_truncate (lfs_t * lfs , lfs_file_t * file , lfs_off_t size ) {
@@ -1924,7 +1929,14 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
1924
1929
// find old entry
1925
1930
lfs_dir_t oldcwd ;
1926
1931
lfs_entry_t oldentry ;
1927
- int err = lfs_dir_find (lfs , & oldcwd , & oldentry , & oldpath );
1932
+ int err = lfs_dir_find (lfs , & oldcwd , & oldentry , & (const char * ){oldpath });
1933
+ if (err ) {
1934
+ return err ;
1935
+ }
1936
+
1937
+ // mark as moving
1938
+ oldentry .d .type |= 0x80 ;
1939
+ err = lfs_dir_update (lfs , & oldcwd , & oldentry , NULL );
1928
1940
if (err ) {
1929
1941
return err ;
1930
1942
}
@@ -1937,11 +1949,9 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
1937
1949
return err ;
1938
1950
}
1939
1951
1940
- bool prevexists = (err != LFS_ERR_NOENT );
1941
- bool samepair = (lfs_paircmp (oldcwd .pair , newcwd .pair ) == 0 );
1942
-
1943
1952
// must have same type
1944
- if (prevexists && preventry .d .type != oldentry .d .type ) {
1953
+ bool prevexists = (err != LFS_ERR_NOENT );
1954
+ if (prevexists && preventry .d .type != (0x7f & oldentry .d .type )) {
1945
1955
return LFS_ERR_ISDIR ;
1946
1956
}
1947
1957
@@ -1953,21 +1963,9 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
1953
1963
err = lfs_dir_fetch (lfs , & dir , preventry .d .u .dir );
1954
1964
if (err ) {
1955
1965
return err ;
1956
- } else if (dir .d .size != sizeof (dir .d )+ 4 ) {
1966
+ } else if (dir .d .size != sizeof (dir .d )+ 4 ) {
1957
1967
return LFS_ERR_NOTEMPTY ;
1958
- }
1959
- }
1960
-
1961
- // mark as moving
1962
- oldentry .d .type |= 0x80 ;
1963
- err = lfs_dir_update (lfs , & oldcwd , & oldentry , NULL );
1964
- if (err ) {
1965
- return err ;
1966
- }
1967
-
1968
- // update pair if newcwd == oldcwd
1969
- if (samepair ) {
1970
- newcwd = oldcwd ;
1968
+ }
1971
1969
}
1972
1970
1973
1971
// move to new location
@@ -1988,10 +1986,13 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
1988
1986
}
1989
1987
}
1990
1988
1991
- // update pair if newcwd == oldcwd
1992
- if (samepair ) {
1993
- oldcwd = newcwd ;
1989
+ // fetch old pair again in case dir block changed
1990
+ lfs -> moving = true;
1991
+ err = lfs_dir_find (lfs , & oldcwd , & oldentry , & oldpath );
1992
+ if (err ) {
1993
+ return err ;
1994
1994
}
1995
+ lfs -> moving = false;
1995
1996
1996
1997
// remove old entry
1997
1998
err = lfs_dir_remove (lfs , & oldcwd , & oldentry );
@@ -2089,6 +2090,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
2089
2090
lfs -> files = NULL ;
2090
2091
lfs -> dirs = NULL ;
2091
2092
lfs -> deorphaned = false;
2093
+ lfs -> moving = false;
2092
2094
2093
2095
return 0 ;
2094
2096
0 commit comments