~youscribe/parted/3.1

« back to all changes in this revision

Viewing changes to libparted/labels/loop.c

  • Committer: Guilhem Lettron
  • Date: 2012-10-22 14:37:59 UTC
  • Revision ID: guilhem+ubuntu@lettron.fr-20121022143759-m403kecgz13sknvp
3.1 from tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    libparted - a library for manipulating disk partitions
 
3
    Copyright (C) 1999-2000, 2007-2012 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/debug.h>
 
23
#include <parted/endian.h>
 
24
#include <stdbool.h>
 
25
 
 
26
#include "pt-tools.h"
 
27
 
 
28
#if ENABLE_NLS
 
29
#  include <libintl.h>
 
30
#  define _(String) dgettext (PACKAGE, String)
 
31
#else
 
32
#  define _(String) (String)
 
33
#endif /* ENABLE_NLS */
 
34
 
 
35
#define LOOP_SIGNATURE          "GNU Parted Loopback 0"
 
36
 
 
37
static PedDiskType loop_disk_type;
 
38
 
 
39
static PedDisk* loop_alloc (const PedDevice* dev);
 
40
static void loop_free (PedDisk* disk);
 
41
 
 
42
static int
 
43
loop_probe (const PedDevice* dev)
 
44
{
 
45
        PedDisk *disk = loop_alloc (dev);
 
46
        if (!disk)
 
47
                goto error;
 
48
 
 
49
        void *buf;
 
50
        if (!ptt_read_sector (dev, 0, &buf))
 
51
                goto error_destroy_disk;
 
52
        int found_sig = !strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE));
 
53
        free (buf);
 
54
 
 
55
        int result;
 
56
        if (found_sig) {
 
57
                result = 1;
 
58
        } else {
 
59
                PedGeometry*    geom;
 
60
 
 
61
                geom = ped_geometry_new (dev, 0, disk->dev->length);
 
62
                if (!geom)
 
63
                        goto error_destroy_disk;
 
64
                result = ped_file_system_probe (geom) != NULL;
 
65
                ped_geometry_destroy (geom);
 
66
        }
 
67
        loop_free (disk);
 
68
        return result;
 
69
 
 
70
error_destroy_disk:
 
71
        loop_free (disk);
 
72
error:
 
73
        return 0;
 
74
}
 
75
 
 
76
static PedDisk*
 
77
loop_alloc (const PedDevice* dev)
 
78
{
 
79
        PED_ASSERT (dev != NULL);
 
80
 
 
81
        if (dev->length < 256)
 
82
                return NULL;
 
83
        return _ped_disk_alloc ((PedDevice*)dev, &loop_disk_type);
 
84
}
 
85
 
 
86
static PedDisk*
 
87
loop_duplicate (const PedDisk* disk)
 
88
{
 
89
        return ped_disk_new_fresh (disk->dev, &loop_disk_type);
 
90
}
 
91
 
 
92
static void
 
93
loop_free (PedDisk* disk)
 
94
{
 
95
        PED_ASSERT (disk != NULL);
 
96
 
 
97
        _ped_disk_free (disk);
 
98
}
 
99
 
 
100
static int
 
101
loop_read (PedDisk* disk)
 
102
{
 
103
        PedDevice*              dev = NULL;
 
104
        PedGeometry*            geom;
 
105
        PedFileSystemType*      fs_type;
 
106
        PedPartition*           part;
 
107
        PedConstraint*          constraint_any;
 
108
 
 
109
        PED_ASSERT (disk != NULL);
 
110
        dev = disk->dev;
 
111
        constraint_any = ped_constraint_any (dev);
 
112
 
 
113
        ped_disk_delete_all (disk);
 
114
 
 
115
        void *buf;
 
116
        if (!ptt_read_sector (dev, 0, &buf))
 
117
                goto error;
 
118
 
 
119
        int found_sig = !strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE));
 
120
        free (buf);
 
121
 
 
122
        if (found_sig) {
 
123
                ped_constraint_destroy (constraint_any);
 
124
                return 1;
 
125
        }
 
126
 
 
127
        geom = ped_geometry_new (dev, 0, dev->length);
 
128
        if (!geom)
 
129
                goto error;
 
130
 
 
131
        fs_type = ped_file_system_probe (geom);
 
132
        if (!fs_type)
 
133
                goto error_free_geom;
 
134
 
 
135
        part = ped_partition_new (disk, PED_PARTITION_NORMAL,
 
136
                                  fs_type, geom->start, geom->end);
 
137
        ped_geometry_destroy (geom);
 
138
        if (!part)
 
139
                goto error;
 
140
        part->fs_type = fs_type;
 
141
 
 
142
        if (!ped_disk_add_partition (disk, part, constraint_any))
 
143
                goto error;
 
144
        ped_constraint_destroy (constraint_any);
 
145
        return 1;
 
146
 
 
147
error_free_geom:
 
148
        ped_geometry_destroy (geom);
 
149
error:
 
150
        ped_constraint_destroy (constraint_any);
 
151
        return 0;
 
152
}
 
153
 
 
154
#ifndef DISCOVER_ONLY
 
155
static int
 
156
loop_write (const PedDisk* disk)
 
