From nobody Wed Dec 17 17:39:16 2025 Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B28128643E for ; Fri, 3 Oct 2025 09:11:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482685; cv=none; b=XnJk9dHAkSCuq3f0piOz55EgWuhbjtY5i6jhPzlqfQunY2OvRMzRgqIJYJSHKYgGVsGexEkhPw4zYeOaAfYvS7BXxcJac1+nilVTJ26BHgLlCToWYJyJAjT923GUfBAOvQbTzh9b6A1eN9MMmNcA2cDEf9J3qX9d4giPCOctI38= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482685; c=relaxed/simple; bh=5qgmGmYUOhVgTZvRetnu8/iMUpcsPIqnDj4z+RlR7p4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GbeDk++CgEXGml5cZAJGOSgMt5kigHlubtgoCJ+C+s+IFqp7ocE5GqbQSGiEB09PJv/UFHb1J1JMV1AWWzQ6t/u6MDa6GX0szbPqXERQL2cc4b8bCST77rajlU3vZ9SQYBmPjFoVHsxoUF32kxtQr5n5GHGcEimbk5WBKHw6dMc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VDNC8yhZ; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VDNC8yhZ" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-57db15eeb11so2314797e87.2 for ; Fri, 03 Oct 2025 02:11:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759482681; x=1760087481; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=arnOv/Eb+ei+WprDdJ+AExiCBQfw52nTIK0kxgp5nQs=; b=VDNC8yhZ0euZu+Sakhfq1zPg2AzcbewP7Ea/L8hXjLnvodrUcHqpwmxsetxZ15OUvo KZBbTFBGS/XdVA8EmrsfPO5ml8g+pB+qDn/kqQg+P8ZJiO+zNHnMlXnh4k8L4d9PGPFu 9Dqg2bsEG+ytT6E4tOT/w3WQreaIC70Xs+r9Hb7MdQ/uB0oRuzuJiedNEIpmUQALo2xg rme723sLziHkh1tDRnPOa6au8V0c1z8MylVjMln8rj5Q7HmJWwtrCUvLz/ytgzyLc3HO UEki9ZvSwBiYmh+FUqQEzlxDA8LV9m6PRuP+JoXZUWnzIBG0dnmBq7yfEcfa8wTUVuUl B2dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759482681; x=1760087481; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=arnOv/Eb+ei+WprDdJ+AExiCBQfw52nTIK0kxgp5nQs=; b=v4+igYASeGpBlWW/h5qR5bYtP4GyZU8m3W58s8tDxXusfNs6tEXMOtw0yrCgHwmyjq aJ9zKHa9NRXjOXtSIfo9RcWpeUIkw+uu9H08fl7JnXoGICEzL20KmuQXkNluwAxLZXFj c/ebuW6lNYcS6a2L9RELLoXzS+Z+C59p8qwWZmFr2456HXcr/xViwHNEXg5hXtr6+SxV Fqk2jmQce4voxCHmPRI6pSDH4RfZfFIwPdARFjV7nn961fgmk521uDhcRDz0qrqSRMLL DQYzaz0zoQtEh03tfA+w8of1Z2ITEC3iTrTPm37N387BnIWnEKyPO8GOgFayIhZ0CqxZ zaBw== X-Forwarded-Encrypted: i=1; AJvYcCXEcojwy96FzjhocQT9syJGyC6QX1Bovz7Fa7sU74M0k20noj2LUNgNixGFzqg03BFCYCb3Q3jEF6A2GaA=@vger.kernel.org X-Gm-Message-State: AOJu0YyfIENOyBjMd2JW/lGqHlY5hcjyzf/qebMBHznv320bc8jxN4Es F6OSwph6r5UHlqprenTBgR/4OPfSLYfkDg9FZ/NkM+i/24ienMWdT0xn X-Gm-Gg: ASbGncuGgEYnYyp3+vfF66mHyCR9NXVtFfwW2f/4CtrezP+FANJOcPwIuwUf5qRvvXW +qO0QPAg2XGZwNOT8fGdAU1u4QdVMj/Khdw+iB06QKg0PHGX5VZX0LKuahaVbZcAUpAroGK8keq WvdmvHMXQBaWZe7txaR7/C+xTkghX9i7AtEPDYRwALpZCKfoJkl+IPEOlTQmylRb7yFnQTZUsxi W58QUX72Two62mJpWhyOz6uEnzs1bBrE7R0MMkQrj6pse8E2cl7zYkZq4dJmskovCdkHvHrssQs lkiMBOWjdsTPnTlLPuuGphtYxIKVDGjaTHUvUCWCs0qzomqPJjeVUjxeMaXtzzhhjSJke+mMur7 74fc0a87LB7BbUVIgYESaQI9pyMipZfUE2rDVjcSI4CY1h1OASTPtOBa1bSJIiJBzWh9YCvybcE G8 X-Google-Smtp-Source: AGHT+IE0aTdUm34GWxVWeIcSrnaWArAnE74mpIbehfqtmMHNBlov2Lov3oNlbPMqnpOMOxtDIGa47g== X-Received: by 2002:a05:651c:1548:b0:372:9420:9509 with SMTP id 38308e7fff4ca-374c37001bdmr6162771fa.15.1759482681129; Fri, 03 Oct 2025 02:11:21 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-373ba444480sm13498971fa.30.2025.10.03.02.11.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 02:11:20 -0700 (PDT) From: Sergey Bashirov To: Chuck Lever , Christoph Hellwig , Dai Ngo , Jeff Layton , NeilBrown , Olga Kornievskaia , Tom Talpey Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Bashirov , Christoph Hellwig Subject: [PATCH v3 1/4] NFSD/blocklayout: Fix minlength check in proc_layoutget Date: Fri, 3 Oct 2025 12:11:03 +0300 Message-ID: <20251003091115.184075-2-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003091115.184075-1-sergeybashirov@gmail.com> References: <20251003091115.184075-1-sergeybashirov@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The extent returned by the file system may have a smaller offset than the segment offset requested by the client. In this case, the minimum segment length must be checked against the requested range. Otherwise, the client may not be able to continue the read/write operation. Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig --- fs/nfsd/blocklayout.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index fde5539cf6a6..425648565ab2 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct= inode *inode, { struct nfsd4_layout_seg *seg =3D &args->lg_seg; struct super_block *sb =3D inode->i_sb; + u64 length; u32 block_size =3D i_blocksize(inode); struct pnfs_block_extent *bex; struct iomap iomap; @@ -56,7 +57,8 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct= inode *inode, goto out_error; } =20 - if (iomap.length < args->lg_minlength) { + length =3D iomap.offset + iomap.length - seg->offset; + if (length < args->lg_minlength) { dprintk("pnfsd: extent smaller than minlength\n"); goto out_layoutunavailable; } --=20 2.43.0 From nobody Wed Dec 17 17:39:16 2025 Received: from mail-lf1-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BEBE275AF2 for ; Fri, 3 Oct 2025 09:11:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482687; cv=none; b=BXr0/hG5r8/EV+3nVZLtUxYsCDMkndWY/yGHgvFdupltJ5dxUvG0m6TNkGwpi+UhMl3+Zvjwij4fq155ScIEcr1zpB7uLOfKRnxBYC2RxpUb+VIEeMGfhrKej1iIn9VGnbnxtJ4rtXVkB9vKB0rYBoBEUYNLkw0VAubRrWZTLUc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482687; c=relaxed/simple; bh=bIFqvMBhqhwmcgcZ4MQVyIHVC5lZccPFA8Mv6XHN7AA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mUDI6sK7J+uXLlNFNa8PbNK8sPF3fe+OYvt0Rp+McwO3pFT3HCfh6CTnIGSVbDs4B38O/F1Hdd4yxI3woNtO7CsqYQ3KOwDglNtVMxr5wzBMlEbkFCi+H6F4RRZQhuRevQtYuzzLXlulo8FmFeXsUonx8hDJk6Dxmi8GtjE5Tnw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DvMsbvbX; arc=none smtp.client-ip=209.85.167.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DvMsbvbX" Received: by mail-lf1-f42.google.com with SMTP id 2adb3069b0e04-579d7104c37so2828789e87.3 for ; Fri, 03 Oct 2025 02:11:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759482683; x=1760087483; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6pxsmtIah7HBjRLQj3EA/UxoyVXQkam0zyy01vtxYeo=; b=DvMsbvbXYd+B6Q9R0+cjRF8DG1pW75yyFcwVwE7bZxwDOxfg8m8ua+61RwhDO/mJK8 ND+UNeQxJQRzFNEuH3RAC3dHxfzamSaiRG1uZ1H6jVB5u29x6mOxXA3rRpdsJTJRwIhN eACxG3eFX1uSq3QxnPKVGSsY5dAiKdfouepfd3jZLUP5UdajvCDxrdYII7qFM3Bn2wW6 maFTJDlxHisMaTXacnDMy81RvJGeOfBdY2kuxpT7Lca0OdtuXNsRqY43MWdO5DOLD26p yHF7tuiN9cjjlI0gHVrNMf0loTmJoe+hnl4eAJTwk3KvTbP6OATNALmNt38zGSUUAizu PnBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759482683; x=1760087483; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6pxsmtIah7HBjRLQj3EA/UxoyVXQkam0zyy01vtxYeo=; b=D5vbV2UlWYjkgJnw7lMZd0uAoggpuuco95Ah8aKTSG7Mpw/LIi8CnqhIC367hlCFgI 2w7oXjeh+6vh0auxydvHa/q680L0Q622VsdrbxEwm+X13DAMKjQbkwL2reejde5JDA89 fFi/E0W7S/rXYmI71cS2nTLWcDuh1TmdIb4VSuJuPmHElGZZBUL1QShxESxLkUBwo+yR qUW3GwidRUG8EDKTH48IbuG8zOrJl5zL7rC5gMP6ZkEz4ZUPBwEInFK3qnXyCCjhQsPS 2Jcr6L7GN8lhfyzIBkcl5eoF82ipqFnQNNXOqRHMQ/xAzBOHihmP3Y7UgbGc4X0ptFoQ 90bQ== X-Forwarded-Encrypted: i=1; AJvYcCXtU6N71QjVHheXQ0MrRmlW0pXsRDBLDcUzzbyiNBIC1dcyY3lYtEp9455KJQIPmWdGSRizFnu/6nwSjEs=@vger.kernel.org X-Gm-Message-State: AOJu0YzEtX8h3pZ67u6h38SRPiZJDbmkyZmEMbpzG2njOo+l3mETUczp phtIh+3gc9/gnFUdO4/LzdCSkuyBORtswSEjexpBjKdeNuLY+zfm8PG4 X-Gm-Gg: ASbGnctSUTbdQdzaXXXRiRdXueQdgo76IxtuUcgJODyD9jGYJyx1kpGB6QcllhfwLV/ GSgd6yhLpRYfk4BCD5AbCzbrOon2ptEhzzOVrgpBm++P9oz1Wztt3DFu4UhiX3pLwxsLBSZrsgQ 7kfehLVe98yBHnqngUK0DDDwjxOmaW5VP61atxTP8HPztpC/ZEnfcc11u9PpEMWi3bs0zPqddxW 8fZVPc7wVxWqtyz7neD0QfrhVrkAMmr+WWoeuQvZX6Iv+pjp2ZoijwR8IqUGzQwQLsEcNMmiKhp 7Pmy0cqdomQAXb5aIX9lIZSXQFUTrTp2Q3gh8J50pzyQR45CjQDsLMatSzgJXkN3wZbULEv5D7+ nbvCo4rVzQ7fAQMOKnT5LUme5WM23RR2ooDRISlZkqaRFfefL0yOVtjqm1GpFa0BUTSH1Afv1qz bO X-Google-Smtp-Source: AGHT+IHW9T7WlOK4+T0hBfSAzghb7rtXEr5URd0twIoAFnjTsNGrfGxgzL5o3XRAYloFcEblSRmzlQ== X-Received: by 2002:a2e:a987:0:b0:36d:4996:1c4d with SMTP id 38308e7fff4ca-374c36c4b2amr6307481fa.9.1759482683019; Fri, 03 Oct 2025 02:11:23 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-373ba444480sm13498971fa.30.2025.10.03.02.11.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 02:11:22 -0700 (PDT) From: Sergey Bashirov To: Chuck Lever , Christoph Hellwig , Dai Ngo , Jeff Layton , NeilBrown , Olga Kornievskaia , Tom Talpey Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Bashirov , Christoph Hellwig Subject: [PATCH v3 2/4] NFSD/blocklayout: Extract extent mapping from proc_layoutget Date: Fri, 3 Oct 2025 12:11:04 +0300 Message-ID: <20251003091115.184075-3-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003091115.184075-1-sergeybashirov@gmail.com> References: <20251003091115.184075-1-sergeybashirov@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" No changes in functionality. Split the proc_layoutget function to create a helper function that maps single extent to the requested range. This helper function is then used to implement support for multiple extents per LAYOUTGET. Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig --- fs/nfsd/blocklayout.c | 115 ++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 425648565ab2..35a95501db63 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -17,68 +17,44 @@ #define NFSDDBG_FACILITY NFSDDBG_PNFS =20 =20 +/* + * Get an extent from the file system that starts at offset or below + * and may be shorter than the requested length. + */ static __be32 -nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode, - const struct svc_fh *fhp, struct nfsd4_layoutget *args) +nfsd4_block_map_extent(struct inode *inode, const struct svc_fh *fhp, + u64 offset, u64 length, u32 iomode, u64 minlength, + struct pnfs_block_extent *bex) { - struct nfsd4_layout_seg *seg =3D &args->lg_seg; struct super_block *sb =3D inode->i_sb; - u64 length; - u32 block_size =3D i_blocksize(inode); - struct pnfs_block_extent *bex; struct iomap iomap; u32 device_generation =3D 0; int error; =20 - if (locks_in_grace(SVC_NET(rqstp))) - return nfserr_grace; - - if (seg->offset & (block_size - 1)) { - dprintk("pnfsd: I/O misaligned\n"); - goto out_layoutunavailable; - } - - /* - * Some clients barf on non-zero block numbers for NONE or INVALID - * layouts, so make sure to zero the whole structure. - */ - error =3D -ENOMEM; - bex =3D kzalloc(sizeof(*bex), GFP_KERNEL); - if (!bex) - goto out_error; - args->lg_content =3D bex; - - error =3D sb->s_export_op->map_blocks(inode, seg->offset, seg->length, - &iomap, seg->iomode !=3D IOMODE_READ, - &device_generation); + error =3D sb->s_export_op->map_blocks(inode, offset, length, &iomap, + iomode !=3D IOMODE_READ, &device_generation); if (error) { if (error =3D=3D -ENXIO) - goto out_layoutunavailable; - goto out_error; - } - - length =3D iomap.offset + iomap.length - seg->offset; - if (length < args->lg_minlength) { - dprintk("pnfsd: extent smaller than minlength\n"); - goto out_layoutunavailable; + return nfserr_layoutunavailable; + return nfserrno(error); } =20 switch (iomap.type) { case IOMAP_MAPPED: - if (seg->iomode =3D=3D IOMODE_READ) + if (iomode =3D=3D IOMODE_READ) bex->es =3D PNFS_BLOCK_READ_DATA; else bex->es =3D PNFS_BLOCK_READWRITE_DATA; bex->soff =3D iomap.addr; break; case IOMAP_UNWRITTEN: - if (seg->iomode & IOMODE_RW) { + if (iomode & IOMODE_RW) { /* * Crack monkey special case from section 2.3.1. */ - if (args->lg_minlength =3D=3D 0) { + if (minlength =3D=3D 0) { dprintk("pnfsd: no soup for you!\n"); - goto out_layoutunavailable; + return nfserr_layoutunavailable; } =20 bex->es =3D PNFS_BLOCK_INVALID_DATA; @@ -87,7 +63,7 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct= inode *inode, } fallthrough; case IOMAP_HOLE: - if (seg->iomode =3D=3D IOMODE_READ) { + if (iomode =3D=3D IOMODE_READ) { bex->es =3D PNFS_BLOCK_NONE_DATA; break; } @@ -95,27 +71,68 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, stru= ct inode *inode, case IOMAP_DELALLOC: default: WARN(1, "pnfsd: filesystem returned %d extent\n", iomap.type); - goto out_layoutunavailable; + return nfserr_layoutunavailable; } =20 error =3D nfsd4_set_deviceid(&bex->vol_id, fhp, device_generation); if (error) - goto out_error; + return nfserrno(error); + bex->foff =3D iomap.offset; bex->len =3D iomap.length; + return nfs_ok; +} + +static __be32 +nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode, + const struct svc_fh *fhp, struct nfsd4_layoutget *args) +{ + struct nfsd4_layout_seg *seg =3D &args->lg_seg; + struct pnfs_block_extent *bex; + u64 length; + u32 block_size =3D i_blocksize(inode); + __be32 nfserr; + + if (locks_in_grace(SVC_NET(rqstp))) + return nfserr_grace; =20 - seg->offset =3D iomap.offset; - seg->length =3D iomap.length; + nfserr =3D nfserr_layoutunavailable; + if (seg->offset & (block_size - 1)) { + dprintk("pnfsd: I/O misaligned\n"); + goto out_error; + } + + /* + * Some clients barf on non-zero block numbers for NONE or INVALID + * layouts, so make sure to zero the whole structure. + */ + nfserr =3D nfserrno(-ENOMEM); + bex =3D kzalloc(sizeof(*bex), GFP_KERNEL); + if (!bex) + goto out_error; + args->lg_content =3D bex; + + nfserr =3D nfsd4_block_map_extent(inode, fhp, seg->offset, seg->length, + seg->iomode, args->lg_minlength, bex); + if (nfserr !=3D nfs_ok) + goto out_error; + + nfserr =3D nfserr_layoutunavailable; + length =3D bex->foff + bex->len - seg->offset; + if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_error; + } + + seg->offset =3D bex->foff; + seg->length =3D bex->len; =20 dprintk("GET: 0x%llx:0x%llx %d\n", bex->foff, bex->len, bex->es); - return 0; + return nfs_ok; =20 out_error: seg->length =3D 0; - return nfserrno(error); -out_layoutunavailable: - seg->length =3D 0; - return nfserr_layoutunavailable; + return nfserr; } =20 static __be32 --=20 2.43.0 From nobody Wed Dec 17 17:39:16 2025 Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D139F2D542A for ; Fri, 3 Oct 2025 09:11:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482688; cv=none; b=bvhs07hvMMtqGwkSTVQUH5KgCHOvpyTBxqYOqtTiTW0hGr14m+3ledZkogv0kAu4K4d/7qM2tfgJ3ObqGYGOF4qbWEUpDfQ8tSce8kZYLmqMUL9b9/gvPxenJa5bf+oMDPPdT7tpUYnOh3Yg9F6CjrmR1BOP4AZNZc793YdRvYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482688; c=relaxed/simple; bh=4Q3QaDycZlayj+5emorjUsIeZOosRc/NtSQvzYPykDc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OZWL8BSGRLa6jSulmfRnQh+k70YIHguFpQRvuPhzTc7us6cFdozodT8+9/FiNZOkwqu7T3sG7E+u7iofbFaekGkUdlQpFNHXJirN85TA64FUbd1PdC0AO+8S0XuHXXHF66iNSJYC0fdmXNvOWPQsYAEMo2iHoiKggCblKwGsUvE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IVt6pl5U; arc=none smtp.client-ip=209.85.167.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IVt6pl5U" Received: by mail-lf1-f44.google.com with SMTP id 2adb3069b0e04-58af7f8b79dso1886348e87.3 for ; Fri, 03 Oct 2025 02:11:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759482685; x=1760087485; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4eQrJ6U8zwJxNRHxnkX4GFTCD/jiPljD9W/O4v8njYs=; b=IVt6pl5UXE6PGHfSGbO+/hCZKaod176tZKEJaXBH0G2ru0SWWU8BSMLQFaZNEOPWT1 s2ByQ9WKW3vxvOknLR7LTvtAiS9RDiR5kvp+tilyaXdxMQSBxbzRDt7W6NkHx+XpkvN1 BU/jxVT2crmk74Lj6ITz/NwA8vjtNVAOV1FZseNLfB67MVISwx/evzMH6g7Lu2msWbn/ kcgPKru/Dgg5/dYsxAQkrHbOCOGfvS8PvhDsSwClt1leOENe8bpbAm59qn2DsX1dHX62 zZzGctG51V2OBr8kvQIuA1c+1m4BXiBLBpOqr6aWVTCQtjEdEdJ1EJOdKGEa1cpjeQq1 Kv1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759482685; x=1760087485; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4eQrJ6U8zwJxNRHxnkX4GFTCD/jiPljD9W/O4v8njYs=; b=qB85jEPTuuVG7z4TXtd25S/Zp9ZprKADcGMrKNNauT/Bn+BCoFgGMtmbk4q2UVkCP3 kdsIyS64pqn5ONNWhj9n5BVewXsa3zV3sZEpySg6qiIEARLzsN44O2vyFy45auuyw2P9 Rohg8a/jqsgS7wnMYsgpNARAjLcSvVx0yYfeFwcGlrtj5h6jJ+aSXQBGEHd98h4EBU+V lO5FgO9TAFv1uw2R2J+tzXSpvK7uGBgo5jHOku9+LQaIN8juWlYGmCPCvHJU8HbIHJqi nzW6vYWk5aBusd4tTTo8zEksO1x4Q6RKKOOaH2QMy5mPsZsR+tPbgGpI1VOZrjsbX/Ev 6o9Q== X-Forwarded-Encrypted: i=1; AJvYcCXh6d7+6A85I89MDXHnKZJ9fN7NGcbFKJtRR4zkyD3WY7XNjDvNal0yfG3IBS8zZ4An5rb/IW7w2xFfRl4=@vger.kernel.org X-Gm-Message-State: AOJu0YzKZYT95YMg/iVea2AbU0Wr+swXZejY5wWqaWAOOetMAhwp+hG/ Z2djLxT+NMacr9nYWnLS80LyKsyRnew0UkdFOG0jz+UiGAY4dwt1fGpD X-Gm-Gg: ASbGncs2L1O62Hhtmmq5lMh8MNW+cloeuti6TbeEJNWzltuoSiRECEF3N7c/We0W4ey pSVSJnZ/SLEtS4oA18QLYF+wZF2zYEnJav5YXnk9X83ssgY9fz3ld5X8c9ERTMFPuHuyk2kUSOJ MQvirlTQN0+nvjyy7+sOO+0sAvC8LFgAPAiRIWSX3EawqpFo6EK/bTUFL0H4V2/AomDirgNkBl7 p4F0ri7kkbNtdCqqcgBnqodaggXziLrF4TgF3Se+IPk/Hd4I16+G7lQgTnfk2pgBQMtcvmpzklS mRYvOJ7BV9Kxo4xefb/As20n0wjG9sEmgSuHeQ5JiZF/hgKbillqA4y1Htgt+5Q6tJ4aqaHaam9 NN8iG2IepJJBf91P92FqyOfYK8wDnJBxoheAABVHyMNvf+CmBRmyS6q+CJOXA63hOKvlEqEEh3/ GJ X-Google-Smtp-Source: AGHT+IEwOBi8H8vI0VnTgYiKNK/rmJrnMUq9+SV+Hm3XBxJGlKzU1nvTZo6tqvELeVVre05Nb9QfRg== X-Received: by 2002:a2e:bc8c:0:b0:337:e5fc:d2d with SMTP id 38308e7fff4ca-374c37eb3f8mr7161301fa.24.1759482684821; Fri, 03 Oct 2025 02:11:24 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-373ba444480sm13498971fa.30.2025.10.03.02.11.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 02:11:24 -0700 (PDT) From: Sergey Bashirov To: Chuck Lever , Christoph Hellwig , Dai Ngo , Jeff Layton , NeilBrown , Olga Kornievskaia , Tom Talpey Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Bashirov , Christoph Hellwig Subject: [PATCH v3 3/4] NFSD/blocklayout: Introduce layout content structure Date: Fri, 3 Oct 2025 12:11:05 +0300 Message-ID: <20251003091115.184075-4-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003091115.184075-1-sergeybashirov@gmail.com> References: <20251003091115.184075-1-sergeybashirov@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a layout content structure instead of a single extent. The ability to store and encode an array of extents is then used to implement support for multiple extents per LAYOUTGET. Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig --- fs/nfsd/blocklayout.c | 26 ++++++++++++++++++++++---- fs/nfsd/blocklayoutxdr.c | 36 +++++++++++++++++++++++++++--------- fs/nfsd/blocklayoutxdr.h | 14 ++++++++++++++ 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 35a95501db63..6d29ea5e8623 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -88,9 +88,10 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struc= t inode *inode, const struct svc_fh *fhp, struct nfsd4_layoutget *args) { struct nfsd4_layout_seg *seg =3D &args->lg_seg; + struct pnfs_block_layout *bl; struct pnfs_block_extent *bex; u64 length; - u32 block_size =3D i_blocksize(inode); + u32 nr_extents_max =3D 1, block_size =3D i_blocksize(inode); __be32 nfserr; =20 if (locks_in_grace(SVC_NET(rqstp))) @@ -102,16 +103,33 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, st= ruct inode *inode, goto out_error; } =20 + /* + * RFC 8881, section 3.3.17: + * The layout4 data type defines a layout for a file. + * + * RFC 8881, section 18.43.3: + * The loga_maxcount field specifies the maximum layout size + * (in bytes) that the client can handle. If the size of the + * layout structure exceeds the size specified by maxcount, + * the metadata server will return the NFS4ERR_TOOSMALL error. + */ + nfserr =3D nfserr_toosmall; + if (args->lg_maxcount < PNFS_BLOCK_LAYOUT4_SIZE + + PNFS_BLOCK_EXTENT_SIZE) + goto out_error; + /* * Some clients barf on non-zero block numbers for NONE or INVALID * layouts, so make sure to zero the whole structure. */ nfserr =3D nfserrno(-ENOMEM); - bex =3D kzalloc(sizeof(*bex), GFP_KERNEL); - if (!bex) + bl =3D kzalloc(struct_size(bl, extents, nr_extents_max), GFP_KERNEL); + if (!bl) goto out_error; - args->lg_content =3D bex; + bl->nr_extents =3D nr_extents_max; + args->lg_content =3D bl; =20 + bex =3D &bl->extents[0]; nfserr =3D nfsd4_block_map_extent(inode, fhp, seg->offset, seg->length, seg->iomode, args->lg_minlength, bex); if (nfserr !=3D nfs_ok) diff --git a/fs/nfsd/blocklayoutxdr.c b/fs/nfsd/blocklayoutxdr.c index e50afe340737..196ef4245604 100644 --- a/fs/nfsd/blocklayoutxdr.c +++ b/fs/nfsd/blocklayoutxdr.c @@ -14,12 +14,25 @@ #define NFSDDBG_FACILITY NFSDDBG_PNFS =20 =20 +/** + * nfsd4_block_encode_layoutget - encode block/scsi layout extent array + * @xdr: stream for data encoding + * @lgp: layoutget content, actually an array of extents to encode + * + * Encode the opaque loc_body field in the layoutget response. Since the + * pnfs_block_layout4 and pnfs_scsi_layout4 structures on the wire are + * the same, this function is used by both layout drivers. + * + * Return values: + * %nfs_ok: Success, all extents encoded into @xdr + * %nfserr_toosmall: Not enough space in @xdr to encode all the data + */ __be32 nfsd4_block_encode_layoutget(struct xdr_stream *xdr, const struct nfsd4_layoutget *lgp) { - const struct pnfs_block_extent *b =3D lgp->lg_content; - int len =3D sizeof(__be32) + 5 * sizeof(__be64) + sizeof(__be32); + const struct pnfs_block_layout *bl =3D lgp->lg_content; + u32 i, len =3D sizeof(__be32) + bl->nr_extents * PNFS_BLOCK_EXTENT_SIZE; __be32 *p; =20 p =3D xdr_reserve_space(xdr, sizeof(__be32) + len); @@ -27,14 +40,19 @@ nfsd4_block_encode_layoutget(struct xdr_stream *xdr, return nfserr_toosmall; =20 *p++ =3D cpu_to_be32(len); - *p++ =3D cpu_to_be32(1); /* we always return a single extent */ + *p++ =3D cpu_to_be32(bl->nr_extents); =20 - p =3D svcxdr_encode_deviceid4(p, &b->vol_id); - p =3D xdr_encode_hyper(p, b->foff); - p =3D xdr_encode_hyper(p, b->len); - p =3D xdr_encode_hyper(p, b->soff); - *p++ =3D cpu_to_be32(b->es); - return 0; + for (i =3D 0; i < bl->nr_extents; i++) { + const struct pnfs_block_extent *bex =3D bl->extents + i; + + p =3D svcxdr_encode_deviceid4(p, &bex->vol_id); + p =3D xdr_encode_hyper(p, bex->foff); + p =3D xdr_encode_hyper(p, bex->len); + p =3D xdr_encode_hyper(p, bex->soff); + *p++ =3D cpu_to_be32(bex->es); + } + + return nfs_ok; } =20 static int diff --git a/fs/nfsd/blocklayoutxdr.h b/fs/nfsd/blocklayoutxdr.h index 7d25ef689671..2e0c6c7d2b42 100644 --- a/fs/nfsd/blocklayoutxdr.h +++ b/fs/nfsd/blocklayoutxdr.h @@ -8,6 +8,15 @@ struct iomap; struct xdr_stream; =20 +/* On the wire size of the layout4 struct with zero number of extents */ +#define PNFS_BLOCK_LAYOUT4_SIZE \ + (sizeof(__be32) * 2 + /* offset4 */ \ + sizeof(__be32) * 2 + /* length4 */ \ + sizeof(__be32) + /* layoutiomode4 */ \ + sizeof(__be32) + /* layouttype4 */ \ + sizeof(__be32) + /* number of bytes */ \ + sizeof(__be32)) /* number of extents */ + struct pnfs_block_extent { struct nfsd4_deviceid vol_id; u64 foff; @@ -21,6 +30,11 @@ struct pnfs_block_range { u64 len; }; =20 +struct pnfs_block_layout { + u32 nr_extents; + struct pnfs_block_extent extents[] __counted_by(nr_extents); +}; + /* * Random upper cap for the uuid length to avoid unbounded allocation. * Not actually limited by the protocol. --=20 2.43.0 From nobody Wed Dec 17 17:39:16 2025 Received: from mail-lj1-f176.google.com (mail-lj1-f176.google.com [209.85.208.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B50B02DCF55 for ; Fri, 3 Oct 2025 09:11:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482690; cv=none; b=mcbcVOdGIbIjtAUpK8ln/qGPjEgipLataaAwNXBvO8VVWFdV/yzoqjMdO0MOPzPL7SelEJDIhl4EZ0gORmyGN28BdBLuDenD8cC1Y4H//6GN53lvcam6UDAlPATZ7PrqeepHTkNG0uVhvxb5f3njbm6bRUsTxtfUoihoGAEwBFU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759482690; c=relaxed/simple; bh=CyDxCOa9a0UVrko0lulNFRdftqZ5S6iGAtvQspBwLPI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VVfrPyKhHZfeNY/BwbSn1pWRmGC89Co4n2SgciMyrzGb6AdaJlZ2B/7Z0biSXvFPGKIWAZoP5CS87yeSr55vFSjHAZ6TGXPRjR9uJ5uMDDLuSHuqbPN+XI/6/Tr6k+A5/UEh9INl0N66Yfa/F42V0QMA+J06gD7kkOvqcldmIvw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ZFdYOeXr; arc=none smtp.client-ip=209.85.208.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZFdYOeXr" Received: by mail-lj1-f176.google.com with SMTP id 38308e7fff4ca-361d175c97fso18576701fa.3 for ; Fri, 03 Oct 2025 02:11:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759482687; x=1760087487; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2MLh0YP6jyjvkv3OLtn1P1Rakr4ufZXEBiz1IixS4zk=; b=ZFdYOeXr92NrVKtMA94H4t76UNUcH0uMU0EuffRK41GUzU8x93v00u6ylE2Brwp3Yu GHJe9iYsP3Xn6MUrlOYMi8joT/xr9KK3maly1fY0H/7P2oqBhNYUolBg5cTsYqC4Qzox H8aYqxTzyJLnBNWnerHdSQSaISIl575j8tYPvBNTNLFghZApG4jVt/e/JclLMtWa5UQa douLQqEiGpkSZoYma4bvS2GjIqZ0MQGrVDKoh78hOMo8ABlyAEoyHnQ7q2yVFnoyqUxn gJnhm73FSkzf3kkcNTAXuMRAzQEAZr9tGD2yfcvCXN4Eyszhf207hTBQCar+vd2XolQd OVWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759482687; x=1760087487; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2MLh0YP6jyjvkv3OLtn1P1Rakr4ufZXEBiz1IixS4zk=; b=iD6grb7zhGwwRSbmW9vcQrwQMU10NN9/md9o9B4cE7TnIx0Xwh1468fkXc4rSE4ASC OUFYOk54yzWJbYRHfif95MavJ2ee2ZqLJvZ1nmyV8sUH0uIFVQ/41PrZafq9ABqNNEt4 acXPowLkay/vxf5y91AVTGz9HtJwlRZxDjAoaOjLhbwmgiaMCRhtaXfhSZaTLhN5JuIC 3Qo9F1g+Lg+dWXXBdYTuS9OD9jKhOYsFolotB2cvl7VgdAgcc3vRJoXXjEM5ilmO4IEW VZpli1S3LLzI2huhBzuA5br+HaSpQu4KOLMqSUkfrXSWcR55ylC35wZo+Fw6oYVTIzvo MRhA== X-Forwarded-Encrypted: i=1; AJvYcCU5n7qKrq7oog0URy9qPWVIc8tAQKVzRGBhuO5HVPLbzdQxUY5eOQ+7PLHsAt7G8C33uCzYpiht45hUMU8=@vger.kernel.org X-Gm-Message-State: AOJu0YwdSg4fuddv43dF63Kxidmmu3c/Gf4cz4TraTfjJgUY/ByPd/gM u/zgozAEh99YSmBXDIs8COXK59fdfZ664VwHfPpbKtMTAdIR1qF/Vm8O X-Gm-Gg: ASbGncuz2x4pQx05TU628BvNIh2NJYNN+qMEehRWtmHtCF5+Iv/5HFsaQZMPFXexFIv SpOHRzkMTuCPC3c9Hk6znbySnTLYr4JuHt48ORnbPgIPGOR1+0onSKX6rxpb7mv1gbmsNHP6sA0 2wavFz2bBuc8EZl+fwyZ5RzSpDABtrZf3jtOjtilNfGAcJigprnxr9ZH0PQ5BVEzu5K77sQgHrc b8L0J4AnZmZuA375Uhdmcq2IKRpovbHVBu+K+yXRWmHNBUIZtX3R/o92bzCMsVZYWuQ66h5Rh1S 0asFXsm7aV8ehk9WyKHfUNnr+N4kt0KIzakrgEZc1u6pXx+bWuQ/yyU3ZlOXHZRZEHvbi2T+Ru+ adDnOXyETLBsC6Vd5FcfjRXNkLAG5VaGHVDy20vwA9D+RsbOmGPYd2nKsq9Thhw47f3q9SjLNcl /UsLbJv7VQXXI= X-Google-Smtp-Source: AGHT+IH626lrMrW4/tqV77SvAxhxkxsSgiUJLrrNrN0WsdcdsYjyni7R/pZ/Q7HnGJRn81ZtrVV7wg== X-Received: by 2002:a2e:a802:0:b0:36a:8c41:643b with SMTP id 38308e7fff4ca-374c386153emr6284711fa.43.1759482686606; Fri, 03 Oct 2025 02:11:26 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-373ba444480sm13498971fa.30.2025.10.03.02.11.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 02:11:26 -0700 (PDT) From: Sergey Bashirov To: Chuck Lever , Christoph Hellwig , Dai Ngo , Jeff Layton , NeilBrown , Olga Kornievskaia , Tom Talpey Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Bashirov , Christoph Hellwig Subject: [PATCH v3 4/4] NFSD/blocklayout: Support multiple extents per LAYOUTGET Date: Fri, 3 Oct 2025 12:11:06 +0300 Message-ID: <20251003091115.184075-5-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251003091115.184075-1-sergeybashirov@gmail.com> References: <20251003091115.184075-1-sergeybashirov@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow the pNFS server to respond with multiple extents to a LAYOUTGET request, thereby avoiding unnecessary load on the server and improving performance for the client. The number of LAYOUTGET requests is significantly reduced for various file access patterns, including random and parallel writes. Additionally, this change allows the client to request layouts with the loga_minlength value greater than the minimum possible length of a single extent in XFS. We use this functionality to fix a livelock in the client. Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig --- fs/nfsd/blocklayout.c | 47 +++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 6d29ea5e8623..101cccbee4a3 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -89,9 +89,9 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct= inode *inode, { struct nfsd4_layout_seg *seg =3D &args->lg_seg; struct pnfs_block_layout *bl; - struct pnfs_block_extent *bex; - u64 length; - u32 nr_extents_max =3D 1, block_size =3D i_blocksize(inode); + struct pnfs_block_extent *first_bex, *last_bex; + u64 offset =3D seg->offset, length =3D seg->length; + u32 i, nr_extents_max, block_size =3D i_blocksize(inode); __be32 nfserr; =20 if (locks_in_grace(SVC_NET(rqstp))) @@ -118,6 +118,13 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, str= uct inode *inode, PNFS_BLOCK_EXTENT_SIZE) goto out_error; =20 + /* + * Limit the maximum layout size to avoid allocating + * a large buffer on the server for each layout request. + */ + nr_extents_max =3D (min(args->lg_maxcount, PAGE_SIZE) - + PNFS_BLOCK_LAYOUT4_SIZE) / PNFS_BLOCK_EXTENT_SIZE; + /* * Some clients barf on non-zero block numbers for NONE or INVALID * layouts, so make sure to zero the whole structure. @@ -129,23 +136,37 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, st= ruct inode *inode, bl->nr_extents =3D nr_extents_max; args->lg_content =3D bl; =20 - bex =3D &bl->extents[0]; - nfserr =3D nfsd4_block_map_extent(inode, fhp, seg->offset, seg->length, - seg->iomode, args->lg_minlength, bex); - if (nfserr !=3D nfs_ok) - goto out_error; + for (i =3D 0; i < bl->nr_extents; i++) { + struct pnfs_block_extent *bex =3D bl->extents + i; + u64 bex_length; + + nfserr =3D nfsd4_block_map_extent(inode, fhp, offset, length, + seg->iomode, args->lg_minlength, bex); + if (nfserr !=3D nfs_ok) + goto out_error; + + bex_length =3D bex->len - (offset - bex->foff); + if (bex_length >=3D length) { + bl->nr_extents =3D i + 1; + break; + } + + offset =3D bex->foff + bex->len; + length -=3D bex_length; + } + + first_bex =3D bl->extents; + last_bex =3D bl->extents + bl->nr_extents - 1; =20 nfserr =3D nfserr_layoutunavailable; - length =3D bex->foff + bex->len - seg->offset; + length =3D last_bex->foff + last_bex->len - seg->offset; if (length < args->lg_minlength) { dprintk("pnfsd: extent smaller than minlength\n"); goto out_error; } =20 - seg->offset =3D bex->foff; - seg->length =3D bex->len; - - dprintk("GET: 0x%llx:0x%llx %d\n", bex->foff, bex->len, bex->es); + seg->offset =3D first_bex->foff; + seg->length =3D last_bex->foff - first_bex->foff + last_bex->len; return nfs_ok; =20 out_error: --=20 2.43.0