From patchwork Wed Mar 25 13:00:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: hujianyang X-Patchwork-Id: 6090731 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 609A5BF90F for ; Wed, 25 Mar 2015 13:00:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 669BA202EB for ; Wed, 25 Mar 2015 13:00:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5493A202F8 for ; Wed, 25 Mar 2015 13:00:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752149AbbCYNAf (ORCPT ); Wed, 25 Mar 2015 09:00:35 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:15793 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751725AbbCYNAe (ORCPT ); Wed, 25 Mar 2015 09:00:34 -0400 Received: from 172.24.2.119 (EHLO szxeml433-hub.china.huawei.com) ([172.24.2.119]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BDP55801; Wed, 25 Mar 2015 21:00:29 +0800 (CST) Received: from [127.0.0.1] (10.111.68.144) by szxeml433-hub.china.huawei.com (10.82.67.210) with Microsoft SMTP Server id 14.3.158.1; Wed, 25 Mar 2015 21:00:20 +0800 Message-ID: <5512B161.4090709@huawei.com> Date: Wed, 25 Mar 2015 21:00:17 +0800 From: hujianyang User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20130801 Thunderbird/17.0.8 MIME-Version: 1.0 To: Artem Bityutskiy , Richard Weinberger CC: "markus.heininger@online.de" , Andreas Dilger , linux-mtd , "linux-fsdevel@vger.kernel.org" , David Sterba Subject: [PATCH RFC] ubifs: introduce an ioctl to get UBIFS files compressed size X-Originating-IP: [10.111.68.144] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020201.5512B16D.0177, ss=1, re=0.001, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: e73c2748d0e5fa49386adfe46f221c60 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As discussed in last mail, I don't think record compressed size in *ubifs_ino_inode* could suffer power cut easily, rebuild the records of each file may increase the mount time and we may need to write more meta data to keep the consistency of compressed size. And I don't think *fiemap* is a good interface either, because it is can't report compressed size at present. http://lists.infradead.org/pipermail/linux-mtd/2015-February/057978.html So I tried another way, introduce a new ioctl which scan the tnc_tree to get the compressed size in each *ubifs_data_node* of the request file. Similar with: https://patchwork.kernel.org/patch/117782/ But This isn't a good solution in performance side. Just want to show my code to push the achievement of this feature. Any test or any advisement is welcomed. Thanks everyone~! Signed-off-by: hujianyang --- fs/ubifs/ioctl.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ubifs/ubifs.h | 2 + 2 files changed, 63 insertions(+), 0 deletions(-) diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 648b143..a148e32 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c @@ -144,6 +144,62 @@ out_unlock: return err; } +static long ubifs_ioctl_compsize(struct file *file, void __user *arg) +{ + struct inode *inode = file_inode(file); + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_info *c = inode->i_sb->s_fs_info; + loff_t compsize = 0; + loff_t synced_i_size; + unsigned int block, beyond, dlen; + struct ubifs_data_node *dn; + union ubifs_key key; + int err = 0; + + if (S_ISDIR(inode->i_mode)) + return -EISDIR; + + dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS); + if (!dn) + return -ENOMEM; + + filemap_write_and_wait(inode->i_mapping); + + mutex_lock(&ui->ui_mutex); + + spin_lock(&ui->ui_lock); + synced_i_size = ui->synced_i_size; + spin_unlock(&ui->ui_lock); + + block = 0; + beyond = (synced_i_size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; + + while (block < beyond) { + data_key_init(c, &key, inode->i_ino, block); + err = ubifs_tnc_lookup(c, &key, dn); + if (err) { + if (err != -ENOENT) { + mutex_unlock(&ui->ui_mutex); + goto out; + } + } else { + dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; + compsize += dlen; + } + block += 1; + } + + mutex_unlock(&ui->ui_mutex); + + err = 0; + if (copy_to_user(arg, &compsize, sizeof(compsize))) + err = -EFAULT; + +out: + kfree(dn); + return err; +} + long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int flags, err; @@ -182,6 +238,9 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return err; } + case UBIFS_IOC_COMPR_SIZE: + return ubifs_ioctl_compsize(file, (void __user *)arg); + default: return -ENOTTY; } @@ -197,6 +256,8 @@ long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case FS_IOC32_SETFLAGS: cmd = FS_IOC_SETFLAGS; break; + case UBIFS_IOC_COMPR_SIZE: + return ubifs_ioctl_compsize(file, (void __user *)arg); default: return -ENOIOCTLCMD; } diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 2911d2d..9000be8 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -169,6 +169,8 @@ /* Maximum number of data nodes to bulk-read */ #define UBIFS_MAX_BULK_READ 32 +#define UBIFS_IOC_COMPR_SIZE _IOR('O', 0, loff_t) + /* * Lockdep classes for UBIFS inode @ui_mutex. */