Commit 8506eb8d6abefa6d91468a8c350b60ce3321a53e
Committed by
Wolfgang Denk
1 parent
e27334212c
Exists in
master
and in
54 other branches
FAT: fix some issues in FAT write support code
Writing a file to the FAT partition didn't work while a test using a CF card. The test was done on mpc5200 based board (powerpc). There is a number of problems in FAT write code: Compiler warning: fat_write.c: In function 'file_fat_write': fat_write.c:326: warning: 'counter' may be used uninitialized in this function fat_write.c:326: note: 'counter' was declared here 'l_filename' string is not terminated, so a file name with garbage at the end is used as a file name as shown by debug code. Return value of set_contents() is not checked properly so actually a file won't be written at all (as checked using 'fatls' after a write attempt with 'fatwrite' command). do_fat_write() doesn't return the number of written bytes if no error happened. However the return value of this function is used to show the number of written bytes in do_fat_fswrite(). The patch adds some debug code and fixes above mentioned problems and also fixes a typo in error output. NOTE: after a successful write to the FAT partition (under U-Boot) the partition was checked under Linux using fsck. The partition needed fixing FATs: -bash-3.2# fsck -a /dev/sda1 fsck 1.39 (29-May-2006) dosfsck 2.11, 12 Mar 2005, FAT32, LFN FATs differ but appear to be intact. Using first FAT. Performing changes. Signed-off-by: Anatolij Gustschin <agust@denx.de> Cc: Donggeun Kim <dg77.kim@samsung.com> Cc: Aaron Williams <Aaron.Williams@cavium.com> Acked-by: Donggeun Kim <dg77.kim@samsung.com>
Showing 1 changed file with 14 additions and 5 deletions Side-by-side Diff
fs/fat/fat_write.c
... | ... | @@ -323,7 +323,7 @@ |
323 | 323 | fill_dir_slot(fsdata *mydata, dir_entry **dentptr, const char *l_name) |
324 | 324 | { |
325 | 325 | dir_slot *slotptr = (dir_slot *)get_vfatname_block; |
326 | - __u8 counter, checksum; | |
326 | + __u8 counter = 0, checksum; | |
327 | 327 | int idx = 0, ret; |
328 | 328 | char s_name[16]; |
329 | 329 | |
... | ... | @@ -926,6 +926,7 @@ |
926 | 926 | int cursect; |
927 | 927 | int root_cluster, ret = -1, name_len; |
928 | 928 | char l_filename[VFAT_MAXLEN_BYTES]; |
929 | + int write_size = size; | |
929 | 930 | |
930 | 931 | dir_curclust = 0; |
931 | 932 | |
932 | 933 | |
... | ... | @@ -985,7 +986,11 @@ |
985 | 986 | dentptr = (dir_entry *) do_fat_read_block; |
986 | 987 | |
987 | 988 | name_len = strlen(filename); |
989 | + if (name_len >= VFAT_MAXLEN_BYTES) | |
990 | + name_len = VFAT_MAXLEN_BYTES - 1; | |
991 | + | |
988 | 992 | memcpy(l_filename, filename, name_len); |
993 | + l_filename[name_len] = 0; /* terminate the string */ | |
989 | 994 | downcase(l_filename); |
990 | 995 | |
991 | 996 | startsect = mydata->rootdir_sect; |
992 | 997 | |
... | ... | @@ -1012,10 +1017,12 @@ |
1012 | 1017 | } |
1013 | 1018 | |
1014 | 1019 | ret = set_contents(mydata, retdent, buffer, size); |
1015 | - if (ret) { | |
1020 | + if (ret < 0) { | |
1016 | 1021 | printf("Error: writing contents\n"); |
1017 | 1022 | goto exit; |
1018 | 1023 | } |
1024 | + write_size = ret; | |
1025 | + debug("attempt to write 0x%x bytes\n", write_size); | |
1019 | 1026 | |
1020 | 1027 | /* Flush fat buffer */ |
1021 | 1028 | ret = flush_fat_buffer(mydata); |
... | ... | @@ -1029,7 +1036,7 @@ |
1029 | 1036 | get_dentfromdir_block, |
1030 | 1037 | mydata->clust_size * mydata->sect_size); |
1031 | 1038 | if (ret) { |
1032 | - printf("Error: wrinting directory entry\n"); | |
1039 | + printf("Error: writing directory entry\n"); | |
1033 | 1040 | goto exit; |
1034 | 1041 | } |
1035 | 1042 | } else { |
1036 | 1043 | |
... | ... | @@ -1056,10 +1063,12 @@ |
1056 | 1063 | start_cluster, size, 0x20); |
1057 | 1064 | |
1058 | 1065 | ret = set_contents(mydata, empty_dentptr, buffer, size); |
1059 | - if (ret) { | |
1066 | + if (ret < 0) { | |
1060 | 1067 | printf("Error: writing contents\n"); |
1061 | 1068 | goto exit; |
1062 | 1069 | } |
1070 | + write_size = ret; | |
1071 | + debug("attempt to write 0x%x bytes\n", write_size); | |
1063 | 1072 | |
1064 | 1073 | /* Flush fat buffer */ |
1065 | 1074 | ret = flush_fat_buffer(mydata); |
... | ... | @@ -1080,7 +1089,7 @@ |
1080 | 1089 | |
1081 | 1090 | exit: |
1082 | 1091 | free(mydata->fatbuf); |
1083 | - return ret; | |
1092 | + return ret < 0 ? ret : write_size; | |
1084 | 1093 | } |
1085 | 1094 | |
1086 | 1095 | int file_fat_write(const char *filename, void *buffer, unsigned long maxsize) |