@@ -888,7 +888,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
888888 }
889889
890890 // check that entry has not been moved
891- if (entry -> d .type & 0x80 ) {
891+ if (! lfs -> moving && entry -> d .type & 0x80 ) {
892892 int moved = lfs_moved (lfs , & entry -> d .u );
893893 if (moved < 0 || moved ) {
894894 return (moved < 0 ) ? moved : LFS_ERR_NOENT ;
@@ -1644,6 +1644,11 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
16441644 file -> pos = file -> size ;
16451645 }
16461646
1647+ if (file -> pos + size > LFS_FILE_MAX ) {
1648+ // larger than file limit?
1649+ return LFS_ERR_FBIG ;
1650+ }
1651+
16471652 if (!(file -> flags & LFS_F_WRITING ) && file -> pos > file -> size ) {
16481653 // fill with zeros
16491654 lfs_off_t pos = file -> pos ;
@@ -1730,24 +1735,24 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
17301735 return err ;
17311736 }
17321737
1733- // update pos
1738+ // find new pos
1739+ lfs_soff_t npos = file -> pos ;
17341740 if (whence == LFS_SEEK_SET ) {
1735- file -> pos = off ;
1741+ npos = off ;
17361742 } 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 ;
17421744 } 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+ }
17461747
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 ;
17481751 }
17491752
1750- return file -> pos ;
1753+ // update pos
1754+ file -> pos = npos ;
1755+ return npos ;
17511756}
17521757
17531758int 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) {
19241929 // find old entry
19251930 lfs_dir_t oldcwd ;
19261931 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 );
19281940 if (err ) {
19291941 return err ;
19301942 }
@@ -1937,11 +1949,9 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
19371949 return err ;
19381950 }
19391951
1940- bool prevexists = (err != LFS_ERR_NOENT );
1941- bool samepair = (lfs_paircmp (oldcwd .pair , newcwd .pair ) == 0 );
1942-
19431952 // 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 )) {
19451955 return LFS_ERR_ISDIR ;
19461956 }
19471957
@@ -1953,21 +1963,9 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
19531963 err = lfs_dir_fetch (lfs , & dir , preventry .d .u .dir );
19541964 if (err ) {
19551965 return err ;
1956- } else if (dir .d .size != sizeof (dir .d )+ 4 ) {
1966+ } else if (dir .d .size != sizeof (dir .d )+ 4 ) {
19571967 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+ }
19711969 }
19721970
19731971 // move to new location
@@ -1988,10 +1986,13 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
19881986 }
19891987 }
19901988
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 ;
19941994 }
1995+ lfs -> moving = false;
19951996
19961997 // remove old entry
19971998 err = lfs_dir_remove (lfs , & oldcwd , & oldentry );
@@ -2089,6 +2090,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
20892090 lfs -> files = NULL ;
20902091 lfs -> dirs = NULL ;
20912092 lfs -> deorphaned = false;
2093+ lfs -> moving = false;
20922094
20932095 return 0 ;
20942096
0 commit comments