[PATCH 3/8] dosfs: Add skip_aligment for msdos_format()
Gedare Bloom
gedare at rtems.org
Thu Nov 29 17:06:35 UTC 2012
On Thu, Nov 29, 2012 at 9:32 AM, Ralf Kirchner <
ralf.kirchner at embedded-brains.de> wrote:
> Add skip_aligment parameter of msdos_format_request_param_t. Delete
> cluster_align parameter of msdos_format_request_param_t.
>
> By default the FAT, data cluster, and root directory for FAT12 and FAT16
> is aligned on a cluster boundary to optimize performance.
>
> Format changes throughout.
> ---
> cpukit/libfs/src/dosfs/dosfs.h | 9 +-
> cpukit/libfs/src/dosfs/fat.h | 1 +
> cpukit/libfs/src/dosfs/msdos_format.c | 231
> ++++++++++++++----------
> cpukit/libmisc/shell/main_msdosfmt.c | 4 +-
> testsuites/fstests/mdosfs_support/fs_support.c | 2 +-
> 5 Dateien geändert, 143 Zeilen hinzugefügt(+), 104 Zeilen entfernt(-)
>
> diff --git a/cpukit/libfs/src/dosfs/dosfs.h
> b/cpukit/libfs/src/dosfs/dosfs.h
> index 93d7789..530d23e 100644
> --- a/cpukit/libfs/src/dosfs/dosfs.h
> +++ b/cpukit/libfs/src/dosfs/dosfs.h
> @@ -49,12 +49,9 @@ typedef struct {
> uint8_t fattype; /* request value: MSDOS_FMT_FAT12/16/32
> */
> uint8_t media; /* media code. default: 0xF8
> */
> bool quick_format; /* true: do not clear out data sectors
> */
> - uint32_t cluster_align; /* requested value: cluster alignment
> */
> - /* make sector number of first sector
> */
> - /* of first cluster divisible by this
> */
> - /* value. This can optimize clusters
> */
> - /* to be located at start of track
> */
> - /* or start of flash block
> */
> + bool skip_alignment; /* do not align FAT, data cluster, and
> */
> + /* root directory for FAT12 and FAT16
> to */
> + /* a cluster boundary
> */
> int info_level; /* The amount of info to output
> */
> } msdos_format_request_param_t;
>
> diff --git a/cpukit/libfs/src/dosfs/fat.h b/cpukit/libfs/src/dosfs/fat.h
> index 260d8aa..dab2471 100644
> --- a/cpukit/libfs/src/dosfs/fat.h
> +++ b/cpukit/libfs/src/dosfs/fat.h
> @@ -271,6 +271,7 @@ extern "C" {
> #define FAT_TOTAL_FSINFO_SIZE 512
>
> #define MS_BYTES_PER_CLUSTER_LIMIT 0x8000 /* 32K */
> +#define MS_BYTES_PER_CLUSTER_LIMIT_FAT12 0x1000 /* 4K */
>
> #define FAT_BR_EXT_FLAGS_MIRROR 0x0080
>
> diff --git a/cpukit/libfs/src/dosfs/msdos_format.c
> b/cpukit/libfs/src/dosfs/msdos_format.c
> index 974c00d..e8107a2 100644
> --- a/cpukit/libfs/src/dosfs/msdos_format.c
> +++ b/cpukit/libfs/src/dosfs/msdos_format.c
> @@ -64,9 +64,24 @@ typedef struct {
> char VolLabel[FAT_BR_VOLLAB_SIZE+1];
> bool VolLabel_present;
> uint32_t vol_id;
> + bool skip_alignment;
> } msdos_format_param_t;
>
> /*
> + * Align to cluster borders
> + */
> +static unsigned int
> + loc_align_object (const unsigned int sectors,
> + const unsigned int clustersize,
> + const bool skip_alignment)
> +{
> + if (! skip_alignment)
> + return (sectors + clustersize - 1) & ~(clustersize - 1);
> + else
> + return sectors;
> +}
> +
> +/*
> * Formatted output.
> */
> static void
> @@ -278,9 +293,12 @@ static int msdos_format_eval_sectors_per_cluster
>
> \*-------------------------------------------------------------------------*/
> int fattype, /* type code of FAT (FAT_FAT12 ...)
> */
> uint32_t bytes_per_sector, /* byte count per sector (512)
> */
> - uint32_t fatdata_sec_cnt, /* sectors available for FAT and
> data */
> + const uint32_t total_sector_cnt, /* total number of secters per
> volume */
> + const uint32_t rsvd_sector_cnt, /* number of reserved sectors */
> + const uint32_t root_dir_sector_cnt,/* number of sectors for the root
> dir */
> uint8_t fat_num, /* number of fat copies
> */
> - uint32_t sectors_per_cluster, /* sectors per cluster (requested)
> */
> + uint32_t sectors_per_cluster, /* sectors per cluster (requested)
> */
> + const bool skip_alignment, /* true for no cluster alignment */
> uint32_t *sectors_per_cluster_adj, /* ret: sec per cluster (granted)
> */
> uint32_t *sectors_per_fat_ptr /* ret: sectors needed for one FAT
> */
> )
> @@ -296,6 +314,8 @@ static int msdos_format_eval_sectors_per_cluster
> uint32_t fat_capacity;
> uint32_t sectors_per_fat;
> uint32_t data_cluster_cnt;
> + uint32_t fatdata_sect_cnt;
> + uint32_t fat_sectors_cnt;
> /*
> * ensure, that maximum cluster size (32KByte) is not exceeded
> */
> @@ -310,27 +330,34 @@ static int msdos_format_eval_sectors_per_cluster
> * - compute storage size for FAT
> * - subtract from total cluster count
> */
> - fatdata_cluster_cnt = fatdata_sec_cnt/sectors_per_cluster;
> + fatdata_sect_cnt = total_sector_cnt -loc_align_object
> (rsvd_sector_cnt, sectors_per_cluster, skip_alignment);
> if (fattype == FAT_FAT12) {
> - fat_capacity = fatdata_cluster_cnt * 3 / 2;
> + fatdata_sect_cnt = fatdata_sect_cnt - loc_align_object
> (root_dir_sector_cnt, sectors_per_cluster, skip_alignment);
>
Lines that are longer than 80 characters should be broken.
+ fatdata_cluster_cnt = fatdata_sect_cnt/sectors_per_cluster;
> + fat_capacity = fatdata_cluster_cnt * 3 / 2;
> }
> else if (fattype == FAT_FAT16) {
> - fat_capacity = fatdata_cluster_cnt * 2;
> + fatdata_sect_cnt = fatdata_sect_cnt - loc_align_object
> (root_dir_sector_cnt, sectors_per_cluster, skip_alignment);
> + fatdata_cluster_cnt = fatdata_sect_cnt/sectors_per_cluster;
> + fat_capacity = fatdata_cluster_cnt * 2;
> }
> else { /* FAT32 */
> - fat_capacity = fatdata_cluster_cnt * 4;
> + fatdata_cluster_cnt = fatdata_sect_cnt/sectors_per_cluster;
> + fat_capacity = fatdata_cluster_cnt * 4;
> }
>
> sectors_per_fat = ((fat_capacity
> + (bytes_per_sector - 1))
> / bytes_per_sector);
>
> + fat_sectors_cnt = loc_align_object (sectors_per_fat * fat_num,
> sectors_per_cluster, skip_alignment);
> +
> data_cluster_cnt = (fatdata_cluster_cnt -
> - (((sectors_per_fat * fat_num)
> + ((fat_sectors_cnt
> + (sectors_per_cluster - 1))
> / sectors_per_cluster));
> /*
> - * data cluster count too big? then make sectors bigger
> + * data cluster count too big? Then make clusters bigger
> */
> if (((fattype == FAT_FAT12) && (data_cluster_cnt >
> FAT_FAT12_MAX_CLN)) ||
> ((fattype == FAT_FAT16) && (data_cluster_cnt >
> FAT_FAT16_MAX_CLN))) {
> @@ -342,7 +369,12 @@ static int msdos_format_eval_sectors_per_cluster
> /*
> * when maximum cluster size is exceeded, we have invalid data,
> abort...
> */
> - if ((sectors_per_cluster * bytes_per_sector)
> + if (fattype == FAT_FAT12) {
> + if (MS_BYTES_PER_CLUSTER_LIMIT_FAT12 < (sectors_per_cluster *
> bytes_per_sector)) {
> + ret_val = EINVAL;
> + finished = true;
> + }
> + } else if ((sectors_per_cluster * bytes_per_sector)
> > MS_BYTES_PER_CLUSTER_LIMIT) {
> ret_val = EINVAL;
> finished = true;
> @@ -352,11 +384,9 @@ static int msdos_format_eval_sectors_per_cluster
> if (ret_val != 0) {
> rtems_set_errno_and_return_minus_one(ret_val);
> }
> - else {
> - *sectors_per_cluster_adj = sectors_per_cluster;
> - *sectors_per_fat_ptr = sectors_per_fat;
> - return 0;
> - }
> + *sectors_per_cluster_adj = sectors_per_cluster;
> + *sectors_per_fat_ptr = fat_sectors_cnt / fat_num;
> + return 0;
> }
>
>
> @@ -381,7 +411,6 @@ static int msdos_format_determine_fmt_params
>
> \*=========================================================================*/
> {
> int ret_val = 0;
> - uint32_t fatdata_sect_cnt;
> uint32_t onebit;
> uint32_t sectors_per_cluster_adj = 0;
> uint64_t total_size = 0;
> @@ -393,7 +422,8 @@ static int msdos_format_determine_fmt_params
> * At least one thing we don't have to magically guess...
> */
> if (ret_val == 0) {
> - ret_val = rtems_disk_fd_get_block_size(fd,
> &fmt_params->bytes_per_sector);
> + ret_val = rtems_disk_fd_get_media_block_size(fd,
> &fmt_params->bytes_per_sector);
> +
> }
> if (ret_val == 0) {
> ret_val = rtems_disk_fd_get_block_count(fd,
> &fmt_params->totl_sector_cnt);
> @@ -410,7 +440,7 @@ static int msdos_format_determine_fmt_params
> */
> if (ret_val == 0) {
> if ((rqdata == NULL) ||
> - (rqdata->fat_num == 0)) {
> + (rqdata->fat_num == 0)) {
> fmt_params->fat_num = 2;
> }
> else if (rqdata->fat_num <= 6) {
> @@ -462,19 +492,19 @@ static int msdos_format_determine_fmt_params
> if (ret_val == 0) {
> fmt_params->sectors_per_cluster = 1;
> if ((rqdata != NULL) &&
> - (rqdata->fattype == MSDOS_FMT_FAT12)) {
> + (rqdata->fattype == MSDOS_FMT_FAT12)) {
> fmt_params->fattype = FAT_FAT12;
> }
> else if ((rqdata != NULL) &&
> - (rqdata->fattype == MSDOS_FMT_FAT16)) {
> + (rqdata->fattype == MSDOS_FMT_FAT16)) {
> fmt_params->fattype = FAT_FAT16;
> }
> else if ((rqdata != NULL) &&
> - (rqdata->fattype == MSDOS_FMT_FAT32)) {
> + (rqdata->fattype == MSDOS_FMT_FAT32)) {
> fmt_params->fattype = FAT_FAT32;
> }
> else if ((rqdata != NULL) &&
> - (rqdata->fattype != MSDOS_FMT_FATANY)) {
> + (rqdata->fattype != MSDOS_FMT_FATANY)) {
> ret_val = -1;
> errno = EINVAL;
> }
> @@ -492,14 +522,12 @@ static int msdos_format_determine_fmt_params
> fat16_sect_per_clust = rqdata->sectors_per_cluster;
> }
>
> - if (fmt_params->totl_sector_cnt
> - < FAT_FAT12_MAX_CLN * fat12_sect_per_clust) {
> + if (fmt_params->totl_sector_cnt < FAT_FAT12_MAX_CLN *
> fat12_sect_per_clust) {
> fmt_params->fattype = FAT_FAT12;
> /* start trying with small clusters */
> fmt_params->sectors_per_cluster = 2;
> }
> - else if (fmt_params->totl_sector_cnt
> - < FAT_FAT16_MAX_CLN * fat16_sect_per_clust) {
> + else if (fmt_params->totl_sector_cnt < FAT_FAT16_MAX_CLN *
> fat16_sect_per_clust) {
> fmt_params->fattype = FAT_FAT16;
> /* start trying with small clusters */
> fmt_params->sectors_per_cluster = 2;
> @@ -520,9 +548,8 @@ static int msdos_format_determine_fmt_params
> * try to use user requested cluster size
> */
> if ((rqdata != NULL) &&
> - (rqdata->sectors_per_cluster > 0)) {
> - fmt_params->sectors_per_cluster =
> - rqdata->sectors_per_cluster;
> + (rqdata->sectors_per_cluster > 0)) {
> + fmt_params->sectors_per_cluster = rqdata->sectors_per_cluster;
> }
> /*
> * check sectors per cluster.
> @@ -532,16 +559,22 @@ static int msdos_format_determine_fmt_params
> */
> for (onebit = 128;onebit >= 1;onebit = onebit>>1) {
> if (fmt_params->sectors_per_cluster >= onebit) {
> - fmt_params->sectors_per_cluster = onebit;
> - if (fmt_params->sectors_per_cluster
> - <= 32768L/fmt_params->bytes_per_sector) {
> - /* value is small enough so this value is ok */
> - onebit = 1;
> - }
> + fmt_params->sectors_per_cluster = onebit;
> + if (fmt_params->sectors_per_cluster <=
> 32768L/fmt_params->bytes_per_sector) {
> + /* value is small enough so this value is ok */
> + onebit = 1;
> + }
> }
> }
> }
>
> + /*
> + * Skip aligning structures or d align them
> + */
> + if ( (0 == ret_val)
> + && (NULL != rqdata)) {
> + fmt_params->skip_alignment = rqdata->skip_alignment;
> + }
> if (ret_val == 0) {
> msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
> "sectors per cluster: %d\n",
> fmt_params->sectors_per_cluster);
> @@ -564,34 +597,31 @@ static int msdos_format_determine_fmt_params
> /* for FAT12/FAT16, set files per root directory */
> /* must fill up an even count of sectors */
> if ((rqdata != NULL) &&
> - (rqdata->files_per_root_dir > 0)) {
> - fmt_params->files_per_root_dir = rqdata->files_per_root_dir;
> + (rqdata->files_per_root_dir > 0)) {
> + fmt_params->files_per_root_dir = rqdata->files_per_root_dir;
> }
> else {
> - if (fmt_params->fattype == FAT_FAT16) {
> - fmt_params->files_per_root_dir = 512;
> - }
> - else {
> - fmt_params->files_per_root_dir = 64;
> - }
> + if (fmt_params->fattype == FAT_FAT16) {
> + fmt_params->files_per_root_dir = 512;
> + }
> + else {
> + fmt_params->files_per_root_dir = 64;
> + }
> }
> fmt_params->files_per_root_dir = (fmt_params->files_per_root_dir +
> - (2*fmt_params->bytes_per_sector/
> - FAT_DIRENTRY_SIZE-1));
> +
> (2*fmt_params->bytes_per_sector/
> +
> FAT_DIRENTRY_SIZE-1));
> fmt_params->files_per_root_dir -= (fmt_params->files_per_root_dir %
> - (2*fmt_params->bytes_per_sector
> - /FAT_DIRENTRY_SIZE));
> +
> (2*fmt_params->bytes_per_sector
> +
> /FAT_DIRENTRY_SIZE));
> +
> }
> fmt_params->root_dir_sectors =
> (((fmt_params->files_per_root_dir * FAT_DIRENTRY_SIZE)
> - + fmt_params->bytes_per_sector - 1)
> + + fmt_params->bytes_per_sector - 1)
> / fmt_params->bytes_per_sector);
> }
> if (ret_val == 0) {
> - fatdata_sect_cnt = (fmt_params->totl_sector_cnt -
> - fmt_params->rsvd_sector_cnt -
> - fmt_params->root_dir_sectors);
> -
> /*
> * check values to get legal arrangement of FAT type and cluster count
> */
> @@ -599,30 +629,45 @@ static int msdos_format_determine_fmt_params
> ret_val = msdos_format_eval_sectors_per_cluster
> (fmt_params->fattype,
> fmt_params->bytes_per_sector,
> - fatdata_sect_cnt,
> + fmt_params->totl_sector_cnt,
> + fmt_params->rsvd_sector_cnt,
> + fmt_params->root_dir_sectors,
> fmt_params->fat_num,
> fmt_params->sectors_per_cluster,
> + fmt_params->skip_alignment,
> §ors_per_cluster_adj,
> &(fmt_params->sectors_per_fat));
> fmt_params->sectors_per_cluster = sectors_per_cluster_adj;
> }
> + if (0 == ret_val)
> + {
> + if (FAT_FAT32 != fmt_params->fattype)
> + {
> + fmt_params->files_per_root_dir = loc_align_object
> (fmt_params->root_dir_sectors,
> +
> fmt_params->sectors_per_cluster,
> +
> fmt_params->skip_alignment)
> + * (fmt_params->bytes_per_sector >>
> 5);
> + }
> + fmt_params->rsvd_sector_cnt = loc_align_object
> (fmt_params->rsvd_sector_cnt,
> +
> fmt_params->sectors_per_cluster,
> +
> fmt_params->skip_alignment);
> + }
>
> /*
> * determine media code
> */
> if (ret_val == 0) {
> - if ((rqdata != NULL) &&
> - (rqdata->media != 0)) {
> + if ((rqdata != NULL) && (rqdata->media != 0)) {
> const char valid_media_codes[] =
> - {0xF0,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
> + {0xF0,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
> if (NULL==memchr(valid_media_codes,
> rqdata->media,
> sizeof(valid_media_codes))) {
> - ret_val = -1;
> - errno = EINVAL;
> + ret_val = -1;
> + errno = EINVAL;
> }
> else {
> - fmt_params->media_code = rqdata->media;
> + fmt_params->media_code = rqdata->media;
> }
> }
> else {
> @@ -636,7 +681,7 @@ static int msdos_format_determine_fmt_params
> if (fmt_params->root_dir_sectors > 0) {
> fmt_params->root_dir_start_sec =
> fmt_params->rsvd_sector_cnt
> - + (fmt_params-> fat_num*fmt_params->sectors_per_fat);
> + + (fmt_params->fat_num*fmt_params->sectors_per_fat);
> fmt_params->root_dir_fmt_sec_cnt = fmt_params->root_dir_sectors;
> }
> else {
> @@ -648,6 +693,8 @@ static int msdos_format_determine_fmt_params
> + (fmt_params-> fat_num*fmt_params->sectors_per_fat);
> fmt_params->root_dir_fmt_sec_cnt = fmt_params->sectors_per_cluster;
> }
> +
> +
>
Only one blank line
> /*
> * determine usable OEMName
> */
> @@ -656,23 +703,20 @@ static int msdos_format_determine_fmt_params
> char *to = fmt_params->OEMName;
> int cnt;
> from = "RTEMS"; /* default: make "from" point to OS Name */
> - if ((rqdata != NULL) &&
> - (rqdata->OEMName != NULL)) {
> + if ((rqdata != NULL) && (rqdata->OEMName != NULL)) {
> from = rqdata->OEMName;
> }
> - for (cnt = 0;
> - cnt < (sizeof(fmt_params->OEMName)-1);
> - cnt++) {
> + for (cnt = 0; cnt < (sizeof(fmt_params->OEMName)-1); cnt++) {
> if (isprint((unsigned char)*from)) {
> - *to++ = *from++;
> + *to++ = *from++;
> }
> else {
> - /*
> - * non-printable character in given name, so keep stuck
> - * at that character and replace all following characters
> - * with a ' '
> - */
> - *to++=' ';
> + /*
> + * non-printable character in given name, so keep stuck
> + * at that character and replace all following characters
> + * with a ' '
> + */
> + *to++=' ';
> }
> *to = '\0';
> }
> @@ -686,24 +730,21 @@ static int msdos_format_determine_fmt_params
> char *to = fmt_params->VolLabel;
> int cnt;
> from = ""; /* default: make "from" point to empty string */
> - if ((rqdata != NULL) &&
> - (rqdata->VolLabel != NULL)) {
> + if ((rqdata != NULL) && (rqdata->VolLabel != NULL)) {
> from = rqdata->VolLabel;
> fmt_params->VolLabel_present = true;
> }
> - for (cnt = 0;
> - cnt < (sizeof(fmt_params->VolLabel)-1);
> - cnt++) {
> + for (cnt = 0; cnt < (sizeof(fmt_params->VolLabel)-1); cnt++) {
> if (isprint((unsigned char)*from)) {
> - *to++ = *from++;
> + *to++ = *from++;
>
Nesting level should be just two blank space characters, not 8.
}
> else {
> - /*
> - * non-printable character in given name, so keep stuck
> - * at that character and replace all following characters
> - * with a ' '
> - */
> - *to++=' ';
> + /*
> + * non-printable character in given name, so keep stuck
> + * at that character and replace all following characters
> + * with a ' '
> + */
> + *to++=' ';
> }
> *to = '\0';
> }
> @@ -721,9 +762,7 @@ static int msdos_format_determine_fmt_params
> if (ret_val != 0) {
> rtems_set_errno_and_return_minus_one(ret_val);
> }
> - else {
> - return 0;
> - }
> + return 0;
> }
>
> /*=========================================================================*\
> | Function:
> |
> @@ -1106,15 +1145,14 @@ int msdos_format
> */
> FAT_SET_VAL32(tmp_sec,8,FAT_FAT32_EOC);
> }
> - for (i = 0;
> - (i < fmt_params.fat_num) && (ret_val == 0);
> - i++) {
> + unsigned int start_sector = loc_align_object
> (fmt_params.rsvd_sector_cnt, fmt_params.sectors_per_cluster,
> fmt_params.skip_alignment);
> + for (i = 0; (i < fmt_params.fat_num) && (ret_val == 0); i++) {
> ret_val = msdos_format_write_sec
> - (fd,
> - fmt_params.rsvd_sector_cnt
> - + (i * fmt_params.sectors_per_fat),
> - fmt_params.bytes_per_sector,
> - tmp_sec);
> + (fd,
> + start_sector
> + + (i * fmt_params.sectors_per_fat),
> + fmt_params.bytes_per_sector,
> + tmp_sec);
> }
> }
> /*
> @@ -1126,5 +1164,8 @@ int msdos_format
> close(fd);
> }
>
> - return ret_val;
> + if (0 != ret_val)
> + return -1;
> + else
> + return 0;
> }
> diff --git a/cpukit/libmisc/shell/main_msdosfmt.c
> b/cpukit/libmisc/shell/main_msdosfmt.c
> index 47dd9f1..60926b9 100644
> --- a/cpukit/libmisc/shell/main_msdosfmt.c
> +++ b/cpukit/libmisc/shell/main_msdosfmt.c
> @@ -36,7 +36,7 @@ static int rtems_shell_main_msdos_format(
> .fattype = MSDOS_FMT_FATANY,
> .media = 0,
> .quick_format = TRUE,
> - .cluster_align = 0,
> + .skip_alignment = 0,
> .info_level = 0
> };
>
> @@ -149,7 +149,7 @@ static int rtems_shell_main_msdos_format(
> printf (" %-20s: %i\n", "fat type", rqdata.fattype);
> printf (" %-20s: %d\n", "media", rqdata.media);
> printf (" %-20s: %d\n", "quick_format", rqdata.quick_format);
> - printf (" %-20s: %" PRIu32 "\n", "cluster align",
> rqdata.cluster_align);
> + printf (" %-20s: %s\n", "skip_alignment", (0 ==
> rqdata.skip_alignment) ? "false" : "true");
> }
>
> if (msdos_format (driver, &rqdata) < 0) {
> diff --git a/testsuites/fstests/mdosfs_support/fs_support.c
> b/testsuites/fstests/mdosfs_support/fs_support.c
> index ef4356e..c58379a 100644
> --- a/testsuites/fstests/mdosfs_support/fs_support.c
> +++ b/testsuites/fstests/mdosfs_support/fs_support.c
> @@ -34,7 +34,7 @@ msdos_format_request_param_t rqdata = {
> fattype: MSDOS_FMT_FATANY,
> media: 0,
> quick_format: FALSE,
> - cluster_align: 0,
> + skip_alignment: 0,
> info_level: 0
> };
>
> --
> 1.7.10.4
>
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20121129/26d4fe19/attachment-0001.html>
More information about the devel
mailing list