embox

Форк
0
/
fatfs_drv.c 
179 строк · 3.4 Кб
1
/**
2
 * @file
3
 * @brief Implementation of FAT driver
4
 *
5
 * @date 28.03.2012
6
 * @author Andrey Gazukin
7
 */
8

9
#include <util/log.h>
10

11
#include <errno.h>
12
#include <stdio.h>
13
#include <string.h>
14
#include <stdlib.h>
15
#include <fcntl.h>
16
#include <limits.h>
17
#include <libgen.h>
18

19
#include <util/err.h>
20

21
#include <fs/file_desc.h>
22
#include <fs/super_block.h>
23
#include <fs/fs_driver.h>
24
#include <fs/inode_operation.h>
25
#include <fs/inode.h>
26

27
#include <drivers/block_dev.h>
28

29
#include "fat.h"
30

31
/* FIXME bdev_by_path is declared in dvfs.h and fs/mount.h */
32
extern struct block_dev *bdev_by_path(const char *source);
33

34
extern struct file_operations fat_fops;
35

36
extern int fat_clean_sb(struct super_block *sb);
37
extern int fat_create(struct inode *i_new, struct inode *i_dir, int mode);
38

39

40

41
#define DEFAULT_FAT_VERSION OPTION_GET(NUMBER, default_fat_version)
42
/**
43
 * @brief Format given block device
44
 * @param dev Pointer to device
45
 * @note Should be block device
46
 *
47
 * @return Negative error code or 0 if succeed
48
 */
49
int fat_format(struct block_dev *dev, void *priv) {
50
	int fat_n = priv ? atoi((char*) priv) : 0;
51
	struct block_dev *bdev = dev;
52

53
	assert(dev);
54

55
	if (!fat_n) {
56
		fat_n = DEFAULT_FAT_VERSION;
57
	}
58

59
	if (fat_n != 12 && fat_n != 16 && fat_n != 32) {
60
		log_error("Unsupported FAT version: FAT%d "
61
				"(FAT12/FAT16/FAT32 available)", fat_n);
62
		return -EINVAL;
63
	}
64

65
	fat_create_partition(bdev, fat_n);
66
	fat_root_dir_record(bdev);
67

68
	return 0;
69
}
70

71
extern struct inode_operations fat_iops;
72
extern struct super_block_operations fat_sbops;
73
extern struct file_operations fat_fops;
74
/* @brief Initializing fat super_block
75
 * @param sb  Structure to be initialized
76
 * @param dev Storage device
77
 *
78
 * @return Negative error code
79
 */
80
int fat_fill_sb(struct super_block *sb, const char *source) {
81
	struct fat_fs_info *fsi;
82
	struct block_dev *bdev;
83
	uint32_t pstart, psize;
84
	uint8_t pactive, ptype;
85
	struct dirinfo *di = NULL;
86
	int rc = 0;
87

88
	assert(sb);
89

90
	bdev = bdev_by_path(source);
91
	if (!bdev) {
92
		/* FAT always uses block device, so we can't fill superblock */
93
		return -ENOENT;
94
	}
95

96
	fsi = fat_fs_alloc();
97
	*fsi = (struct fat_fs_info) {
98
		.bdev = bdev,
99
	};
100
	sb->sb_data = fsi;
101
	sb->sb_iops = &fat_iops;
102
	sb->sb_fops = &fat_fops;
103
	sb->sb_ops  = &fat_sbops;
104
	sb->bdev    = bdev;
105

106
	/* Obtain pointer to first partition on first (only) unit */
107
	pstart = fat_get_ptn_start(bdev, 0, &pactive, &ptype, &psize);
108
	if (pstart == 0xffffffff) {
109
		rc = -EINVAL;
110
		goto error;
111
	}
112

113
	if (fat_get_volinfo(bdev, &fsi->vi, pstart)) {
114
		rc = -EBUSY;
115
		goto error;
116
	}
117

118
	if (NULL == (di = fat_dirinfo_alloc())) {
119
		rc = -ENOMEM;
120
		goto error;
121
	}
122
	memset(di, 0, sizeof(struct dirinfo));
123
	di->p_scratch = fat_sector_buff;
124

125
	if (fat_open_rootdir(fsi, di)) {
126
		rc = -EBUSY;
127
		goto error;
128
	}
129

130
	di->fi.fsi = fsi;
131
	di->fi.volinfo = &fsi->vi;
132

133
	inode_priv_set(sb->sb_root, di);
134
	sb->sb_root->i_ops = &fat_iops;
135

136
	return 0;
137

138
error:
139
	if (di) {
140
		fat_dirinfo_free(di);
141
	}
142

143
	fat_fs_free(fsi);
144
	return rc;
145
}
146

147
/**
148
 * @brief Cleanup FS-specific stuff. No need to clean all files: VFS should
149
 * do it by itself
150
 *
151
 * @param sb Pointer to superblock
152
 *
153
 * @return Negative error code or 0 if succeed
154
 */
155
int fat_clean_sb(struct super_block *sb) {
156
	struct fat_fs_info *fsi;
157

158
	assert(sb);
159

160
	fsi = sb->sb_data;
161

162
	assert(fsi);
163

164
	fat_fs_free(fsi);
165

166
	fat_dirinfo_free(inode_priv(sb->sb_root));
167

168
	return 0;
169
}
170

171

172
static const struct fs_driver fatfs_driver = {
173
	.name     = "vfat",
174
	.format = fat_format,
175
	.fill_sb  = fat_fill_sb,
176
	.clean_sb = fat_clean_sb,
177
};
178

179
DECLARE_FILE_SYSTEM_DRIVER(fatfs_driver);
180

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.