]>
Commit | Line | Data |
---|---|---|
53668523 L |
1 | /*----------------------------------------------------------------------/\r |
2 | / Allocate a contiguous area to the file\r | |
3 | /-----------------------------------------------------------------------/\r | |
4 | / This function checks if the file is contiguous with desired size.\r | |
5 | / If not, a block of contiguous sectors is allocated to the file.\r | |
6 | / If the file has been opened without FA_WRITE flag, it only checks if\r | |
7 | / the file is contiguous and returns the resulut. */\r | |
8 | \r | |
7b78a5a2 | 9 | #if _FATFS != 80367 /* Check if R0.10c */\r |
53668523 L |
10 | #error This function may not be compatible with this revision of FatFs module.\r |
11 | #endif\r | |
12 | \r | |
13 | /* Declarations of FatFs internal functions accessible from applications.\r | |
14 | / This is intended to be used for disk checking/fixing or dirty hacks :-) */\r | |
15 | DWORD clust2sect (FATFS* fs, DWORD clst);\r | |
16 | DWORD get_fat (FATFS* fs, DWORD clst);\r | |
17 | FRESULT put_fat (FATFS* fs, DWORD clst, DWORD val);\r | |
18 | \r | |
19 | \r | |
20 | DWORD allocate_contiguous_clusters ( /* Returns the first sector in LBA (0:error or not contiguous) */\r | |
21 | FIL* fp, /* Pointer to the open file object */\r | |
22 | DWORD len /* Number of bytes to allocate */\r | |
23 | )\r | |
24 | {\r | |
25 | DWORD csz, tcl, ncl, ccl, cl;\r | |
26 | \r | |
27 | \r | |
28 | if (f_lseek(fp, 0) || !len) /* Check if the given parameters are valid */\r | |
29 | return 0;\r | |
30 | csz = 512UL * fp->fs->csize; /* Cluster size in unit of byte (assuming 512 bytes/sector) */\r | |
31 | tcl = (len + csz - 1) / csz; /* Total number of clusters required */\r | |
32 | len = tcl * csz; /* Round-up file size to the cluster boundary */\r | |
33 | \r | |
34 | /* Check if the existing cluster chain is contiguous */\r | |
35 | if (len == fp->fsize) {\r | |
36 | ncl = 0; ccl = fp->sclust;\r | |
37 | do {\r | |
38 | cl = get_fat(fp->fs, ccl); /* Get the cluster status */\r | |
39 | if (cl + 1 < 3) return 0; /* Hard error? */\r | |
40 | if (cl != ccl + 1 &&; cl < fp->fs->n_fatent) break; /* Not contiguous? */\r | |
41 | ccl = cl;\r | |
42 | } while (++ncl < tcl);\r | |
43 | if (ncl == tcl) /* Is the file contiguous? */\r | |
44 | return clust2sect(fp->fs, fp->sclust); /* Return file start sector */\r | |
45 | }\r | |
46 | #if _FS_READONLY\r | |
47 | return 0;\r | |
48 | #else\r | |
49 | if (f_truncate(fp)) return 0; /* Remove the existing chain */\r | |
50 | \r | |
51 | /* Find a free contiguous area */\r | |
52 | ccl = cl = 2; ncl = 0;\r | |
53 | do {\r | |
54 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */\r | |
55 | if (get_fat(fp->fs, cl)) { /* Encounterd a cluster in use */\r | |
56 | do { /* Skip the block of used clusters */\r | |
57 | cl++;\r | |
58 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */\r | |
59 | } while (get_fat(fp->fs, cl));\r | |
60 | ccl = cl; ncl = 0;\r | |
61 | }\r | |
62 | cl++; ncl++;\r | |
63 | } while (ncl < tcl);\r | |
64 | \r | |
65 | /* Create a contiguous cluster chain */\r | |
66 | fp->fs->last_clust = ccl - 1;\r | |
67 | if (f_lseek(fp, len)) return 0;\r | |
68 | \r | |
69 | return clust2sect(fp->fs, fp->sclust); /* Return file start sector */\r | |
70 | #endif\r | |
71 | }\r | |
72 | \r | |
73 | \r | |
74 | int main (void)\r | |
75 | {\r | |
76 | FRESULT fr;\r | |
77 | DRESULT dr;\r | |
78 | FATFS fs;\r | |
79 | FIL fil;\r | |
80 | DWORD org;\r | |
81 | \r | |
82 | \r | |
83 | /* Open or create a file */\r | |
84 | f_mount(&fs, "", 0);\r | |
85 | fr = f_open(&fil, "swapfile.sys", FA_READ | FA_WRITE | FA_OPEN_ALWAYS);\r | |
86 | if (fr) return 1;\r | |
87 | \r | |
88 | /* Check if the file is 64MB in size and occupies a contiguous area.\r | |
89 | / If not, a contiguous area will be re-allocated to the file. */\r | |
90 | org = allocate_contiguous_clusters(&fil, 0x4000000);\r | |
91 | if (!org) {\r | |
92 | printf("Function failed due to any error or insufficient contiguous area.\n");\r | |
93 | f_close(&fil);\r | |
94 | return 1;\r | |
95 | }\r | |
96 | \r | |
97 | /* Now you can read/write the file with disk functions bypassing the file system layer. */\r | |
98 | \r | |
99 | dr = disk_write(fil.fs->drv, Buff, org, 1024); /* Write 512KiB from top of the file */\r | |
100 | \r | |
101 | ...\r | |
102 | \r | |
103 | f_close(&fil);\r | |
104 | return 0;\r | |
105 | }\r | |
106 | \r |