OSDN Git Service

2ebc0080cf5dda364f81be988dbfbc4a0095f989
[android-x86/external-parted.git] / libparted / fs / bfs / bfs.c
1 /*
2     libparted - a library for manipulating disk partitions
3     Copyright (C) 2005, 2007, 2009-2010 Free Software Foundation, Inc.
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <config.h>
20
21 #include <parted/parted.h>
22 #include <parted/endian.h>
23 #include <parted/debug.h>
24
25 #if ENABLE_NLS
26 #  include <libintl.h>
27 #  define _(String) dgettext (PACKAGE, String)
28 #else
29 #  define _(String) (String)
30 #endif /* ENABLE_NLS */
31
32 #include <unistd.h>
33
34 #include "bfs.h"
35
36
37 #define BFS_SPECIFIC(fs) ((struct BfsSpecific*) (fs->type_specific))
38 #define BFS_SB(fs)       (BFS_SPECIFIC(fs)->sb)
39
40
41 const char BFS_MAGIC[4] = { 0x1B, 0xAD, 0xFA, 0xCE };
42 const long long BFS_SECTOR_SIZE         = 512;
43 const uint32_t  BFS_PED_SANITY          = 0xffffffff;
44 const long long BFS_PED_MIN_INODES      = 16;
45
46 static PedGeometry*
47 bfs_probe (PedGeometry* geom)
48 {
49         uint8_t*        buf;
50
51         PED_ASSERT (geom      != NULL, return NULL);
52         PED_ASSERT (geom->dev != NULL, return NULL);
53
54         buf = ped_malloc (geom->dev->sector_size);
55
56         if (!ped_geometry_read (geom, buf, 0, 1))
57                 return 0;
58
59         //if ( PED_CPU_TO_LE32((uint32_t)buf) == BFS_MAGIC )
60                 return ped_geometry_new (geom->dev, geom->start,
61                                 ped_div_round_up (
62                                         PED_CPU_TO_LE32((uint32_t)(buf+8)),
63                                         geom->dev->sector_size));
64         else
65                 return NULL;
66 }
67
68 #ifndef DISCOVER_ONLY
69 static int
70 bfs_clobber (PedGeometry* geom)
71 {
72         uint8_t*  buf;
73
74         PED_ASSERT (geom      != NULL, return 0);
75         PED_ASSERT (geom->dev != NULL, return 0);
76
77         buf = ped_malloc (geom->dev->sector_size);
78
79         if (!ped_geometry_read (geom, buf, 0, 1))
80                 return 0;
81         memset (buf, 0, 512);
82         return ped_geometry_write (geom, buf, 0, 1);
83 }
84 #endif /* !DISCOVER_ONLY */
85
86
87 static PedFileSystem*
88 bfs_alloc (const PedGeometry* geom)
89 {
90         PedFileSystem*  fs;
91
92         fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
93         if (!fs)
94                 goto error;
95
96         fs->type_specific = (struct BfsSpecific*) ped_malloc (
97                         sizeof (struct BfsSpecific));
98         if (!fs->type_specific)
99                 goto error_free_fs;
100
101         fs->geom = ped_geometry_duplicate (geom);
102         if (!fs->geom)
103                 goto error_free_type_specific;
104
105         fs->checked = 0;
106         return fs;
107
108 error_free_type_specific:
109         free (fs->type_specific);
110 error_free_fs:
111         free (fs);
112 error:
113         return NULL;
114 }
115
116
117 void
118 bfs_free (PedFileSystem* fs)
119 {
120         ped_geometry_destroy (fs->geom);
121         free (fs->type_specific);
122         free (fs);
123 }
124
125
126 static PedFileSystem*
127 bfs_open (PedGeometry *geom)
128 {
129         PedFileSystem* fs = bfs_alloc (geom);
130
131         struct bfs_sb* sb = (struct bfs_sb*) ped_malloc(sizeof(struct bfs_sb));
132         struct BfsSpecific* bfs;
133         uint8_t* buf;
134
135         PED_ASSERT (geom      != NULL, return NULL);
136         PED_ASSERT (geom->dev != NULL, return NULL);
137
138         buf = ped_malloc (geom->dev->sector_size);
139
140         if (!fs)
141                 return NULL;
142
143         bfs = fs->type_specific;
144
145         if (!ped_geometry_read (geom, buf, 0, 1))
146                 return NULL;
147
148         memcpy (sb, buf, BFS_SECTOR_SIZE);
149
150         bfs->sb = sb;
151
152         return fs;
153 }
154
155
156 #ifndef DISCOVER_ONLY
157 static struct bfs_inode* create_root_inode()
158 {
159         struct bfs_inode* root = ped_malloc (sizeof(struct bfs_inode));
160
161         root->i = 2UL;
162         /*root->start = FIX;
163         root->end = ;
164         root->eof_off = ;*/
165         root->attr = 2UL;
166         root->mode = 512UL; /* rwxrwxrwx */
167         root->uid = root->gid = 0UL;
168         root->nlinks = 0UL;
169         root->atime = root->ctime = 0UL;
170         memset ((void*)root->reserved, 0, 32*4);
171
172         return root;
173 }
174
175
176 static uint8_t* _block_alloc (int n)
177 {
178         return ped_calloc (n * BFS_SECTOR_SIZE);
179 }
180
181
182 static void _write_inodes (PedFileSystem* fs)
183 {
184 }
185
186
187 /* write a BFS block - always 512 bytes */
188 static int _write_block (PedFileSystem* fs, uint8_t* buf, int n)
189 {
190         /* FIXME: support for bs != 2^9 */
191         return ped_geometry_write ( fs->geom, buf, n, 1 );
192 }
193
194
195 static int _write_sb (PedFileSystem* fs)
196 {
197         uint8_t* sb = _block_alloc (1);
198
199         BFS_SB(fs)->magic  = BFS_MAGIC;
200         BFS_SB(fs)->sanity = BFS_PED_SANITY;
201         BFS_SB(fs)->start  = BFS_SPECIFIC(fs)->data_start;
202         BFS_SB(fs)->size   = BFS_SPECIFIC(fs)->size;
203
204         memcpy (sb, BFS_SB(fs), sizeof(struct bfs_sb));
205
206         return _write_block (fs, sb, 1);
207 }
208
209
210 static PedFileSystem*
211 bfs_create (PedGeometry *geom, PedTimer *timer)
212 {
213         PedFileSystem* fs = bfs_alloc (geom);
214         int n_inodes = PED_MAX (BFS_PED_MIN_INODES, 16/*some sane value here*/);
215
216         /* TODO: check whether geometry is big enough */
217
218         fs->data_start = 1 + ped_round_up_to (n_inodes * 64, 512);
219         fs->size = geom->dev->sector_size * length;
220
221         ped_timer_set_state_name (timer, "Writing inodes");
222
223
224
225         ped_timer_set_state_name (timer, "Writing super block");
226         _write_sb (fs);
227
228         return 0;
229 }
230 #endif /* !DISCOVER_ONLY */
231
232
233 static PedFileSystemOps bfs_ops = {
234         probe:          bfs_probe,
235 #ifndef DISCOVER_ONLY
236         clobber:        bfs_clobber,
237 #else
238         clobber:        NULL,
239 #endif
240         open:           bfs_open,
241 #ifndef DISCOVER_ONLY
242         create:         bfs_create,
243 #else
244         create:         NULL
245 #endif
246         close:          NULL,
247         check:          NULL,
248         copy:           NULL,
249         resize:         NULL,
250         get_create_constraint:  NULL,
251         get_resize_constraint:  NULL,
252         get_copy_constraint:    NULL
253 };
254
255 static PedFileSystemType bfs_type = {
256         next:           NULL,
257         ops:            &bfs_ops,
258         name:           "bfs",
259         block_sizes:    ((int[2]){512, 0})
260 };
261
262 void
263 ped_file_system_bfs_init ()
264 {
265         ped_file_system_type_register (&bfs_type);
266 }
267
268 void
269 ped_file_system_bfs_done ()
270 {
271         ped_file_system_type_unregister (&bfs_type);
272 }