Merge branch 'time_upgrade'
authorCharles Manning <cdhmanning@gmail.com>
Wed, 7 Jul 2021 04:00:35 +0000 (16:00 +1200)
committerCharles Manning <cdhmanning@gmail.com>
Wed, 7 Jul 2021 04:00:35 +0000 (16:00 +1200)
direct/test-framework/basic-tests/dtest.c
direct/test-framework/timothy_tests/quick_tests/lib.c
direct/yaffsfs.c
direct/yaffsfs.h
direct/ydirectenv.h
yaffs_endian.c
yaffs_endian.h
yaffs_guts.h
yaffs_vfs_multi.c
yaffs_vfs_single.c

index 405f00a..60d1749 100644 (file)
 #include <time.h>
 #include <ctype.h>
 
+
 #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");
index 5673ff1..2063d2c 100644 (file)
@@ -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)
index d1e4e4e..2c1ac42 100644 (file)
@@ -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;
index b96011f..b96411f 100644 (file)
@@ -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 */
index b477343..08fc04d 100644 (file)
@@ -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
index 6103f4e..571a35f 100644 (file)
@@ -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);
 
index 8c27189..0f1ef04 100644 (file)
@@ -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)))
 
index 96fd547..22381f9 100644 (file)
@@ -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;
index 19c8919..a08e071 100644 (file)
@@ -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;
index 1abbfd8..0817ff0 100644 (file)
@@ -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;