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