From patchwork Wed Feb 13 04:23:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Do Q.Thang" X-Patchwork-Id: 2134341 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) by patchwork2.kernel.org (Postfix) with ESMTP id E073ADFE75 for ; Wed, 13 Feb 2013 04:55:56 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [IPv6:::1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 3604F89E; Wed, 13 Feb 2013 04:55:53 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9A61A8A2 for ; Wed, 13 Feb 2013 04:55:52 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mail.omesemicon.co.jp.omesemicon.co.jp (219-118-191-130.cust.bit-drive.ne.jp [219.118.191.130]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id B0CFD1F8AB for ; Wed, 13 Feb 2013 04:55:51 +0000 (UTC) Received: from [192.168.11.3] by [192.168.11.254] with ESMTP; Wed, 13 Feb 2013 13:55:51 +0900 Received: from localhost (p14010-ipadfx41marunouchi.tokyo.ocn.ne.jp [61.118.107.10]) by mail.omesemicon.co.jp.omesemicon.co.jp (8.13.1/3.7W) with ESMTP id r1D4Onc2007093 for ; Wed, 13 Feb 2013 13:24:49 +0900 From: Do Quang Thang To: ltsi-dev@lists.linuxfoundation.org Date: Wed, 13 Feb 2013 13:23:57 +0900 Message-Id: <1360729438-10731-10-git-send-email-dq-thang@jinso.co.jp> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1360729438-10731-1-git-send-email-dq-thang@jinso.co.jp> References: <1360729438-10731-1-git-send-email-dq-thang@jinso.co.jp> MIME-Version: 1.0 X-Spam-Status: No, score=0.1 required=5.0 tests=BAYES_00, RCVD_DOUBLE_IP_LOOSE, RDNS_DYNAMIC autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [LTSI-dev] [PATCH 09/10] usb: gadget: mass_storage: fail fsg_store_file() early if colud not open file X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org From: Michal Nazarewicz Currently, when a new value is stored to the “file” sysfs entry, fsg_store_file() will release existing backing file and only then attempt to open a new one. If that fails, no new backing file is open. This commit changes the fsg_lun_open() so that it closes existing backing file only after the new backing file has been successfully opened. With that change, fsg_store_file() may use it to perform an atomic open operation with guarantee that logical unit will either point to the new backing file or still to the old one. Signed-off-by: Michal Nazarewicz Acked-by: Alan Stern (cherry picked from commit d6e16a89578fcc8834be634c85c5c5ddc2d13229) Signed-off-by: Do Quang Thang --- drivers/usb/gadget/storage_common.c | 52 +++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 8a8157f..e576678 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -617,6 +617,16 @@ static struct usb_gadget_strings fsg_stringtab = { * the caller must own fsg->filesem for writing. */ +static void fsg_lun_close(struct fsg_lun *curlun) +{ + if (curlun->filp) { + LDBG(curlun, "close backing file\n"); + fput(curlun->filp); + curlun->filp = NULL; + } +} + + static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) { int ro; @@ -626,6 +636,8 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) loff_t size; loff_t num_sectors; loff_t min_sectors; + unsigned int blkbits; + unsigned int blksize; /* R/W if we can, R/O if we must */ ro = curlun->initially_ro; @@ -670,17 +682,17 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) } if (curlun->cdrom) { - curlun->blksize = 2048; - curlun->blkbits = 11; + blksize = 2048; + blkbits = 11; } else if (inode->i_bdev) { - curlun->blksize = bdev_logical_block_size(inode->i_bdev); - curlun->blkbits = blksize_bits(curlun->blksize); + blksize = bdev_logical_block_size(inode->i_bdev); + blkbits = blksize_bits(blksize); } else { - curlun->blksize = 512; - curlun->blkbits = 9; + blksize = 512; + blkbits = 9; } - num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */ + num_sectors = size >> blkbits; /* File size in logic-block-size blocks */ min_sectors = 1; if (curlun->cdrom) { min_sectors = 300; /* Smallest track is 300 frames */ @@ -697,7 +709,12 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) goto out; } + if (fsg_lun_is_open(curlun)) + fsg_lun_close(curlun); + get_file(filp); + curlun->blksize = blksize; + curlun->blkbits = blkbits; curlun->ro = ro; curlun->filp = filp; curlun->file_length = size; @@ -711,16 +728,6 @@ out: } -static void fsg_lun_close(struct fsg_lun *curlun) -{ - if (curlun->filp) { - LDBG(curlun, "close backing file\n"); - fput(curlun->filp); - curlun->filp = NULL; - } -} - - /*-------------------------------------------------------------------------*/ /* @@ -871,19 +878,18 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, if (count > 0 && buf[count-1] == '\n') ((char *) buf)[count-1] = 0; /* Ugh! */ - /* Eject current medium */ - down_write(filesem); - if (fsg_lun_is_open(curlun)) { - fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } /* Load new medium */ + down_write(filesem); if (count > 0 && buf[0]) { + /* fsg_lun_open() will close existing file if any. */ rc = fsg_lun_open(curlun, buf); if (rc == 0) curlun->unit_attention_data = SS_NOT_READY_TO_READY_TRANSITION; + } else if (fsg_lun_is_open(curlun)) { + fsg_lun_close(curlun); + curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; } up_write(filesem); return (rc < 0 ? rc : count);