From: Roman Tereshonkov <roman.tereshonkov@nokia.com>
To: Rohit Hassan Sathyanarayan <rohit.hs@samsung.com>
Cc: linux-mtd@lists.infradead.org
Subject: Re: [PATCH 1/1][MTD] Adding IOCTLs for run-time partitioning support
Date: Thu, 2 Sep 2010 16:24:16 +0300 [thread overview]
Message-ID: <20100902132416.GA9857@nokia.com> (raw)
In-Reply-To: <000101cb2f11$86c3f5d0$944be170$%hs@samsung.com>
On Thu, Jul 29, 2010 at 05:00:59PM +0530, Rohit Hassan Sathyanarayan wrote:
> Hi All
>
> Sending the patch on MTD for adding four IOCTLs.
> MTDPARTITIONCREATE
> MTDPARTITIONDELETE
> MTDPARTITIONSETPERMISSION
> MTDPARTITIONMERGE
>
>
>
> Signed-off-by: Rohit HS <rohit.hs at samsung.com>
> ---
> drivers/mtd/mtdchar.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++
> include/mtd/mtd-abi.h | 17 ++++++
> 2 files changed, 142 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> index 8b223c0..704788c 100644
> --- a/drivers/mtd/mtdchar.c
> +++ b/drivers/mtd/mtdchar.c
> @@ -22,6 +22,10 @@
>
> #include <asm/uaccess.h>
>
> +#ifdef CONFIG_MTD_PARTITIONS
> +#include <linux/mtd/partitions.h>
> +#endif
> +
> #define MTD_INODE_FS_MAGIC 0x11307854
> static struct vfsmount *mtd_inode_mnt __read_mostly;
>
> @@ -826,6 +830,128 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
> }
> file->f_pos = 0;
> break;
> +#ifdef CONFIG_MTD_PARTITIONS
> +
> + case MTDPARTITIONCREATE:
> + {
> + struct mtd_partition *pst_minfo = NULL;
> + struct mtd_partition *pst_minfo_hold = NULL;
> + struct mtd_partition st_free;
> + uint64_t u64_userfreeoffset = 0;
> + uint64_t u64_userfreesize = 0;
> + struct user_mtd *puser_partitions = NULL;
> + struct user_mtd_info upartition;
> + int i;
> +
> + if (copy_from_user(&upartition, argp,
> + sizeof(struct user_mtd_info))) {
> + ret = -EFAULT;
> + break;
> + }
> + puser_partitions = kzalloc(sizeof(struct user_mtd)*
> + upartition.num_partitions
> + , GFP_KERNEL);
> + pst_minfo = kzalloc(sizeof(struct mtd_partition)*
> + upartition.num_partitions,
> + GFP_KERNEL);
> + pst_minfo_hold = pst_minfo;
> + if (puser_partitions == NULL) {
> + ret = -EFAULT;
> + break;
> + }
The case puser_partitions == NULL && pst_minfo != NULL leads to the memory leakage.
> + if (copy_from_user(puser_partitions,
> + upartition.pst_user_partitions,
> + sizeof(struct user_mtd)*
> + upartition.num_partitions)) {
> + ret = -EFAULT;
> + break;
What happens with previously allocated memory?
> + }
> + for (i = 0; i < upartition.num_partitions; i++) {
> + pst_minfo->name = puser_partitions->name;
> + pst_minfo->size =
> + puser_partitions->partition_size;
> + u64_userfreesize += pst_minfo->size;
> + pst_minfo->offset =
> + puser_partitions->partition_offset;
> + u64_userfreeoffset += pst_minfo->offset;
> + pst_minfo->mask_flags =
> + puser_partitions->partition_mask;
> +
> + puser_partitions++;
> + pst_minfo++;
> + }
> + add_mtd_partitions(mtd, pst_minfo_hold,
> + upartition.num_partitions);
The function add_mtd_partitions implies to be called only for all mtd partitions at once.
There are some dependences on the partition which goes the first in the passed list.
See add_one_partition function partno argument.
> + if ((mtd->size - u64_userfreesize) > 0) {
> + st_free.name = "FREE";
> + st_free.size = mtd->size - u64_userfreesize;
> + st_free.offset = u64_userfreesize;
> + st_free.mask_flags = 0;
> + add_mtd_partitions(mtd, &st_free, 1);
> + }
> + break;
> + }
> + case MTDPARTITIONDELETE:
> + {
How do you free memory allocated in MTDPARTITIONCREATE?
> + struct mtd_info *pst_del_info = NULL;
> + uint32_t mtd_partition_number;
> +
> + if (copy_from_user(&mtd_partition_number, argp,
> + sizeof(mtd_partition_number))) {
> + ret = -EFAULT;
> + break;
> + }
> + pst_del_info = get_mtd_device(NULL,
> + mtd_partition_number);
> +
> + if (pst_del_info != NULL) {
> + put_mtd_device(pst_del_info);
> + del_mtd_device(pst_del_info);
> + }
> + break;
> + }
If the partition is used del_mtd_device returns EBUSY.
Should the user space be informed about this?
> + case MTDPARTITIONSETPERMISSION:
> + {
> + uint32_t u32_mask_flags;
> + struct mtd_info *pst_device = NULL;
> + int i32_dev_num;
> +
> + if (copy_from_user(&u32_mask_flags, argp,
> + sizeof(u32_mask_flags))) {
> + ret = -EFAULT;
> + break;
> + }
> + i32_dev_num = (u32_mask_flags & 0x0000FFFF);
> + u32_mask_flags = (u32_mask_flags & 0xFFFF0000) >> 16;
> + pst_device = get_mtd_device(NULL, i32_dev_num);
> + pst_device->flags = u32_mask_flags;
> + break;
> + }
> + case MTDPARTITIONMERGE:
MERGE = DELETE + CREATE
Is this ioctl really needed?
> + {
> + struct mtd_info *pst_merge_device1 = NULL;
> + struct mtd_info *pst_merge_device2 = NULL;
> + unsigned char partition_number[2];
> +
> + if (copy_from_user(partition_number, argp, 2)) {
> + ret = -EFAULT;
> + break;
> + }
> + pst_merge_device1 = get_mtd_device(NULL,
> + partition_number[0]);
> + pst_merge_device2 = get_mtd_device(NULL,
> + partition_number[1]);
The case when only one of pst_merge_device1 and pst_merge_device2 is non-NULL
leads to the unreleased mtd_device.
> + if ((pst_merge_device1 != NULL) &&
> + (pst_merge_device2 != NULL)) {
> + pst_merge_device1->size +=
> + pst_merge_device2->size;
> + put_mtd_device(pst_merge_device2);
> + del_mtd_device(pst_merge_device2);
pst_merge_device1 should be released probably.
> + }
> + break;
> + }
> +#endif
> +
> }
>
> default:
> diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
> index be51ae2..85168f2 100644
> --- a/include/mtd/mtd-abi.h
> +++ b/include/mtd/mtd-abi.h
> @@ -30,6 +30,18 @@ struct mtd_oob_buf64 {
> __u64 usr_ptr;
> };
>
> +struct user_mtd {
> + char name[32];
> + __u64 partition_size;
> + __u64 partition_offset;
> + __u32 partition_mask;
> +};
> +
> +struct user_mtd_info {
> + struct user_mtd *pst_user_partitions;
> + __u32 num_partitions;
> +};
> +
> #define MTD_ABSENT 0
> #define MTD_RAM 1
> #define MTD_ROM 2
> @@ -110,7 +122,10 @@ struct otp_info {
> #define MEMERASE64 _IOW('M', 20, struct erase_info_user64)
> #define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64)
> #define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64)
> -
> +#define MTDPARTITIONCREATE _IOW('M', 23, int)
> +#define MTDPARTITIONDELETE _IOW('M', 24, int)
> +#define MTDPARTITIONSETPERMISSION _IOW('M', 26, int)
> +#define MTDPARTITIONMERGE _IOW('M', 27, int)
> /*
> * Obsolete legacy interface. Keep it in order not to break userspace
> * interfaces
> ---
>
>
prev parent reply other threads:[~2010-09-02 13:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-29 11:30 [PATCH 1/1][MTD] Adding IOCTLs for run-time partitioning support Rohit Hassan Sathyanarayan
2010-08-23 14:33 ` Artem Bityutskiy
2010-09-06 2:34 ` Rohit Hassan Sathyanarayan
2010-09-18 18:57 ` Artem Bityutskiy
2010-09-02 13:24 ` Roman Tereshonkov [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100902132416.GA9857@nokia.com \
--to=roman.tereshonkov@nokia.com \
--cc=linux-mtd@lists.infradead.org \
--cc=rohit.hs@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.