157
{
 
158
        size_t buflen = disk->dev->sector_size;
 
159
        char *buf = ped_malloc (buflen);
 
160
        if (buf == NULL)
 
161
                return 0;
 
162
 
 
163
        if (ped_disk_get_partition (disk, 1)) {
 
164
                if (!ped_device_read (disk->dev, buf, 0, 1)) {
 
165
                        free (buf);
 
166
                        return 0;
 
167
                }
 
168
                if (strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE)) != 0) {
 
169
                        free (buf);
 
170
                        return 1;
 
171
                }
 
172
                memset (buf, 0, strlen (LOOP_SIGNATURE));
 
173
                return ped_device_write (disk->dev, buf, 0, 1);
 
174
        }
 
175
 
 
176
        memset (buf, 0, buflen);
 
177
        strcpy (buf, LOOP_SIGNATURE);
 
178
 
 
179
        int write_ok = ped_device_write (disk->dev, buf, 0, 1);
 
180
        free (buf);
 
181
        return write_ok;
 
182
}
 
183
#endif /* !DISCOVER_ONLY */
 
184
 
 
185
static PedPartition*
 
186
loop_partition_new (const PedDisk* disk, PedPartitionType part_type,
 
187
                    const PedFileSystemType* fs_type,
 
188
                    PedSector start, PedSector end)
 
189
{
 
190
        PedPartition*   part;
 
191
 
 
192
        part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
 
193
        if (!part)
 
194
                return NULL;
 
195
        part->disk_specific = NULL;
 
196
        return part;
 
197
}
 
198
 
 
199
static PedPartition*
 
200
loop_partition_duplicate (const PedPartition* part)
 
201
{
 
202
        PedPartition* result;
 
203
 
 
204
        result = ped_partition_new (part->disk, part->type, part->fs_type,
 
205
                                    part->geom.start, part->geom.end);
 
206
        if (result == NULL)
 
207
                return NULL;
 
208
        result->num = part->num;
 
209
        return result;
 
210
}
 
211
 
 
212
static void
 
213
loop_partition_destroy (PedPartition* part)
 
214
{
 
215
        free (part);
 
216
}
 
217
 
 
218
static int
 
219
loop_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
 
220
{
 
221
        part->fs_type = fs_type;
 
222
        return 1;
 
223
}
 
224
 
 
225
static int
 
226
loop_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
 
227
{
 
228
        return 0;
 
229
}
 
230
 
 
231
static int
 
232
loop_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
 
233
{
 
234
        return 0;
 
235
}
 
236
 
 
237
static int
 
238
loop_partition_align (PedPartition* part, const PedConstraint* constraint)
 
239
{
 
240
        PedGeometry*    new_geom;
 
241
 
 
242
        new_geom = ped_constraint_solve_nearest (constraint, &part->geom);
 
243
        if (!new_geom) {
 
244
                ped_exception_throw (
 
245
                        PED_EXCEPTION_ERROR,
 
246
                        PED_EXCEPTION_CANCEL,
 
247
                        _("Unable to satisfy all constraints on the "
 
248
                          "partition."));
 
249
                return 0;
 
250
        }
 
251
        ped_geometry_set (&part->geom, new_geom->start, new_geom->length);
 
252
        ped_geometry_destroy (new_geom);
 
253
        return 1;
 
254
}
 
255
 
 
256
static int
 
257
loop_partition_is_flag_available (const PedPartition* part,
 
258
                                  PedPartitionFlag flag)
 
259
{
 
260
        return 0;
 
261
}
 
262
 
 
263
static int
 
264
loop_partition_enumerate (PedPartition* part)
 
265
{
 
266
        part->num = 1;
 
267
        return 1;
 
268
}
 
269
 
 
270
static int
 
271
loop_alloc_metadata (PedDisk* disk)
 
272
{
 
273
        return 1;
 
274
}
 
275
 
 
276
static int
 
277
loop_get_max_primary_partition_count (const PedDisk* disk)
 
278
{
 
279
        return 1;
 
280
}
 
281
 
 
282
static bool
 
283
loop_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
 
284
{
 
285
        *max_n = 1;
 
286
        return true;
 
287
}
 
288
 
 
289
#include "pt-common.h"
 
290
PT_define_limit_functions (loop)
 
291
 
 
292
static PedDiskOps loop_disk_ops = {
 
293
        clobber:                NULL,
 
294
        write:                  NULL_IF_DISCOVER_ONLY (loop_write),
 
295
 
 
296
        partition_set_name:     NULL,
 
297
        partition_get_name:     NULL,
 
298
 
 
299
        PT_op_function_initializers (loop)
 
300
};
 
301
 
 
302
static PedDiskType loop_disk_type = {
 
303
        next:           NULL,
 
304
        name:           "loop",
 
305
        ops:            &loop_disk_ops,
 
306
        features:       0
 
307
};
 
308
 
 
309
void
 
310
ped_disk_loop_init ()
 
311
{
 
312
        ped_disk_type_register (&loop_disk_type);
 
313
}
 
314
 
 
315
void
 
316
ped_disk_loop_done ()
 
317
{
 
318
        ped_disk_type_unregister (&loop_disk_type);
 
319
}