mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Added tests, cleanup, and fixed a small issue with updating file flags
Related to changes to custom attribute and open file syncing
This commit is contained in:
		
							
								
								
									
										3
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -2527,6 +2527,7 @@ static int lfs_file_rawopencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
| #ifndef LFS_READONLY | #ifndef LFS_READONLY | ||||||
|     } else if (flags & LFS_O_TRUNC) { |     } else if (flags & LFS_O_TRUNC) { | ||||||
|         // truncate if requested |         // truncate if requested | ||||||
|  |         // always mark dirty in case we have custom attributes | ||||||
|         tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0); |         tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0); | ||||||
|         file->flags |= LFS_F_DIRTY; |         file->flags |= LFS_F_DIRTY; | ||||||
| #endif | #endif | ||||||
| @@ -2878,7 +2879,7 @@ static int lfs_file_rawsync(lfs_t *lfs, lfs_file_t *file) { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 file->flags &= ~(LFS_F_DIRTY | LFS_F_WRITING | LFS_F_READING); |                 f->flags &= ~(LFS_F_DIRTY | LFS_F_WRITING | LFS_F_READING); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -294,10 +294,10 @@ struct lfs_file_config { | |||||||
|     void *buffer; |     void *buffer; | ||||||
|  |  | ||||||
|     // Optional list of custom attributes related to the file. If the file |     // Optional list of custom attributes related to the file. If the file | ||||||
|     // is opened with read access, these attributes will be read from disk |     // is opened for reading, these attributes will be read from disk during | ||||||
|     // during the open call. If the file is opened with write access, the |     // open. If the file is open for writing, these attribute will be atomically | ||||||
|     // attributes will be written to disk every file sync or close. This |     // written to disk when the file is written to disk. Note that these | ||||||
|     // write occurs atomically with update to the file's contents. |     // attributes are not written unless the file is modified. | ||||||
|     // |     // | ||||||
|     // Custom attributes are uniquely identified by an 8-bit type and limited |     // Custom attributes are uniquely identified by an 8-bit type and limited | ||||||
|     // to LFS_ATTR_MAX bytes. If the stored attribute is larger than the |     // to LFS_ATTR_MAX bytes. If the stored attribute is larger than the | ||||||
|   | |||||||
| @@ -242,3 +242,265 @@ code = ''' | |||||||
|  |  | ||||||
|     lfs_unmount(&lfs) => 0; |     lfs_unmount(&lfs) => 0; | ||||||
| ''' | ''' | ||||||
|  |  | ||||||
|  | [[case]] # open same file reading from separate file handles | ||||||
|  | define.READERS = 3 | ||||||
|  | define.SIZE = [10, 100, 1000, 10000] | ||||||
|  | define.RDMODE = ['LFS_O_RDONLY', 'LFS_O_RDWR'] | ||||||
|  | code = ''' | ||||||
|  |     const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; | ||||||
|  |     lfs_format(&lfs, &cfg) => 0; | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     lfs_file_open(&lfs, &file, "shared", LFS_O_CREAT | LFS_O_WRONLY) => 0; | ||||||
|  |     for (int j = 0; j < SIZE; j++) { | ||||||
|  |         lfs_file_write(&lfs, &file, &alphas[j % 26], 1) => 1; | ||||||
|  |     } | ||||||
|  |     lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     // open all files | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     lfs_file_t readers[READERS]; | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         lfs_file_open(&lfs, &readers[i], "shared", RDMODE) => 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // perform operations while all readers are open | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &readers[i], buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == alphas[j % 26]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         lfs_file_close(&lfs, &readers[i]) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # open same file reading and writing from separate file handles | ||||||
|  | define.READERS = 3 | ||||||
|  | define.SIZE = [10, 100, 1000, 10000] | ||||||
|  | define.RDMODE = ['LFS_O_RDONLY', 'LFS_O_RDWR'] | ||||||
|  | define.WRMODE = ['LFS_O_WRONLY', 'LFS_O_RDWR'] | ||||||
|  | code = ''' | ||||||
|  |     const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; | ||||||
|  |     const char nums[] = "0123456789"; | ||||||
|  |     lfs_format(&lfs, &cfg) => 0; | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     lfs_file_open(&lfs, &file, "shared", LFS_O_CREAT | LFS_O_WRONLY) => 0; | ||||||
|  |     for (int j = 0; j < SIZE; j++) { | ||||||
|  |         lfs_file_write(&lfs, &file, &alphas[j % 26], 1) => 1; | ||||||
|  |     } | ||||||
|  |     lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     // open all files | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     lfs_file_t writer; | ||||||
|  |     lfs_file_t readers[READERS]; | ||||||
|  |     lfs_file_open(&lfs, &writer, "shared", WRMODE) => 0; | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         lfs_file_open(&lfs, &readers[i], "shared", RDMODE) => 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // perform operations while all readers are open | ||||||
|  |     for (int j = 0; j < SIZE; j++) { | ||||||
|  |         lfs_file_write(&lfs, &writer, &nums[j % 10], 1) => 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         for (int j = 0; j < SIZE/2; j++) { | ||||||
|  |             lfs_file_read(&lfs, &readers[i], buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == alphas[j % 26]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // sync, now write should reflect in all open files | ||||||
|  |     lfs_file_sync(&lfs, &writer) => 0; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         for (int j = SIZE/2; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &readers[i], buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == nums[j % 10]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // double check our writer reflects its own changes | ||||||
|  |     if (WRMODE == LFS_O_RDWR) { | ||||||
|  |         lfs_file_rewind(&lfs, &writer) => 0; | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &writer, buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == nums[j % 10]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         lfs_file_close(&lfs, &readers[i]) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | ''' | ||||||
|  |  | ||||||
|  | [[case]] # check that attributes are updated in open files | ||||||
|  | define.READERS = 3 | ||||||
|  | define.SIZE = 10 | ||||||
|  | define.RDMODE = ['LFS_O_RDONLY', 'LFS_O_RDWR'] | ||||||
|  | define.WRMODE = ['LFS_O_WRONLY', 'LFS_O_RDWR'] | ||||||
|  | code = ''' | ||||||
|  |     const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; | ||||||
|  |     const char nums[] = "0123456789"; | ||||||
|  |     lfs_format(&lfs, &cfg) => 0; | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     const struct lfs_file_config filecfg = { | ||||||
|  |         .attr_count = 3, | ||||||
|  |         .attrs = (struct lfs_attr[]){ | ||||||
|  |             {'A', "a",   1}, | ||||||
|  |             {'B', "bb",  2}, | ||||||
|  |             {'C', "ccc", 3}, | ||||||
|  |         }, | ||||||
|  |     }; | ||||||
|  |     lfs_file_opencfg(&lfs, &file, "shared", | ||||||
|  |             LFS_O_CREAT | LFS_O_WRONLY, &filecfg) => 0; | ||||||
|  |     for (int j = 0; j < SIZE; j++) { | ||||||
|  |         lfs_file_write(&lfs, &file, &alphas[j % 26], 1) => 1; | ||||||
|  |     } | ||||||
|  |     lfs_file_close(&lfs, &file) => 0; | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  |  | ||||||
|  |     // open all files | ||||||
|  |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|  |     lfs_file_t writer; | ||||||
|  |     const struct lfs_file_config writercfg = { | ||||||
|  |         .attr_count = 3, | ||||||
|  |         .attrs = (struct lfs_attr[]){ | ||||||
|  |             {'A', &(uint8_t[1]){0}, 1}, | ||||||
|  |             {'B', &(uint8_t[2]){0}, 2}, | ||||||
|  |             {'C', &(uint8_t[3]){0}, 3}}}; | ||||||
|  |     lfs_file_t readers[READERS]; | ||||||
|  |     const struct lfs_file_config readercfgs[READERS] = { | ||||||
|  |         {   .attr_count = 3, | ||||||
|  |             .attrs = (struct lfs_attr[]){ | ||||||
|  |                 {'A', &(uint8_t[1]){0}, 1}, | ||||||
|  |                 {'B', &(uint8_t[2]){0}, 2}, | ||||||
|  |                 {'C', &(uint8_t[3]){0}, 3}}}, | ||||||
|  |         {   .attr_count = 3, | ||||||
|  |             .attrs = (struct lfs_attr[]){ | ||||||
|  |                 {'A', &(uint8_t[1]){0}, 1}, | ||||||
|  |                 {'B', &(uint8_t[2]){0}, 2}, | ||||||
|  |                 {'C', &(uint8_t[3]){0}, 3}}}, | ||||||
|  |         {   .attr_count = 3, | ||||||
|  |             .attrs = (struct lfs_attr[]){ | ||||||
|  |                 {'A', &(uint8_t[1]){0}, 1}, | ||||||
|  |                 {'B', &(uint8_t[2]){0}, 2}, | ||||||
|  |                 {'C', &(uint8_t[3]){0}, 3}}}}; | ||||||
|  |     lfs_file_opencfg(&lfs, &writer, "shared", | ||||||
|  |             WRMODE, &writercfg) => 0; | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         lfs_file_opencfg(&lfs, &readers[i], "shared", | ||||||
|  |                 RDMODE, &readercfgs[i]) => 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // perform operations while all readers are open | ||||||
|  |     writercfg.attrs[0].size = 1; | ||||||
|  |     memcpy(writercfg.attrs[0].buffer, "0", 1); | ||||||
|  |     writercfg.attrs[1].size = 2; | ||||||
|  |     memcpy(writercfg.attrs[1].buffer, "11", 2); | ||||||
|  |     writercfg.attrs[2].size = 3; | ||||||
|  |     memcpy(writercfg.attrs[2].buffer, "222", 3); | ||||||
|  |     for (int j = 0; j < SIZE; j++) { | ||||||
|  |         lfs_file_write(&lfs, &writer, &nums[j % 10], 1) => 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         assert(readercfgs[i].attrs[0].size == 1); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[0].buffer, "a", 1) == 0); | ||||||
|  |         assert(readercfgs[i].attrs[1].size == 2); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[1].buffer, "bb", 2) == 0); | ||||||
|  |         assert(readercfgs[i].attrs[2].size == 3); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[2].buffer, "ccc", 3) == 0); | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &readers[i], buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == alphas[j % 26]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // sync, now write should reflect in all open files | ||||||
|  |     lfs_file_sync(&lfs, &writer) => 0; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         assert(readercfgs[i].attrs[0].size == 1); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[0].buffer, "0", 1) == 0); | ||||||
|  |         assert(readercfgs[i].attrs[1].size == 2); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[1].buffer, "11", 2) == 0); | ||||||
|  |         assert(readercfgs[i].attrs[2].size == 3); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[2].buffer, "222", 3) == 0); | ||||||
|  |         lfs_file_rewind(&lfs, &readers[i]) => 0; | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &readers[i], buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == nums[j % 10]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // double check our writer reflects its own changes | ||||||
|  |     if (WRMODE == LFS_O_RDWR) { | ||||||
|  |         assert(writercfg.attrs[0].size == 1); | ||||||
|  |         assert(memcmp(writercfg.attrs[0].buffer, "0", 1) == 0); | ||||||
|  |         assert(writercfg.attrs[1].size == 2); | ||||||
|  |         assert(memcmp(writercfg.attrs[1].buffer, "11", 2) == 0); | ||||||
|  |         assert(writercfg.attrs[2].size == 3); | ||||||
|  |         assert(memcmp(writercfg.attrs[2].buffer, "222", 3) == 0); | ||||||
|  |         lfs_file_rewind(&lfs, &writer) => 0; | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &writer, buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == nums[j % 10]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // now try explicit lfs_setattr calls, this should still update open files | ||||||
|  |     lfs_setattr(&lfs, "shared", 'A', "A",   1) => 0; | ||||||
|  |     lfs_setattr(&lfs, "shared", 'B', "BB",  2) => 0; | ||||||
|  |     lfs_setattr(&lfs, "shared", 'C', "CCC", 3) => 0; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         assert(readercfgs[i].attrs[0].size == 1); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[0].buffer, "A", 1) == 0); | ||||||
|  |         assert(readercfgs[i].attrs[1].size == 2); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[1].buffer, "BB", 2) == 0); | ||||||
|  |         assert(readercfgs[i].attrs[2].size == 3); | ||||||
|  |         assert(memcmp(readercfgs[i].attrs[2].buffer, "CCC", 3) == 0); | ||||||
|  |         lfs_file_rewind(&lfs, &readers[i]) => 0; | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &readers[i], buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == nums[j % 10]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (WRMODE == LFS_O_RDWR) { | ||||||
|  |         assert(writercfg.attrs[0].size == 1); | ||||||
|  |         assert(memcmp(writercfg.attrs[0].buffer, "A", 1) == 0); | ||||||
|  |         assert(writercfg.attrs[1].size == 2); | ||||||
|  |         assert(memcmp(writercfg.attrs[1].buffer, "BB", 2) == 0); | ||||||
|  |         assert(writercfg.attrs[2].size == 3); | ||||||
|  |         assert(memcmp(writercfg.attrs[2].buffer, "CCC", 3) == 0); | ||||||
|  |         lfs_file_rewind(&lfs, &writer) => 0; | ||||||
|  |         for (int j = 0; j < SIZE; j++) { | ||||||
|  |             lfs_file_read(&lfs, &writer, buffer, 1) => 1; | ||||||
|  |             assert(buffer[0] == nums[j % 10]); | ||||||
|  |         } | ||||||
|  |     } else if (WRMODE == LFS_O_WRONLY) { | ||||||
|  |         // this should NOT update wronly attributes, these may be | ||||||
|  |         // stored in read-only memory | ||||||
|  |         assert(writercfg.attrs[0].size == 1); | ||||||
|  |         assert(memcmp(writercfg.attrs[0].buffer, "0", 1) == 0); | ||||||
|  |         assert(writercfg.attrs[1].size == 2); | ||||||
|  |         assert(memcmp(writercfg.attrs[1].buffer, "11", 2) == 0); | ||||||
|  |         assert(writercfg.attrs[2].size == 3); | ||||||
|  |         assert(memcmp(writercfg.attrs[2].buffer, "222", 3) == 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < READERS; i++) { | ||||||
|  |         lfs_file_close(&lfs, &readers[i]) => 0; | ||||||
|  |     } | ||||||
|  |     lfs_unmount(&lfs) => 0; | ||||||
|  | ''' | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user