From patchwork Fri Jun 18 10:08:30 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Tereshonkov X-Patchwork-Id: 56161 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9B2FAB7D8B for ; Fri, 18 Jun 2010 20:10:22 +1000 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1OPYVK-0000iu-22; Fri, 18 Jun 2010 10:08:54 +0000 Received: from smtp.nokia.com ([192.100.122.230] helo=mgw-mx03.nokia.com) by bombadil.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1OPYVA-0000H0-4m for linux-mtd@lists.infradead.org; Fri, 18 Jun 2010 10:08:48 +0000 Received: from vaebh105.NOE.Nokia.com (vaebh105.europe.nokia.com [10.160.244.31]) by mgw-mx03.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o5IA5lJ5021843 for ; Fri, 18 Jun 2010 13:08:41 +0300 Received: from esebh102.NOE.Nokia.com ([172.21.138.183]) by vaebh105.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 18 Jun 2010 13:08:32 +0300 Received: from mgw-sa01.ext.nokia.com ([147.243.1.47]) by esebh102.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Fri, 18 Jun 2010 13:08:32 +0300 Received: from localhost.localdomain (ramses.research.nokia.com [172.21.51.130]) by mgw-sa01.ext.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o5IA8VmO021141; Fri, 18 Jun 2010 13:08:32 +0300 From: Roman Tereshonkov To: linux-mtd@lists.infradead.org Subject: [PATCH 3/4] mtd: add MTDREPARTITION ioctl Date: Fri, 18 Jun 2010 13:08:30 +0300 Message-Id: <1276855711-18570-4-git-send-email-roman.tereshonkov@nokia.com> X-Mailer: git-send-email 1.6.2.4 In-Reply-To: <1276855711-18570-3-git-send-email-roman.tereshonkov@nokia.com> References: <1276855711-18570-1-git-send-email-roman.tereshonkov@nokia.com> <1276855711-18570-2-git-send-email-roman.tereshonkov@nokia.com> <1276855711-18570-3-git-send-email-roman.tereshonkov@nokia.com> X-OriginalArrivalTime: 18 Jun 2010 10:08:32.0400 (UTC) FILETIME=[34EA1900:01CB0ECE] X-Nokia-AV: Clean X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20100618_060847_970565_577959E4 X-CRM114-Status: GOOD ( 19.69 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [192.100.122.230 listed in list.dnswl.org] -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain Cc: Roman Tereshonkov X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add MTDREPARTITION ioctl to modify all partitions for given mtd master device. The partitions having the same master are modified all at once: all previous are deleted and the new set is created. Signed-off-by: Roman Tereshonkov --- drivers/mtd/mtdchar.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 109 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 91c8013..ccdccad 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -19,7 +19,7 @@ #include #include - +#include #include #define MTD_INODE_FS_MAGIC 0x11307854 @@ -463,6 +463,65 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start, return ret; } +#ifdef CONFIG_MTD_PARTITIONS +static int mtd_do_repartition(struct file *file, struct mtd_info *mtd, + uint32_t nparts, void __user *ptr) +{ + struct mtd_partition *parts; + struct mtd_partition_user *up; + int size, i, ret = -ENOMEM; + + if (!(file->f_mode & FMODE_WRITE)) + return -EPERM; + + size = nparts * sizeof(struct mtd_partition_user); + if (!size) + return -EINVAL; + + if (!access_ok(VERIFY_READ, ptr, size)) + return -EFAULT; + + up = kmalloc(size, GFP_KERNEL); + if (!up) + return -ENOMEM; + + if (copy_from_user(up, ptr, size)) { + ret = -EFAULT; + goto err_free_up; + } + + size = nparts * sizeof(struct mtd_partition); + parts = kzalloc(size, GFP_KERNEL); + if (!parts) + goto err_free_up; + + for (i = 0; i < nparts; i++) { + parts[i].offset = up[i].offset; + parts[i].size = up[i].size; + parts[i].mask_flags = up[i].mask_flags; + + parts[i].name = kstrndup(up[i].name, MTD_MAX_PARTITION_NAME_LEN, + GFP_KERNEL); + if (!parts[i].name) + goto err_free; + } + + ret = del_mtd_partitions(mtd); + if (!ret) + ret = add_mtd_partitions(mtd, parts, nparts); + + err_free: + for (i = 0; i < nparts; i++) + kfree(parts[i].name); + kfree(parts); + err_free_up: + kfree(up); + + return ret; +} +#endif + + static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) { struct mtd_file_info *mfi = file->private_data; @@ -826,7 +885,25 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) file->f_pos = 0; break; } +#ifdef CONFIG_MTD_PARTITIONS + case MTDREPARTITION: + { + struct mtd_partitions p; + struct mtd_info *master; + + /* only root (no assigned master) device can be accessed */ + master = part_get_mtd_master(mtd); + if (master) + return -EACCES; + + if (copy_from_user(&p, argp, sizeof(p))) + return -EFAULT; + + ret = mtd_do_repartition(file, mtd, p.nparts, p.parts); + break; + } +#endif default: ret = -ENOTTY; } @@ -856,6 +933,15 @@ struct mtd_oob_buf32 { #define MEMWRITEOOB32 _IOWR('M', 3, struct mtd_oob_buf32) #define MEMREADOOB32 _IOWR('M', 4, struct mtd_oob_buf32) +#ifdef CONFIG_MTD_PARTITIONS +struct mtd_partitions32 { + uint32_t nparts; + compat_caddr_t ptr; +}; + +#define MTDREPARTITION32 _IOW('M', 23, struct mtd_partitions32) +#endif + static long mtd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -895,6 +981,28 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd, &buf_user->start); break; } + +#ifdef CONFIG_MTD_PARTITIONS + case MTDREPARTITION32: + { + struct mtd_partitions32 p; + struct mtd_info *master; + + /* only root (no assigned master) device can be accessed */ + master = part_get_mtd_master(mtd); + if (!master) { + if (copy_from_user(&p, argp, sizeof(p))) + ret = -EFAULT; + else + ret = mtd_do_repartition(file, mtd, p.nparts, + compat_ptr(p.ptr)); + } else { + ret = -EACCES; + } + + break; + } +#endif default: ret = mtd_ioctl(file, cmd, (unsigned long)argp); }