/*
libparted - a library for manipulating disk partitions
- Copyright (C) 1999 - 2001, 2005, 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 1999 - 2001, 2005, 2007-2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <limits.h>
#include <unistd.h>
+#include <stdlib.h>
#include <errno.h>
#include "architecture.h"
under section 6.7.8 part 10
of ISO/EIC 9899:1999 */
-#ifndef HAVE_CANONICALIZE_FILE_NAME
-char *
-canonicalize_file_name (const char *name)
-{
- char * buf;
- int size;
- char * result;
-
-#ifdef PATH_MAX
- size = PATH_MAX;
-#else
- /* Bigger is better; realpath has no way todo bounds checking. */
- size = 4096;
-#endif
-
- /* Just in case realpath does not NULL terminate the string
- * or it just fits in SIZE without a NULL terminator. */
- buf = calloc (size + 1, sizeof(char));
- if (! buf) {
- errno = ENOMEM;
- return NULL;
- }
-
- result = realpath (name, buf);
- if (! result)
- free (buf);
-
- return result;
-}
-#endif /* !HAVE_CANONICALIZE_FILE_NAME */
-
static void
_device_register (PedDevice* dev)
{
if (walk == dev) break;
}
+ /* This function may be called twice for the same device if a
+ libparted user explictly removes the device from the cache using
+ ped_device_cache_remove(), we get called and it then becomes the
+ user's responsibility to free the PedDevice by calling
+ ped_device_destroy().
+ ped_device_destroy() will then call us a second time, so if the
+ device is not found in the list do nothing. */
+ if (walk == NULL)
+ return;
+
if (last)
last->next = dev->next;
else
ped_device_get (const char* path)
{
PedDevice* walk;
- char* normal_path;
+ char* normal_path = NULL;
PED_ASSERT (path != NULL, return NULL);
- normal_path = canonicalize_file_name (path);
+ /* Don't canonicalize /dev/mapper paths, see tests/symlink.c */
+ if (strncmp (path, "/dev/mapper/", 12))
+ normal_path = canonicalize_file_name (path);
if (!normal_path)
/* Well, maybe it is just that the file does not exist.
* Try it anyway. */
* constraint.
*/
PedConstraint*
-ped_device_get_constraint (PedDevice* dev)
+ped_device_get_constraint (const PedDevice* dev)
{
PedGeometry *s, *e;
PedConstraint* c = ped_constraint_new (
return c;
}
+static PedConstraint*
+_ped_device_get_aligned_constraint(const PedDevice *dev,
+ PedAlignment* start_align)
+{
+ PedAlignment *end_align = NULL;
+ PedGeometry *whole_dev_geom = NULL;
+ PedConstraint *c = NULL;
+
+ if (start_align) {
+ end_align = ped_alignment_new(start_align->offset - 1,
+ start_align->grain_size);
+ if (!end_align)
+ goto free_start_align;
+ }
+
+ whole_dev_geom = ped_geometry_new (dev, 0, dev->length);
+
+ if (start_align)
+ c = ped_constraint_new (start_align, end_align,
+ whole_dev_geom, whole_dev_geom,
+ 1, dev->length);
+ else
+ c = ped_constraint_new (ped_alignment_any, ped_alignment_any,
+ whole_dev_geom, whole_dev_geom,
+ 1, dev->length);
+
+ free (whole_dev_geom);
+ free (end_align);
+free_start_align:
+ free (start_align);
+ return c;
+}
+
+/**
+ * Get a constraint that represents hardware requirements on geometry and
+ * alignment.
+ *
+ * This function will return a constraint representing the limits imposed
+ * by the size of the disk and the minimal alignment requirements for proper
+ * performance of the disk.
+ *
+ * \return NULL on error, otherwise a pointer to a dynamically allocated
+ * constraint.
+ */
+PedConstraint*
+ped_device_get_minimal_aligned_constraint(const PedDevice *dev)
+{
+ return _ped_device_get_aligned_constraint(dev,
+ ped_device_get_minimum_alignment(dev));
+}
+
+/**
+ * Get a constraint that represents hardware requirements on geometry and
+ * alignment.
+ *
+ * This function will return a constraint representing the limits imposed
+ * by the size of the disk and the alignment requirements for optimal
+ * performance of the disk.
+ *
+ * \return NULL on error, otherwise a pointer to a dynamically allocated
+ * constraint.
+ */
+PedConstraint*
+ped_device_get_optimal_aligned_constraint(const PedDevice *dev)
+{
+ return _ped_device_get_aligned_constraint(dev,
+ ped_device_get_optimum_alignment(dev));
+}
+
/**
* Get an alignment that represents minimum hardware requirements on alignment.
* When for example using media that has a physical sector size that is a
PedAlignment*
ped_device_get_minimum_alignment(const PedDevice *dev)
{
+ PedAlignment *align = NULL;
+
if (ped_architecture->dev_ops->get_minimum_alignment)
- return ped_architecture->dev_ops->get_minimum_alignment(dev);
+ align = ped_architecture->dev_ops->get_minimum_alignment(dev);
- return NULL; /* ped_alignment_none */
+ if (align == NULL)
+ align = ped_alignment_new(0,
+ dev->phys_sector_size / dev->sector_size);
+
+ return align;
}
/**
PedAlignment*
ped_device_get_optimum_alignment(const PedDevice *dev)
{
- if (ped_architecture->dev_ops->get_optimum_alignment)
- return ped_architecture->dev_ops->get_optimum_alignment(dev);
+ PedAlignment *align = NULL;
- return NULL; /* ped_alignment_none */
+ if (ped_architecture->dev_ops->get_optimum_alignment)
+ align = ped_architecture->dev_ops->get_optimum_alignment(dev);
+
+ /* If the arch specific code could not give as an alignment
+ return a default value based on the type of device. */
+ if (align == NULL) {
+ switch (dev->type) {
+ case PED_DEVICE_DASD:
+ align = ped_device_get_minimum_alignment(dev);
+ break;
+ default:
+ /* Align to a grain of 1MiB (like vista / win7) */
+ align = ped_alignment_new(0,
+ (PED_DEFAULT_ALIGNMENT
+ / dev->sector_size));
+ }
+ }
+
+ return align;
}
/** @} */
-