Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp3123620pxp; Tue, 22 Mar 2022 12:36:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwYh5S99VfYy0d+aqWyyNzWoDw75u3V3irU8fzdwjPEMv8LnMBOizAzCjS1y7/yfVhGp5D8 X-Received: by 2002:a17:903:404b:b0:154:297b:7125 with SMTP id n11-20020a170903404b00b00154297b7125mr18831811pla.11.1647977772622; Tue, 22 Mar 2022 12:36:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1647977772; cv=none; d=google.com; s=arc-20160816; b=f9ZFVbKk8DEqiXsvQHUIRmA2iFGZRF53U1uX5jW4AN3JRYZXOzRCHHJNouZjMCGy9d U1yCfmrplHgkmlJF0OJPdDa57WUX035HH100/3FMKh5Q6tLlbU6ardErKh+o6aKtQsj0 7gpCdqfR5wA4TvIZdmBr8G/P6IjPwGyMMWjYVm7BQ3sGmym/HbV0unC/OifJe31lbuH8 d5J4mS9BAShqi/YxaGIPG6F3KdReRskQnh/FUR1EBbQG+U4lnDNpOJXmX+5r2hJQ6W0t qftwDlHjzcYlFbDoH+Dq51MhakPKG+ttu4hO+QZ05+cBd1zAR7ZvEQ49YfSVukKRUR9m cenQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mYlcJXELlZhVptMh+O2GeI4aAI1hklR5kr3BVNYyJ0A=; b=uWBytJ8ip3hfsdTWW9VHvWeFdR2JIetQ8oFYXR4r9NXkEl0TmOPCXeGB/vSnxKSZTQ xBMpER0CiD6L1gbjCH436+Q87FnbgVTKyEbbYyoZbwhTUOjJl5UC1IeQOTJtrgBRENEH tDXClFXseGbfWzkUtvG3pBhAXxl65+aEZGIam9cqoRK5RPY36BDaFRnZlURySjkk9Ie9 ooUcwFwzLO4k3AW9KjSEQxHGJI1q0th83KrpX/SzcvADpTL0R5jBpe8FEoKhn4GJ0Ko9 NCbWrmRESX1Dxrin8TbI6WSeHYZnLyDKARrJ8oPnZXrKoqVjM1pQPbgqlxU4bhY384tL +iCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=oTzgcWJF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x21-20020a633115000000b003834c8174e6si4080329pgx.595.2022.03.22.12.35.49; Tue, 22 Mar 2022 12:36:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=oTzgcWJF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237343AbiCVOSx (ORCPT + 99 others); Tue, 22 Mar 2022 10:18:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237237AbiCVOQK (ORCPT ); Tue, 22 Mar 2022 10:16:10 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 060075EDCF; Tue, 22 Mar 2022 07:14:06 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3070561604; Tue, 22 Mar 2022 14:14:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3C11C340EC; Tue, 22 Mar 2022 14:14:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1647958443; bh=e+oOV9jSgG9m9f5wAlr9642Rk7E1Wa3hgaprHfDb/dg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oTzgcWJFNV4LI9X30f4Ftw7KG01r5h7CqR2bX0DZS4dtX4EcBOuNA7eW/FARmGwkf mPvz649l/RpgEcmqGXHtLSrAgJZz6FScJ1+q8h+XQ2nQqMNZWHpQefVs2L5YsXVQBv LkF3faVI+mqbOKZBCJm1UUWj6yyfk722+F2HarnuIu4jORw7XVJDcSTyFfe1Brp6yl aKWkeUXReToYwpT3uX1D9kiuVx7fwN+HXoAWg9Y1d7eN0LG4QpeZNYs2ODp5KlHaGm yWl9q3LqWYT7RIc+8Gx32FO54lsiu60nGyu+PDr+VdJjOEXz2lkmNRSoz1ILCG5ErO DtyjBy4y9t2hQ== From: Jeff Layton To: idryomov@gmail.com, xiubli@redhat.com Cc: ceph-devel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, lhenriques@suse.de Subject: [RFC PATCH v11 47/51] ceph: plumb in decryption during sync reads Date: Tue, 22 Mar 2022 10:13:12 -0400 Message-Id: <20220322141316.41325-48-jlayton@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220322141316.41325-1-jlayton@kernel.org> References: <20220322141316.41325-1-jlayton@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Switch to using sparse reads when the inode is encrypted. Note that the crypto block may be smaller than a page, but the reverse cannot be true. Signed-off-by: Jeff Layton --- fs/ceph/file.c | 89 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 19d5c50f60df..eb04dc8f1f93 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -934,7 +934,7 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, u64 off = *ki_pos; u64 len = iov_iter_count(to); u64 i_size = i_size_read(inode); - bool sparse = ceph_test_mount_opt(fsc, SPARSEREAD); + bool sparse = IS_ENCRYPTED(inode) || ceph_test_mount_opt(fsc, SPARSEREAD); u64 objver = 0; dout("sync_read on inode %p %llx~%llx\n", inode, *ki_pos, len); @@ -962,10 +962,19 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, int idx; size_t left; struct ceph_osd_req_op *op; + u64 read_off = off; + u64 read_len = len; + + /* determine new offset/length if encrypted */ + ceph_fscrypt_adjust_off_and_len(inode, &read_off, &read_len); + + dout("sync_read orig %llu~%llu reading %llu~%llu", + off, len, read_off, read_len); req = ceph_osdc_new_request(osdc, &ci->i_layout, - ci->i_vino, off, &len, 0, 1, - sparse ? CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ, + ci->i_vino, read_off, &read_len, 0, 1, + sparse ? CEPH_OSD_OP_SPARSE_READ : + CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, NULL, ci->i_truncate_seq, ci->i_truncate_size, false); @@ -974,10 +983,13 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, break; } + /* adjust len downward if the request truncated the len */ + if (off + len > read_off + read_len) + len = read_off + read_len - off; more = len < iov_iter_count(to); - num_pages = calc_pages_for(off, len); - page_off = off & ~PAGE_MASK; + num_pages = calc_pages_for(read_off, read_len); + page_off = offset_in_page(off); pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL); if (IS_ERR(pages)) { ceph_osdc_put_request(req); @@ -985,7 +997,8 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, break; } - osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_off, + osd_req_op_extent_osd_data_pages(req, 0, pages, read_len, + offset_in_page(read_off), false, false); op = &req->r_ops[0]; @@ -1004,7 +1017,7 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, ceph_update_read_metrics(&fsc->mdsc->metric, req->r_start_latency, req->r_end_latency, - len, ret); + read_len, ret); if (ret > 0) objver = req->r_version; @@ -1019,8 +1032,34 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, else if (ret == -ENOENT) ret = 0; + if (ret > 0 && IS_ENCRYPTED(inode)) { + int fret; + + fret = ceph_fscrypt_decrypt_extents(inode, pages, read_off, + op->extent.sparse_ext, op->extent.sparse_ext_cnt); + if (fret < 0) { + ret = fret; + ceph_osdc_put_request(req); + break; + } + + /* account for any partial block at the beginning */ + fret -= (off - read_off); + + /* + * Short read after big offset adjustment? + * Nothing is usable, just call it a zero + * len read. + */ + fret = max(fret, 0); + + /* account for partial block at the end */ + ret = min_t(ssize_t, fret, len); + } + ceph_osdc_put_request(req); + /* Short read but not EOF? Zero out the remainder. */ if (ret >= 0 && ret < len && (off + ret < i_size)) { int zlen = min(len - ret, i_size - off - ret); int zoff = page_off + ret; @@ -1034,15 +1073,16 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, idx = 0; left = ret > 0 ? ret : 0; while (left > 0) { - size_t len, copied; - page_off = off & ~PAGE_MASK; - len = min_t(size_t, left, PAGE_SIZE - page_off); + size_t plen, copied; + + plen = min_t(size_t, left, PAGE_SIZE - page_off); SetPageUptodate(pages[idx]); copied = copy_page_to_iter(pages[idx++], - page_off, len, to); + page_off, plen, to); off += copied; left -= copied; - if (copied < len) { + page_off = 0; + if (copied < plen) { ret = -EFAULT; break; } @@ -1059,20 +1099,21 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, break; } - if (off > *ki_pos) { - if (off >= i_size) { - *retry_op = CHECK_EOF; - ret = i_size - *ki_pos; - *ki_pos = i_size; - } else { - ret = off - *ki_pos; - *ki_pos = off; + if (ret > 0) { + if (off > *ki_pos) { + if (off >= i_size) { + *retry_op = CHECK_EOF; + ret = i_size - *ki_pos; + *ki_pos = i_size; + } else { + ret = off - *ki_pos; + *ki_pos = off; + } } - } - - if (last_objver && ret > 0) - *last_objver = objver; + if (last_objver) + *last_objver = objver; + } dout("sync_read result %zd retry_op %d\n", ret, *retry_op); return ret; } -- 2.35.1