Changeset f4ae95a in mainline


Ignore:
Timestamp:
2017-07-02T16:22:09Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a927398
Parents:
ee50130
Message:

mkfat needs to be able to set the volume label. fat FS should ignore volume label in the boot sector.

Location:
uspace
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/mkfat/mkfat.c

    ree50130 rf4ae95a  
    3838 */
    3939
     40#include <ctype.h>
    4041#include <stdio.h>
    4142#include <stdlib.h>
     
    4849#include <errno.h>
    4950#include "fat.h"
     51#include "fat_dentry.h"
    5052
    5153#define NAME    "mkfat"
     54
     55#define LABEL_NONAME "NO NAME"
    5256
    5357/** Divide and round up. */
     
    7781        uint32_t total_clusters;
    7882        uint8_t fat_count;
     83        const char *label;
    7984} fat_cfg_t;
    8085
     
    102107        cfg.root_ent_max = 128;
    103108        cfg.fat_type = FATAUTO;
     109        cfg.label = NULL;
    104110
    105111        if (argc < 2) {
     
    142148                        return 1;
    143149                }
     150
     151                --argc; ++argv;
     152        }
     153
     154        if (str_cmp(*argv, "--label") == 0) {
     155                --argc; ++argv;
     156                if (*argv == NULL) {
     157                        printf(NAME ": Error, argument missing.\n");
     158                        syntax_print();
     159                        return 1;
     160                }
     161
     162                cfg.label = *argv;
    144163
    145164                --argc; ++argv;
     
    216235static void syntax_print(void)
    217236{
    218         printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] <device_name>\n");
     237        printf("syntax: mkfat [--size <sectors>] [--type 12|16|32] "
     238            "[--label <label>] <device_name>\n");
     239}
     240
     241static int fat_label_encode(void *dest, const char *src)
     242{
     243        int i;
     244        const char *sp;
     245        uint8_t *dp;
     246
     247        i = 0;
     248        sp = src;
     249        dp = (uint8_t *)dest;
     250
     251        while (*sp != '\0' && i < FAT_VOLLABEL_LEN) {
     252                if (!ascii_check(*sp))
     253                        return EINVAL;
     254                if (dp != NULL)
     255                        dp[i] = toupper(*sp);
     256                ++i; ++sp;
     257        }
     258
     259        while (i < FAT_VOLLABEL_LEN) {
     260                if (dp != NULL)
     261                        dp[i] = FAT_PAD;
     262                ++i;
     263        }
     264
     265        return EOK;
    219266}
    220267
     
    241288                        cfg->sector_size);
    242289        } else
    243                 cfg->rootdir_sectors = 0;
     290                cfg->rootdir_sectors = cfg->sectors_per_cluster;
    244291        non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
    245292
     
    268315        cfg->fat_sectors = div_round_up(fat_bytes, cfg->sector_size);
    269316
     317        if (cfg->label != NULL && fat_label_encode(NULL, cfg->label) != EOK)
     318                return EINVAL;
     319
    270320        return EOK;
    271321}
     
    280330        int rc;
    281331        struct fat_bs bs;
     332        fat_dentry_t *de;
    282333
    283334        fat_bootsec_create(cfg, &bs);
     
    339390        printf("Writing root directory.\n");
    340391        memset(buffer, 0, cfg->sector_size);
    341         if (cfg->fat_type != FAT32) {
    342                 size_t idx;
    343                 for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
    344                         rc = block_write_direct(service_id, addr, 1, buffer);
    345                         if (rc != EOK)
    346                                 return EIO;
    347 
    348                         ++addr;
    349                 }
    350         } else {
    351                 for (i = 0; i < cfg->sectors_per_cluster; i++) {
    352                         rc = block_write_direct(service_id, addr, 1, buffer);
    353                         if (rc != EOK)
    354                                 return EIO;
    355 
    356                         ++addr;
    357                 }       
     392        de = (fat_dentry_t *)buffer;
     393        size_t idx;
     394        for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
     395
     396                if (idx == 0 && cfg->label != NULL) {
     397                        /* Set up volume label entry */
     398                        (void) fat_label_encode(&de->name, cfg->label);
     399                        de->attr = FAT_ATTR_VOLLABEL;
     400                        de->mtime = 0x1234;
     401                        de->mdate = 0x1234;
     402                } else if (idx == 1) {
     403                        /* Clear volume label entry */
     404                        memset(buffer, 0, cfg->sector_size);
     405                }
     406
     407                rc = block_write_direct(service_id, addr, 1, buffer);
     408                if (rc != EOK)
     409                        return EIO;
     410
     411                ++addr;
    358412        }
    359413
     
    366420static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs)
    367421{
     422        const char *bs_label;
     423
     424        /*
     425         * The boot sector must always contain a valid label. If there
     426         * is no label, there should be 'NO NAME'
     427         */
     428        if (cfg->label != NULL)
     429                bs_label = cfg->label;
     430        else
     431                bs_label = LABEL_NONAME;
    368432        memset(bs, 0, sizeof(*bs));
    369433
     
    404468                bs->fat32.root_cluster = 2;
    405469
    406                 memcpy(bs->fat32.label, "HELENOS_NEW", 11);
     470                (void) fat_label_encode(&bs->fat32.label, bs_label);
    407471                memcpy(bs->fat32.type, "FAT32   ", 8);
    408472        } else {
     
    412476                bs->id = host2uint32_t_be(0x12345678);
    413477
    414                 memcpy(bs->label, "HELENOS_NEW", 11);
     478                (void) fat_label_encode(&bs->label, bs_label);
    415479                memcpy(bs->type, "FAT   ", 8);
    416480        }
  • uspace/srv/fs/fat/fat_dentry.h

    ree50130 rf4ae95a  
    3535#define FAT_FAT_DENTRY_H_
    3636
     37#include <ctype.h>
    3738#include <stdint.h>
    3839#include <stdbool.h>
  • uspace/srv/fs/fat/fat_ops.c

    ree50130 rf4ae95a  
    10391039static int fat_fsprobe(service_id_t service_id, vfs_fs_probe_info_t *info)
    10401040{
    1041         fat_bs_t *bs;
    10421041        fat_idx_t *ridxp;
    10431042        fs_node_t *rfn;
     
    10451044        fat_directory_t di;
    10461045        char label[FAT_VOLLABEL_LEN + 1];
    1047         int i;
    10481046        int rc;
    10491047
     
    10601058        rc = fat_directory_vollabel_get(&di, label);
    10611059        if (rc != EOK) {
    1062                 /* No label in root directory. Read label from the BS */
    1063                 bs = block_bb_get(service_id);
    1064                 i = FAT_VOLLABEL_LEN;
    1065                 while (i > 0 && bs->label[i - 1] == FAT_PAD)
    1066                         --i;
    1067 
    1068                 /* XXX Deal with non-ASCII characters */
    1069                 memcpy(label, bs->label, i);
    1070                 label[i] = '\0';
     1060                if (rc != ENOENT)
     1061                        return rc;
     1062
     1063                label[0] = '\0';
    10711064        }
    10721065
Note: See TracChangeset for help on using the changeset viewer.