From patchwork Fri Aug 16 23:22:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Lutomirski X-Patchwork-Id: 267937 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 6DFA02C0293 for ; Sat, 17 Aug 2013 10:27:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755789Ab3HQA1e (ORCPT ); Fri, 16 Aug 2013 20:27:34 -0400 Received: from mail-pb0-f47.google.com ([209.85.160.47]:52976 "EHLO mail-pb0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755554Ab3HQA1d (ORCPT ); Fri, 16 Aug 2013 20:27:33 -0400 Received: by mail-pb0-f47.google.com with SMTP id rr4so2555039pbb.6 for ; Fri, 16 Aug 2013 17:27:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=PyqQmsYslEON5UT5tmcAEDBefhHbLo/xYRv0ktmaIBw=; b=gd5Uo/+umDj0A2c5CI7EDGKX8DvJQwrFGGxARWVGrCSQA7oUH+yJVwFWdtdaXLk2wf AdotVQkrLiHb4NmmrJqAtX5RGlDIxP7vq/wwibbcc54TKrjVB1C9JQYxJw0KtCfG1RaL hjCGELl4XkyVwP6ggfe4KD6/Ux6Eof/HXxQrLK8MFgZA1V6O4TZTKb/BwuOVmQtYK4Jt hPcbOd+t0eyizyvhXIms/ZEsysD9845WW0adP9R4CAHHIARC3iA1M/cHwY2MVTxi0I02 69t88xdXuY3N287Xx/ywF18Ti3yOd6t7an7pWMBkIZCs2mIOIMERAzExWNKjB5Ojiuvm Sv2g== X-Gm-Message-State: ALoCoQmY4HZDWMgomeawhyb4/F59J/k5VXHhyzN4dNwbJ1T9phUMQ9kegrAWhK013Zw2E5CBu0dZ X-Received: by 10.67.4.197 with SMTP id cg5mr5508750pad.10.1376695344543; Fri, 16 Aug 2013 16:22:24 -0700 (PDT) Received: from localhost (50-76-60-73-ip-static.hfc.comcastbusiness.net. [50.76.60.73]) by mx.google.com with ESMTPSA id xs1sm76265pac.7.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 16 Aug 2013 16:22:23 -0700 (PDT) From: Andy Lutomirski To: linux-kernel@vger.kernel.org Cc: linux-ext4@vger.kernel.org, Dave Chinner , Theodore Ts'o , Dave Hansen , xfs@oss.sgi.com, Jan Kara , Tim Chen , Christoph Hellwig , Andy Lutomirski Subject: [PATCH v3 2/5] fs: Add inode_update_time_writable Date: Fri, 16 Aug 2013 16:22:09 -0700 Message-Id: X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This is like file_update_time, except that it acts on a struct inode * instead of a struct file *. Signed-off-by: Andy Lutomirski --- fs/inode.c | 72 ++++++++++++++++++++++++++++++++++++++++++------------ include/linux/fs.h | 1 + 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index d6dfb09..bc90c12 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1637,6 +1637,34 @@ int file_remove_suid(struct file *file) } EXPORT_SYMBOL(file_remove_suid); +/* + * This does the work that's common to file_update_time and + * inode_update_time. + */ +static int prepare_update_cmtime(struct inode *inode, struct timespec *now) +{ + int sync_it; + + /* First try to exhaust all avenues to not sync */ + if (IS_NOCMTIME(inode)) + return 0; + + *now = current_fs_time(inode->i_sb); + if (!timespec_equal(&inode->i_mtime, now)) + sync_it = S_MTIME; + + if (!timespec_equal(&inode->i_ctime, now)) + sync_it |= S_CTIME; + + if (IS_I_VERSION(inode)) + sync_it |= S_VERSION; + + if (!sync_it) + return 0; + + return sync_it; +} + /** * file_update_time - update mtime and ctime time * @file: file accessed @@ -1654,23 +1682,9 @@ int file_update_time(struct file *file) { struct inode *inode = file_inode(file); struct timespec now; - int sync_it = 0; + int sync_it = prepare_update_cmtime(inode, &now); int ret; - /* First try to exhaust all avenues to not sync */ - if (IS_NOCMTIME(inode)) - return 0; - - now = current_fs_time(inode->i_sb); - if (!timespec_equal(&inode->i_mtime, &now)) - sync_it = S_MTIME; - - if (!timespec_equal(&inode->i_ctime, &now)) - sync_it |= S_CTIME; - - if (IS_I_VERSION(inode)) - sync_it |= S_VERSION; - if (!sync_it) return 0; @@ -1685,6 +1699,34 @@ int file_update_time(struct file *file) } EXPORT_SYMBOL(file_update_time); +/** + * inode_update_time_writable - update mtime and ctime time + * @inode: inode accessed + * + * This is like file_update_time, but it assumes the mnt is writable + * and takes an inode parameter instead. (We need to assume the mnt + * was writable because inodes aren't associated with any particular + * mnt. + */ + +int inode_update_time_writable(struct inode *inode) +{ + struct timespec now; + int sync_it = prepare_update_cmtime(inode, &now); + int ret; + + if (!sync_it) + return 0; + + /* sb_start_pagefault and update_time can both sleep. */ + sb_start_pagefault(inode->i_sb); + ret = update_time(inode, &now, sync_it); + sb_end_pagefault(inode->i_sb); + + return ret; +} +EXPORT_SYMBOL(inode_update_time_writable); + int inode_needs_sync(struct inode *inode) { if (IS_SYNC(inode)) diff --git a/include/linux/fs.h b/include/linux/fs.h index 9818747..86cf0a4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2590,6 +2590,7 @@ extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); extern int file_update_time(struct file *file); +extern int inode_update_time_writable(struct inode *inode); extern int generic_show_options(struct seq_file *m, struct dentry *root); extern void save_mount_options(struct super_block *sb, char *options);