Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp2964524imm; Sun, 7 Oct 2018 16:29:47 -0700 (PDT) X-Google-Smtp-Source: ACcGV630RtzA3OGc6Zir3RLFNxkz8HsLAGDX3SfW2tWhCmBlmEaQcuMUhxUXrD+h0Pw7wIYsgAPp X-Received: by 2002:a62:d046:: with SMTP id p67-v6mr23224503pfg.147.1538954987742; Sun, 07 Oct 2018 16:29:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538954987; cv=none; d=google.com; s=arc-20160816; b=kp9RUxQpcfKJ2lY2YbrIBvYCAPsgx8/1qgZn20U68nPoQQL5xPlgfZvTjNQ61LLyGr oST2GdCSH8OMk5Vkv8ib4bqOCUWNVwxbguXVaAvepMZ449UfDNFAHu17ScJmETZt5S+C FwdzZwVJuEqe9ENGVnugJ1tW1ED/GUM6FBnETf9Y6kJqA5H1QBj52s45cU/WYBpCZ83b 0C+Qs81Fvg2CYHccRuJlgix8WR6NINwjel+tIJvQRPqEyW08es8JLjxapNmM2h7Z28rr TJgZd3/uUo5caDBtBC5cdLta2k4ComoNCwJBSe6dvqXVFdtlG6SstHG39lsAOcg9cyAU 7rRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=idwzqZPvg8/SO2d47Tiai819xLoijednl4cLWo+6w+s=; b=N4jLu1y/SuZu9i/TDNc0uSODYjajK525I2xg+q/h18d9VY+6SHIVYf/eNzkX15EFb5 QrfgqZ0Oi8FY5nqNewDIH0k7gQQOwqfrL1yAyLGWNnI7YubJVJ72lzucBqu4+NpXlLVG Xxzu+F1Fouga272efbnXw9ziSi4M4wmsWorOzaZLBIGiDqoRN3bd9NIyyGeSTcGMnMGk vrzfCR+X9xDaLA0evt1KlOK7Qsb7Mg8tmPZa0h30HzHS2Jmi/Yxou9AoQfJZ3RKSIH8t ToJAuou78qH+boeRcfNj5OFAXl1d62FuOfvx7+GwmmhIGOK/SHvDKZjWsExrRgJTNwSE p6ew== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@omnibond-com.20150623.gappssmtp.com header.s=20150623 header.b=Kl0bmeQh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m66-v6si9481698pfm.191.2018.10.07.16.29.32; Sun, 07 Oct 2018 16:29:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@omnibond-com.20150623.gappssmtp.com header.s=20150623 header.b=Kl0bmeQh; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728273AbeJHGhG (ORCPT + 99 others); Mon, 8 Oct 2018 02:37:06 -0400 Received: from mail-qt1-f171.google.com ([209.85.160.171]:44923 "EHLO mail-qt1-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726607AbeJHGhF (ORCPT ); Mon, 8 Oct 2018 02:37:05 -0400 Received: by mail-qt1-f171.google.com with SMTP id c56-v6so19234126qtd.11 for ; Sun, 07 Oct 2018 16:28:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=omnibond-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=idwzqZPvg8/SO2d47Tiai819xLoijednl4cLWo+6w+s=; b=Kl0bmeQhRLbOp8e10VYDEBWzXbs1XVIPte3v94zI+thh8DSQ85o8LyIEfrHtbUzu/K FaA++BOypsbxzYlkxrPJsVCC69JP9OijqRVDn1RkyBJW7Idwxbt3yHNzJCba3TGVVBcQ QiG2uD1pLDQi45oubvhjjkHQRMytnNd4LnjlIrbiOuUGZ5by/z4RDrWGeFjUAtHzbZ6R b7ZkmK/H8WraNPu6MGIZq2+kEr4qqK30AoC2lDM0TR8WySCzjcL92jCaUP6b2vm5bVz4 /3E/j7xyhyGPQ2aKvCIKPQb5maoacc7USyDUH+W70KK0RP1jdjToVG4x6MMZkRabaQP9 WE4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=idwzqZPvg8/SO2d47Tiai819xLoijednl4cLWo+6w+s=; b=RqnWEmWTUjXBUE3Z5/q4czABr3o0EJGmOYjsGjs0pjWwnvmnQ6VOUSzk8PHSq6pHN1 pLBmSrZ47s+BsyhYEVjTLx6ykSLfdb+AqSOyc7A7mDXT7jep5kVm2MM/ntwc+xLqhtbQ A1kOcLLR71QVT7Md+GRMTNXDxs9maIgbv1yEfAArCzW3Too5r5CDGHJHdS8rJdngkfG7 XmVLGaek4Im/5jZ6Fc57HysFssgKqgD2cpcyUee9/tlXClXfDGEiuX8FrOc8gK8COHJJ ws49VwCjiLigzmKY1YLWCopCeYLpshR0DvG4S9lM4z482Vmt19iKIqyq+x4d2bwE5Ufy 9FqA== X-Gm-Message-State: ABuFfoinlYIS8QHp6mILBeOvELTkCGS8RVutoBHsVXH4BrDepddU9or8 wPxlxloL2cMc+OxUtRgP82jkDQ== X-Received: by 2002:ad4:51d2:: with SMTP id p18-v6mr17708711qvq.186.1538954890542; Sun, 07 Oct 2018 16:28:10 -0700 (PDT) Received: from ip-172-31-22-34.ec2.internal (ec2-35-153-175-159.compute-1.amazonaws.com. [35.153.175.159]) by smtp.gmail.com with ESMTPSA id x38-v6sm6793915qtc.39.2018.10.07.16.28.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 07 Oct 2018 16:28:09 -0700 (PDT) From: Martin Brandenburg To: devel@lists.orangefs.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, hubcap@omnibond.com Cc: Martin Brandenburg Subject: [PATCH 12/19] orangefs: implement writepage Date: Sun, 7 Oct 2018 23:27:29 +0000 Message-Id: <20181007232736.3780-13-martin@omnibond.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181007232736.3780-1-martin@omnibond.com> References: <20181007232736.3780-1-martin@omnibond.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now orangefs_inode_getattr fills from cache if an inode has dirty pages. also if attr_valid and dirty pages and !flags, we spin on inode writeback before returning if pages still dirty after: should it be other way Signed-off-by: Martin Brandenburg --- fs/orangefs/file.c | 77 +++++++----------------------------- fs/orangefs/inode.c | 59 ++++++++++++++++++++++++--- fs/orangefs/orangefs-utils.c | 12 +++++- 3 files changed, 78 insertions(+), 70 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 4bc06c310e02..ba580a5c6fd2 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * (C) 2001 Clemson University and The University of Chicago + * Copyright 2018 Omnibond Systems, L.L.C. * * See COPYING in top-level directory. */ @@ -348,65 +349,11 @@ static ssize_t orangefs_file_read_iter(struct kiocb *iocb, return generic_file_read_iter(iocb, iter); } -static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) +static ssize_t orangefs_file_write_iter(struct kiocb *iocb, + struct iov_iter *iter) { - struct file *file = iocb->ki_filp; - loff_t pos; - ssize_t rc; - - BUG_ON(iocb->private); - - truncate_inode_pages(file->f_mapping, 0); - - gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_write_iter\n"); - - inode_lock(file->f_mapping->host); - - /* Make sure generic_write_checks sees an up to date inode size. */ - if (file->f_flags & O_APPEND) { - rc = orangefs_inode_getattr(file->f_mapping->host, - ORANGEFS_GETATTR_SIZE); - if (rc == -ESTALE) - rc = -EIO; - if (rc) { - gossip_err("%s: orangefs_inode_getattr failed, " - "rc:%zd:.\n", __func__, rc); - goto out; - } - } - - rc = generic_write_checks(iocb, iter); - - if (rc <= 0) { - gossip_err("%s: generic_write_checks failed, rc:%zd:.\n", - __func__, rc); - goto out; - } - - /* - * if we are appending, generic_write_checks would have updated - * pos to the end of the file, so we will wait till now to set - * pos... - */ - pos = iocb->ki_pos; - - rc = do_readv_writev(ORANGEFS_IO_WRITE, - file, - &pos, - iter); - if (rc < 0) { - gossip_err("%s: do_readv_writev failed, rc:%zd:.\n", - __func__, rc); - goto out; - } - - iocb->ki_pos = pos; orangefs_stats.writes++; - -out: - - inode_unlock(file->f_mapping->host); - return rc; + return generic_file_write_iter(iocb, iter); } /* @@ -501,9 +448,6 @@ static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma) (char *)file->f_path.dentry->d_name.name : (char *)"Unknown")); - if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) - return -EINVAL; - /* set the sequential readahead hint */ vma->vm_flags |= VM_SEQ_READ; vma->vm_flags &= ~VM_RAND_READ; @@ -543,8 +487,6 @@ static int orangefs_file_release(struct inode *inode, struct file *file) gossip_debug(GOSSIP_INODE_DEBUG, "flush_racache finished\n"); } - truncate_inode_pages(file_inode(file)->i_mapping, - 0); } return 0; } @@ -562,6 +504,11 @@ static int orangefs_fsync(struct file *file, ORANGEFS_I(file_inode(file)); struct orangefs_kernel_op_s *new_op = NULL; + ret = filemap_write_and_wait_range(file_inode(file)->i_mapping, + start, end); + if (ret) + return ret; + new_op = op_alloc(ORANGEFS_VFS_OP_FSYNC); if (!new_op) return -ENOMEM; @@ -643,6 +590,11 @@ static int orangefs_lock(struct file *filp, int cmd, struct file_lock *fl) return rc; } +int orangefs_flush(struct file *file, fl_owner_t id) +{ + return vfs_fsync(file, 0); +} + /** ORANGEFS implementation of VFS file operations */ const struct file_operations orangefs_file_operations = { .llseek = orangefs_file_llseek, @@ -652,6 +604,7 @@ const struct file_operations orangefs_file_operations = { .unlocked_ioctl = orangefs_ioctl, .mmap = orangefs_file_mmap, .open = generic_file_open, + .flush = orangefs_flush, .release = orangefs_file_release, .fsync = orangefs_fsync, }; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 826054b979cc..bd2ce18453f2 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -15,6 +15,44 @@ #include "orangefs-kernel.h" #include "orangefs-bufmap.h" +static int orangefs_writepage(struct page *page, struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + struct iov_iter iter; + struct bio_vec bv; + size_t len, wlen; + ssize_t ret; + loff_t off; + + set_page_writeback(page); + + off = page_offset(page); + len = i_size_read(inode); + if (off + PAGE_SIZE > len) + wlen = len - off; + else + wlen = PAGE_SIZE; + + bv.bv_page = page; + bv.bv_len = wlen; + bv.bv_offset = off % PAGE_SIZE; + if (wlen == 0) + dump_stack(); + iov_iter_bvec(&iter, ITER_BVEC | WRITE, &bv, 1, wlen); + + ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, wlen, + len); + if (ret < 0) { + SetPageError(page); + mapping_set_error(page->mapping, ret); + } else { + ret = 0; + } + end_page_writeback(page); + unlock_page(page); + return ret; +} + static int orangefs_readpage(struct file *file, struct page *page) { struct inode *inode = page->mapping->host; @@ -48,6 +86,15 @@ static int orangefs_readpage(struct file *file, struct page *page) return ret; } +int orangefs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) +{ + int r; + r = simple_write_end(file, mapping, pos, len, copied, page, fsdata); + mark_inode_dirty_sync(file_inode(file)); + return r; +} + static void orangefs_invalidatepage(struct page *page, unsigned int offset, unsigned int length) @@ -77,17 +124,17 @@ static ssize_t orangefs_direct_IO(struct kiocb *iocb, { struct file *file = iocb->ki_filp; loff_t pos = *(&iocb->ki_pos); - /* - * This cannot happen until write_iter becomes - * generic_file_write_iter. - */ - BUG_ON(iov_iter_rw(iter) != READ); - return do_readv_writev(ORANGEFS_IO_READ, file, &pos, iter); + return do_readv_writev(iov_iter_rw(iter) == WRITE ? + ORANGEFS_IO_WRITE : ORANGEFS_IO_READ, file, &pos, iter); } /** ORANGEFS2 implementation of address space operations */ static const struct address_space_operations orangefs_address_operations = { + .writepage = orangefs_writepage, .readpage = orangefs_readpage, + .set_page_dirty = __set_page_dirty_nobuffers, + .write_begin = simple_write_begin, + .write_end = orangefs_write_end, .invalidatepage = orangefs_invalidatepage, .releasepage = orangefs_releasepage, .direct_IO = orangefs_direct_IO, diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 9221c4a3398e..902ebd1599e1 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -247,12 +247,16 @@ int orangefs_inode_getattr(struct inode *inode, int flags) spin_lock(&inode->i_lock); /* Must have all the attributes in the mask and be within cache time. */ if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) || - orangefs_inode->attr_valid) { + orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) { if (orangefs_inode->attr_valid) { spin_unlock(&inode->i_lock); write_inode_now(inode, 1); goto again; } + if (inode->i_state & I_DIRTY_PAGES) { + spin_unlock(&inode->i_lock); + return 0; + } spin_unlock(&inode->i_lock); return 0; } @@ -281,12 +285,16 @@ int orangefs_inode_getattr(struct inode *inode, int flags) spin_lock(&inode->i_lock); /* Must have all the attributes in the mask and be within cache time. */ if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) || - orangefs_inode->attr_valid) { + orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) { if (orangefs_inode->attr_valid) { spin_unlock(&inode->i_lock); write_inode_now(inode, 1); goto again2; } + if (inode->i_state & I_DIRTY_PAGES) { + spin_unlock(&inode->i_lock); + return 0; + } gossip_debug(GOSSIP_UTILS_DEBUG, "%s: in cache or dirty\n", __func__); ret = 0; -- 2.19.0