Changeset c111da2 in mainline for uspace/lib/fmgt/src/fmgt.c
- Timestamp:
- 2025-10-09T15:44:52Z (3 months ago)
- Branches:
- master
- Children:
- cfd04c4
- Parents:
- 1a96db9
- File:
-
- 1 edited
-
uspace/lib/fmgt/src/fmgt.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/fmgt/src/fmgt.c
r1a96db9 rc111da2 46 46 47 47 #define NEWNAME_LEN 64 48 #define BUFFER_SIZE 16384 48 49 49 50 /** Create file management library instance. … … 59 60 if (fmgt == NULL) 60 61 return ENOMEM; 62 63 fibril_mutex_initialize(&fmgt->lock); 64 fmgt->timer = fibril_timer_create(&fmgt->lock); 65 if (fmgt->timer == NULL) { 66 free(fmgt); 67 return ENOMEM; 68 } 61 69 62 70 *rfmgt = fmgt; … … 77 85 } 78 86 87 /** Configure whether to give immediate initial progress update. 88 * 89 * @param fmgt File management object 90 * @param enabled @c true to post and immediate initial progress update 91 */ 92 void fmgt_set_init_update(fmgt_t *fmgt, bool enabled) 93 { 94 fmgt->do_init_update = enabled; 95 } 96 79 97 /** Destroy file management library instance. 80 98 * … … 83 101 void fmgt_destroy(fmgt_t *fmgt) 84 102 { 103 (void)fibril_timer_clear(fmgt->timer); 104 fibril_timer_destroy(fmgt->timer); 85 105 free(fmgt); 86 106 } … … 116 136 } 117 137 138 /** Get progress update report. 139 * 140 * @param fmgt File management object 141 * @param progress Place to store progress update 142 */ 143 static void fmgt_get_progress(fmgt_t *fmgt, fmgt_progress_t *progress) 144 { 145 unsigned percent; 146 147 if (fmgt->curf_totalb > 0) 148 percent = fmgt->curf_procb * 100 / fmgt->curf_totalb; 149 else 150 percent = 100; 151 152 capa_blocks_format_buf(fmgt->curf_procb, 1, progress->curf_procb, 153 sizeof(progress->curf_procb)); 154 capa_blocks_format_buf(fmgt->curf_totalb, 1, progress->curf_totalb, 155 sizeof(progress->curf_totalb)); 156 snprintf(progress->curf_percent, sizeof(progress->curf_percent), "%u%%", 157 percent); 158 } 159 160 /** Give the caller progress update. 161 * 162 * @param fmgt File management object 163 */ 164 static void fmgt_progress_update(fmgt_t *fmgt) 165 { 166 fmgt_progress_t progress; 167 168 if (fmgt->cb != NULL && fmgt->cb->progress != NULL) { 169 fmgt_get_progress(fmgt, &progress); 170 fmgt->curf_progr = true; 171 fmgt->cb->progress(fmgt->cb_arg, &progress); 172 } 173 } 174 175 /** Provide initial progress update (if required). 176 * 177 * The caller configures the file management object regarding whether 178 * initial updates are required. 179 * 180 * @param fmgt File management object 181 */ 182 static void fmgt_initial_progress_update(fmgt_t *fmgt) 183 { 184 if (fmgt->do_init_update) 185 fmgt_progress_update(fmgt); 186 } 187 188 /** Provide final progress update (if required). 189 * 190 * Final update is provided only if a previous progress update was given. 191 * 192 * @param fmgt File management object 193 */ 194 static void fmgt_final_progress_update(fmgt_t *fmgt) 195 { 196 if (fmgt->curf_progr) 197 fmgt_progress_update(fmgt); 198 } 199 200 /** Progress timer function. 201 * 202 * Periodically called to provide progress updates. 203 * 204 * @param arg Argument (fmgt_t *) 205 */ 206 static void fmgt_timer_fun(void *arg) 207 { 208 fmgt_t *fmgt = (fmgt_t *)arg; 209 210 fmgt_progress_update(fmgt); 211 fibril_timer_set(fmgt->timer, 500000, fmgt_timer_fun, (void *)fmgt); 212 } 213 214 /** Start progress update timer. 215 * 216 * @param fmgt File management object 217 */ 218 static void fmgt_timer_start(fmgt_t *fmgt) 219 { 220 fibril_timer_set(fmgt->timer, 500000, fmgt_timer_fun, (void *)fmgt); 221 } 222 223 /** Create new file. 224 * 225 * @param fmgt File management object 226 * @param fname File name 227 * @param fsize Size of new file (number of zero bytes to fill in) 228 * @return EOK on success or an error code 229 */ 230 errno_t fmgt_new_file(fmgt_t *fmgt, const char *fname, uint64_t fsize) 231 { 232 int fd; 233 size_t nw; 234 aoff64_t pos = 0; 235 uint64_t now; 236 char *buffer; 237 errno_t rc; 238 239 buffer = calloc(BUFFER_SIZE, 1); 240 if (buffer == NULL) 241 return ENOMEM; 242 243 rc = vfs_lookup_open(fname, WALK_REGULAR | WALK_MUST_CREATE, 244 MODE_WRITE, &fd); 245 if (rc != EOK) { 246 free(buffer); 247 return rc; 248 } 249 250 fmgt->curf_procb = 0; 251 fmgt->curf_totalb = fsize; 252 fmgt->curf_progr = false; 253 fmgt_timer_start(fmgt); 254 255 fmgt_initial_progress_update(fmgt); 256 257 while (fmgt->curf_procb < fsize) { 258 now = fsize - fmgt->curf_procb; 259 if (now > BUFFER_SIZE) 260 now = BUFFER_SIZE; 261 262 rc = vfs_write(fd, &pos, buffer, now, &nw); 263 if (rc != EOK) { 264 free(buffer); 265 vfs_put(fd); 266 fmgt_final_progress_update(fmgt); 267 return rc; 268 } 269 270 fmgt->curf_procb += nw; 271 } 272 273 free(buffer); 274 vfs_put(fd); 275 fmgt_final_progress_update(fmgt); 276 return EOK; 277 } 278 118 279 /** @} 119 280 */
Note:
See TracChangeset
for help on using the changeset viewer.
