From patchwork Tue Feb 14 02:46:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 727672 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 3vMmyr1d9mz9s74 for ; Tue, 14 Feb 2017 13:46:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751504AbdBNCqj (ORCPT ); Mon, 13 Feb 2017 21:46:39 -0500 Received: from mx2.suse.de ([195.135.220.15]:34207 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750943AbdBNCqi (ORCPT ); Mon, 13 Feb 2017 21:46:38 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 229E3AAC7; Tue, 14 Feb 2017 02:46:37 +0000 (UTC) From: Goldwyn Rodrigues To: linux-fsdevel@vger.kernel.org Cc: jack@suse.cz, Goldwyn Rodrigues , linux-ext4@vger.kernel.org Subject: [PATCH 5/7] nonblocking aio: ext4 Date: Mon, 13 Feb 2017 20:46:01 -0600 Message-Id: <20170214024603.9563-6-rgoldwyn@suse.de> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170214024603.9563-1-rgoldwyn@suse.de> References: <20170214024603.9563-1-rgoldwyn@suse.de> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Goldwyn Rodrigues Return EAGAIN if any of the following checks fail for direct I/O: + i_rwsem is lockable + Writing beyond end of file (will trigger allocation) + Blocks are allocated at the write location Signed-off-by: Goldwyn Rodrigues --- fs/ext4/file.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 2a822d3..c8d1e41 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -93,11 +93,16 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct inode *inode = file_inode(iocb->ki_filp); int o_direct = iocb->ki_flags & IOCB_DIRECT; + int nonblocking = iocb->ki_flags & IOCB_NONBLOCKING; int unaligned_aio = 0; int overwrite = 0; ssize_t ret; - inode_lock(inode); + if (o_direct && nonblocking) { + if (!inode_trylock(inode)) + return -EAGAIN; + } else + inode_lock(inode); ret = generic_write_checks(iocb, from); if (ret <= 0) goto out; @@ -132,12 +137,18 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (o_direct) { size_t length = iov_iter_count(from); loff_t pos = iocb->ki_pos; + unsigned int blkbits = inode->i_blkbits; + + if (nonblocking + && (pos + length > EXT4_BLOCK_ALIGN(i_size_read(inode), blkbits))) { + ret = -EAGAIN; + goto out; + } /* check whether we do a DIO overwrite or not */ - if (ext4_should_dioread_nolock(inode) && !unaligned_aio && - pos + length <= i_size_read(inode)) { + if ((ext4_should_dioread_nolock(inode) && !unaligned_aio && + pos + length <= i_size_read(inode)) || nonblocking) { struct ext4_map_blocks map; - unsigned int blkbits = inode->i_blkbits; int err, len; map.m_lblk = pos >> blkbits; @@ -157,8 +168,13 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) * non-flags are returned. So we should check * these two conditions. */ - if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) - overwrite = 1; + if (err == len) { + if (map.m_flags & EXT4_MAP_MAPPED) + overwrite = 1; + } else if (nonblocking) { + ret = -EAGAIN; + goto out; + } } }