From: Charles Manning Date: Wed, 7 Jul 2021 04:00:35 +0000 (+1200) Subject: Merge branch 'time_upgrade' X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=e40cfb32abd2a9147f6fc956fef433e794baadd0;hp=89c47bd92c6accf5955184ba65742b20523b05a9 Merge branch 'time_upgrade' --- diff --git a/direct/test-framework/basic-tests/dtest.c b/direct/test-framework/basic-tests/dtest.c index 405f00a..60d1749 100644 --- a/direct/test-framework/basic-tests/dtest.c +++ b/direct/test-framework/basic-tests/dtest.c @@ -18,9 +18,11 @@ #include #include + #include "yaffsfs.h" #include "yaffs_guts.h" /* Only for dumping device innards */ +#include "yaffs_endian.h" /*For testing the swap_u64 macro */ extern int yaffs_trace_mask; @@ -2662,6 +2664,7 @@ void basic_utime_test(const char *mountpt) struct yaffs_utimbuf utb; struct yaffs_stat st; + //setup yaffs_start_up(); yaffs_mount(mountpt); @@ -2676,16 +2679,21 @@ void basic_utime_test(const char *mountpt) h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); yaffs_fstat(h,&st); - printf(" times %lu %lu %lu\n", - st.yst_atime, st.yst_ctime, st.yst_mtime); + printf(" times before %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); + //here are the last access and modification times. utb.actime = 1000; utb.modtime = 2000; + + //futime sets the last modification and access time of the file result = yaffs_futime(h,&utb); - printf("futime to a 1000 m 2000 result %d\n",result); + printf("setting times using the futime function to a 1000 m 2000 result %d\n",result); + + //read the times from the file header yaffs_fstat(h,&st); - printf(" times %lu %lu %lu\n", - st.yst_atime, st.yst_ctime, st.yst_mtime); + printf(" times %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); utb.actime = 5000; @@ -2693,18 +2701,154 @@ void basic_utime_test(const char *mountpt) result = yaffs_utime(name, &utb); printf("utime to a 5000 m 8000 result %d\n",result); yaffs_fstat(h,&st); - printf(" times %lu %lu %lu\n", - st.yst_atime, st.yst_ctime, st.yst_mtime); + printf(" times %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); result = yaffs_utime(name, NULL); printf("utime to NULL result %d\n",result); yaffs_fstat(h,&st); - printf(" times %lu %lu %lu\n", - st.yst_atime, st.yst_ctime, st.yst_mtime); + printf(" times %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); } +void print_binary(u64 val){ + int count = 0; + for (int i= 63; i>=0; i --) { + if (count == 0){ + printf(" "); + } + if ((((u64)1) << i) & val) { + printf("1"); + } else { + printf("0"); + } + count = (count +1) % 8; + } +} + +void testing_swap_u64() { + int numberOfFailedTests = 0; + for (int i =0; i < 8; i ++) { + u64 startingNumber = (0xffLLu << (i*8)); + u64 expected = (0xffLLu << (64 - (i*8) -8)); + u64 converted = swap_u64(startingNumber); + if (converted != expected) { + numberOfFailedTests ++; + printf("numbers do not match.\n"); + printf("0xff\t\t\t"); + print_binary(0xff); + printf("\nStarting Number \t"); + print_binary(startingNumber); + printf("\nExpecting \t\t"); + print_binary(expected); + printf("\nConverted \t\t"); + print_binary(converted); + + printf("\n"); + } + } + if (numberOfFailedTests){ + printf("testing_swap failed %d tests\n", numberOfFailedTests); + } else { + printf("testing_swap_u64 passed all tests\n"); + } +} + + +void size_utime_test(const char *mountpt) +{ + char name[100]; + int h; + int result; + struct yaffs_utimbuf utb; + struct yaffs_stat st; + + //setup + yaffs_start_up(); + + yaffs_mount(mountpt); + + strcpy(name,mountpt); + strcat(name,"/"); + strcat(name,"xfile"); + + yaffs_unlink(name); + + printf("created\n"); + h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); + + yaffs_fstat(h,&st); + printf(" times before %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); + + //first lets get the yaffs_object. + + //then check that yaffs_stat also works. + //yaffs_stat already uses 64 bits for both wince and unix times. + //To see if we are using 32 or 64 bit time, save a large number into the time and + //see if it overflows. + long bitsInTime = 8*sizeof(st.yst_ctime); + printf("the times are %ld bits long\n", bitsInTime); + + //two testcases + if (bitsInTime == 64) { + //no need to test the overflow. Just check that it can be retrieved intact. + + //use u64 variables in case utb truncates the values to 32 bit time by accident. + u64 start = 0xfffff; + u64 end = 0xffffff; + + utb.actime = start; + utb.modtime = end; + + result = yaffs_futime(h,&utb); + yaffs_fstat(h,&st); + if (st.yst_atime == start && st.yst_mtime == end) { + printf("successfully stored and retrevied a 64 bit number for atime and modtime\n"); + } else { + printf("failed to store and retrieve a 64 bit number for atime and modtime\n"); + + } + } else { + //it is a 32 bit number. Check to see that it overflowed. + + } + + + //here are the last access and modification times. + utb.actime = 1000; + utb.modtime = 2000; + + //futime sets the last modification and access time of the file + result = yaffs_futime(h,&utb); + printf("setting times using the futime function to a 1000 m 2000 result %d\n",result); + + //read the times from the file header + yaffs_fstat(h,&st); + printf(" times %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); + + + utb.actime = 5000; + utb.modtime = 8000; + result = yaffs_utime(name, &utb); + printf("utime to a 5000 m 8000 result %d\n",result); + yaffs_fstat(h,&st); + printf(" times %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); + + result = yaffs_utime(name, NULL); + printf("utime to NULL result %d\n",result); + yaffs_fstat(h,&st); + printf(" times %llu %llu %llu\n", + ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime); + + +} + + void basic_xattr_test(const char *mountpt) { char name[100]; @@ -3511,7 +3655,7 @@ int main(int argc, char *argv[]) //long_test_on_path("/ram2k"); // long_test_on_path("/flash"); //simple_rw_test("/flash/flash"); - fill_n_file_test("/nand128MB", 50, 128000000/50); + //fill_n_file_test("/nand128MB", 50, 128000000/50); // rename_over_test("/flash"); //lookup_test("/flash"); //freespace_test("/flash/flash"); @@ -3543,7 +3687,9 @@ int main(int argc, char *argv[]) //large_file_test("/nand"); //readdir_test("/nand"); - //basic_utime_test("/nand"); + basic_utime_test("/nand"); + testing_swap_u64(); + size_utime_test("/nand"); //case_insensitive_test("/nand"); //yy_test("/nand"); diff --git a/direct/test-framework/timothy_tests/quick_tests/lib.c b/direct/test-framework/timothy_tests/quick_tests/lib.c index 5673ff1..2063d2c 100644 --- a/direct/test-framework/timothy_tests/quick_tests/lib.c +++ b/direct/test-framework/timothy_tests/quick_tests/lib.c @@ -136,7 +136,7 @@ int delete_dir(char *dir_name) yaffs_DIR *d; struct yaffs_dirent *de; struct yaffs_stat s; - char str[100]; + char str[300]; d = yaffs_opendir(dir_name); //printf("%s\n",dir_name); if(!d) diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index d1e4e4e..2c1ac42 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -1943,17 +1943,21 @@ static int yaffsfs_DoUtime(struct yaffs_obj *obj, } #if !CONFIG_YAFFS_WINCE + // if the the buffer is null then create one with the fields set to the current time. if (!buf) { local.actime = Y_CURRENT_TIME; local.modtime = local.actime; buf = &local; } + // copy the buffer's time into the obj. if (obj) { int result; obj->yst_atime = buf->actime; obj->yst_mtime = buf->modtime; + + // set the obj to dirty to cause it to be written to flash during the next flush operation. obj->dirty = 1; result = yaffs_flush_file(obj, 0, 0, 0); retVal = result == YAFFS_OK ? 0 : -1; diff --git a/direct/yaffsfs.h b/direct/yaffsfs.h index b96011f..b96411f 100644 --- a/direct/yaffsfs.h +++ b/direct/yaffsfs.h @@ -69,16 +69,16 @@ struct yaffs_stat { unsigned long yst_wince_mtime[2]; unsigned long yst_wince_ctime[2]; #else - unsigned long yst_atime; /* time of last access */ - unsigned long yst_mtime; /* time of last modification */ - unsigned long yst_ctime; /* time of last change */ + YTIME_T yst_atime; /* time of last access */ + YTIME_T yst_mtime; /* time of last modification */ + YTIME_T yst_ctime; /* time of last change */ #endif }; struct yaffs_utimbuf { - unsigned long actime; - unsigned long modtime; + YTIME_T actime; + YTIME_T modtime; }; /* Normal POSIX-style API functions */ diff --git a/direct/ydirectenv.h b/direct/ydirectenv.h index b477343..08fc04d 100644 --- a/direct/ydirectenv.h +++ b/direct/ydirectenv.h @@ -29,6 +29,11 @@ void yaffs_bug_fn(const char *file_name, int line_no); #define BUG() do { yaffs_bug_fn(__FILE__, __LINE__); } while (0) +#ifdef YAFFS_USE_32_BIT_TIME_T + #define YTIME_T u32 +#else + #define YTIME_T u64 +#endif #define YCHAR char #define YUCHAR unsigned char diff --git a/yaffs_endian.c b/yaffs_endian.c index 6103f4e..571a35f 100644 --- a/yaffs_endian.c +++ b/yaffs_endian.c @@ -42,9 +42,9 @@ void yaffs_do_endian_oh(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh) oh->yst_uid = swap_u32(oh->yst_uid); oh->yst_gid = swap_u32(oh->yst_gid); - oh->yst_atime = swap_u32(oh->yst_atime); - oh->yst_mtime = swap_u32(oh->yst_mtime); - oh->yst_ctime = swap_u32(oh->yst_ctime); + oh->yst_atime = swap_ytime_t(oh->yst_atime); + oh->yst_mtime = swap_ytime_t(oh->yst_mtime); + oh->yst_ctime = swap_ytime_t(oh->yst_ctime); oh->file_size_low = swap_u32(oh->file_size_low); diff --git a/yaffs_endian.h b/yaffs_endian.h index 8c27189..0f1ef04 100644 --- a/yaffs_endian.h +++ b/yaffs_endian.h @@ -25,6 +25,26 @@ static inline u32 swap_u32(u32 val) ((val <<24) & 0xff000000); } +static inline u64 swap_u64(u64 val) +{ + return ((val >> 56) & 0x00000000000000ff) | + ((val >> 40) & 0x000000000000ff00) | + ((val >> 24) & 0x0000000000ff0000) | + ((val >> 8) & 0x00000000ff000000) | + ((val << 8) & 0x000000ff00000000) | + ((val << 24) & 0x0000ff0000000000) | + ((val << 40) & 0x00ff000000000000) | + ((val << 56) & 0xff00000000000000); +} + +//YTIME_T can be a 32 or 64 bit number. +#if YAFFS_USE_32_BIT_TIME_T + #define swap_ytime_t( val ) swap_u32(val) +#else + #define swap_ytime_t( val ) swap_u64(val) +#endif + +//swap a signed 32 bit integer. #define swap_s32(val) \ (s32)(swap_u32((u32)(val))) diff --git a/yaffs_guts.h b/yaffs_guts.h index 96fd547..22381f9 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -482,15 +482,17 @@ struct yaffs_obj { YCHAR short_name[YAFFS_SHORT_NAME_LENGTH + 1]; #ifdef CONFIG_YAFFS_WINCE + //these are always 64 bits u32 win_ctime[2]; u32 win_mtime[2]; u32 win_atime[2]; #else - u32 yst_uid; - u32 yst_gid; - u32 yst_atime; - u32 yst_mtime; - u32 yst_ctime; + //these can be 32 or 64 bits + YTIME_T yst_uid; + YTIME_T yst_gid; + YTIME_T yst_atime; + YTIME_T yst_mtime; + YTIME_T yst_ctime; #endif u32 yst_rdev; diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c index 19c8919..a08e071 100644 --- a/yaffs_vfs_multi.c +++ b/yaffs_vfs_multi.c @@ -2047,11 +2047,11 @@ static void yaffs_fill_inode_from_obj(struct inode *inode, #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) inode->i_rdev = old_decode_dev(obj->yst_rdev); - inode->i_atime.tv_sec = (time_t) (obj->yst_atime); + inode->i_atime.tv_sec = (YTIME_T) (obj->yst_atime); inode->i_atime.tv_nsec = 0; - inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; + inode->i_mtime.tv_sec = (YTIME_T) obj->yst_mtime; inode->i_mtime.tv_nsec = 0; - inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; + inode->i_ctime.tv_sec = (YTIME_T) obj->yst_ctime; inode->i_ctime.tv_nsec = 0; #else inode->i_rdev = obj->yst_rdev; diff --git a/yaffs_vfs_single.c b/yaffs_vfs_single.c index 1abbfd8..0817ff0 100644 --- a/yaffs_vfs_single.c +++ b/yaffs_vfs_single.c @@ -1890,11 +1890,11 @@ static void yaffs_fill_inode_from_obj(struct inode *inode, inode->i_rdev = old_decode_dev(obj->yst_rdev); - inode->i_atime.tv_sec = (time_t) (obj->yst_atime); + inode->i_atime.tv_sec = (YTIME_T) (obj->yst_atime); inode->i_atime.tv_nsec = 0; - inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; + inode->i_mtime.tv_sec = (YTIME_T) obj->yst_mtime; inode->i_mtime.tv_nsec = 0; - inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; + inode->i_ctime.tv_sec = (YTIME_T) obj->yst_ctime; inode->i_ctime.tv_nsec = 0; inode->i_size = yaffs_get_obj_length(obj); inode->i_blocks = (inode->i_size + 511) >> 9;