From nobody Sat Feb 7 23:23:25 2026 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 46725253F03 for ; Thu, 2 Oct 2025 20:31:31 +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=1759437093; cv=none; b=WL5QvNipZiLy3IaHHiWOZs2oDCYMKRQD8DqyAwp2pBtfoUbTT7ps6LCzc3BpSUOgL448I4RBIxTblkG6v8VKc1qg1d4MSbFO9oqre4JwCyA0XHLcylFQrLcXwEpR67Na+yDSxMYRel3JmPhBR7vZ+RSVEKdteGi/Lc8lePRL9bA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759437093; c=relaxed/simple; bh=FAGQoyCRso2DpNbErMRrpyTp/YXHTvsHFqKt1MWxd0o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dV7+eE19752yrFo/ZCurAaelqZ60D9LsEZyUsdDT8Kqg6ffhVgkrqJHlvwWYnQ4MkMtdhVLuee80xEvgl6EQhF2lLoDJuOraDXvGXWObNdi/9Hi1j3TPNin2b9tE3J0XmCqHUcfpF8Tt3vDjur0huTDTyFI6W8FhG7uJlQMHUW0= 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=HfaWl1J/; 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="HfaWl1J/" Received: by mail-lf1-f42.google.com with SMTP id 2adb3069b0e04-5797c8612b4so1870182e87.2 for ; Thu, 02 Oct 2025 13:31:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759437089; x=1760041889; 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=q+Kz42OrzHLhFdDtoqoAsqRj8EeTAJG1g9F7w1OSmto=; b=HfaWl1J/3LHl3n21iBkO39j821AbCpxIAyIAcxgA3dW49C0+VJgRPXEP36NNrm3Fu7 hCkGJJ6QI3GzNFgL2rcb1c3YQS9FC98QDiOZos19D4LJd3WeAFdj/uyQJa2CEXMOC0ot sV2SEU5YTxZhAHWmvku8K2R+aKdbKxZKvtvaoncDbxjuJShDYP1QpynL4jOkOpAGklG2 ak0V3E4WTYgOmqDFbiau1wmY8JXkoFfgEa7vKFBglhKRj5Z20WNHdqarbuWgqgNgZI5i lihPZus5R4/NmYS/a1Awz4QgFiD35ZUdMXeSRSXWVBz+RDiA3xrfTMLLj/S2m0Ra4/Fa VQcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759437089; x=1760041889; 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=q+Kz42OrzHLhFdDtoqoAsqRj8EeTAJG1g9F7w1OSmto=; b=fEpDgFivd7fYikytfwfldF2ZG67LhVXVYbMOpBMzUchq+1OFr2Ozs9LaOdC5mlS7VG dWeDjwpRuIsWGb9072VQ+c7ENKL+pNTzIVuGcblfQx8ljvPGEe5sl18BsbKvOQx53+B3 87w3pVcn9UE4TpvkQy26Wte+LyeKT/+1tGxq3t3685mhn631w+9ZtiLlbcfpB7JkjWA3 5EJgpmZ0ZtwiIEmcO5jKGAcATshp+s9gKb89VceIFNe/5es6BODTOVRWIeJ2bia8ikqq 9uSJbuA313kDIzfVNmaL9pf5yn94i/+7yoZ+pDuCIj8eQ1tQp1qhTYNlLY9FLQwB3FSM YxKg== X-Forwarded-Encrypted: i=1; AJvYcCXvVeyouxWl6twM84ccyDkVxIsaXL3fzzK4CSDvDX2sI8OsjtLjYb4nFbRsqbwcVfI7xGiJiliRcMQscEg=@vger.kernel.org X-Gm-Message-State: AOJu0YxSaBU2USZeaHcWvu+DfG/po0wFNPyfovYRBgAmUvu1v2eWSXLg t+kvYpjxipOtJZeOJbAv5ZdFLdgvSZSRx2YxQg162VC7hSFD+oEPoS7g X-Gm-Gg: ASbGncsMTztB5dpLfNpocfTGV1NRSfsnJ26zTiL8xMVO1L0n948g8KlxmwHzAHVqDmh B7lrt7fd7cSUjzu0nH80oUqDew1lDjnavL4wzr4lzt1HnfqWCERxlWmimP4Td7UMNsNyrOsAxqj PbrrMbJmStpAtah4x8Vo21PrEfMe3UeFrJ3fKhNQ0Afyc01JwK0eojbqWNLFfXV0qgjhyfQtFV9 neBPmXLAiYD35PNhp+3p3xmOtT+6JJwVTaWD0hLKIdJagfx3iv0C2g8GbL2YC3WubyJZQIRL2qf pmJ5jUngebJb9Cm3nCxZnzJ2GoQbUPmjgs9GIEiAJaGXyJwPLL4qc9+UcZBhhYlahrL/zzGWOlr 8QN8Tm53MsBmlKyLUIjR3ro6W87JT8rOMxslA1OgOIgJvVJLINAVXVIXdClWUKbXpqwcKDTO0M0 3C X-Google-Smtp-Source: AGHT+IFsWi8xckIBDYjvJqMEjC+9e2bI4bSFpyTa6nMpxw3Xh7pt1ip35GMgbuqSHivjUBFyez5+Dw== X-Received: by 2002:a05:6512:2391:b0:577:3ccf:cdee with SMTP id 2adb3069b0e04-58cbc2a512cmr147438e87.41.1759437089052; Thu, 02 Oct 2025 13:31:29 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-58b0113f3ddsm1127316e87.52.2025.10.02.13.31.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 13:31:28 -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 Subject: [PATCH v2 1/4] NFSD/blocklayout: Fix minlength check in proc_layoutget Date: Thu, 2 Oct 2025 23:31:11 +0300 Message-ID: <20251002203121.182395-2-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002203121.182395-1-sergeybashirov@gmail.com> References: <20251002203121.182395-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" Minor fix as part of the functional changes. 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. 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 Sat Feb 7 23:23:25 2026 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 F0E3B288CA6 for ; Thu, 2 Oct 2025 20:31:33 +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=1759437095; cv=none; b=mKVBTz6LRE+o1wjV9IFr/UW9RNdO6kkwrvtoZeGLESs4oF5r9ZmKh9Zq7u76ugUzOeeyCEHNDDf+u+yPxNA+BBmjVAP19rEQod4Db0tWgRzfulBA/Po5gVI5VLmYVnImh7biH6VsuUhRIQO/zbTngttkuObg2T6SLMaXKw23HZk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759437095; c=relaxed/simple; bh=oFqfX8Z2mJdTJQsFSTDiVyLiBlBkNY9lzw2zoVWVqgs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RQh00IsRpJ0bubWiVLabZDInSW+E8ic2P4V4WSlRGKUZVkmDIT2O+wuxVLUosAi9lrVD/7u5yNOe/EdiD6qf8XO5wk+B/kRTElXOnFL5w0GLOS9H6X01TdCL6w9+34NL9PWRjo5MN4sI/1MoTI4cWK3fFB71Yse4v4H0uVc7Tp8= 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=niKD+msE; 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="niKD+msE" Received: by mail-lf1-f42.google.com with SMTP id 2adb3069b0e04-57f1b88354eso1387312e87.1 for ; Thu, 02 Oct 2025 13:31:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759437092; x=1760041892; 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=vnaoVcrd4pwmhUrJPtwORPmWfBFGgKSYQKAf2waxl6w=; b=niKD+msEFgjCBdznqEM0W5KpORqIMjRPZWdSvQyWtjyix5xg2oQyb+ZQO5GTon9e76 5MAQna0YedZiKfPxPmkMco1JLb/6xWRrMultkECQKJiuTpp2q0xnvzyhgM0ynAWyBvcF 4NodqLTBn1157ZesKABN/FTAVV9Y+f8MZEcmrtRfiZS4tT4HqLJNgqUPi7dU7KMQJxxh pmlfNn5MdroGnzmJtGZMWnAcJxAdekCtVBeSBfS0AWhzqz+4hO+2BKLoaUt1HEzDWcBu MhdLU1+IQKCAESSu/evhGzFlhvsUyM9Oqh4uivsS50h6bywpoqEskj7DppR006VI9rl6 aKLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759437092; x=1760041892; 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=vnaoVcrd4pwmhUrJPtwORPmWfBFGgKSYQKAf2waxl6w=; b=JUNotp2/iaIgKJngj++CxbyXDqAktgeubfhzkWMgxPVlRAkYTZbUHuthV0dzMdWmcv I/XYKDlX8/n+EciWMpKZ7CbtIF2KFHwAJKWAY/eNChUZSk75DMKWCbmBQ7i1ZP12CdJz ywjmqHbqgrZ37kloIWFxkHxVJeH3DWqGrCr5BgIwrzRo+TFkUUzy0gQrXdrEmSEu3UiL sCUdZ1CcNmgIUoF4c0gdNMRieUypax0LnvHgwk7v5AbGRQVrwOgSEvgwicIHKPN9Pr4L TpTvXPKP8o6J0ZrpGucLkMFLsz/NUQ2i4U/5kRnNX35j6s8xO/HJv857199ArQMlKd8f 0zbA== X-Forwarded-Encrypted: i=1; AJvYcCVL7tPeGhJUgg0dmy12TGVomQ7V6E0vt5+GIFkdR/RHgAj8Q4j4gl2N4bCvZjJ6eew+VwzVMJmBCPiC1bc=@vger.kernel.org X-Gm-Message-State: AOJu0YzfsKkzmcnmuLwngXv6PdyzBjTVtpVs/afEGsAPwrbeOlf53Sdc iXljwKQ2ILXhiyl4xQiB5u21IxjxbUXk3yxXS+JuBk75PX4q+i70WQXB X-Gm-Gg: ASbGncvukFv6/ih7Ki7pFiAK2wQyldESB139yjXdgADnOHHdfsqaJpOFTPUJV+3/ix5 ho/Ad4kUTbpFRMpuN/pnCYfATUQUwxmwD4yPMftr03ZAWi1lhljK2I6/IwTJOz3innzg00xsSO5 XfckeHNBaHCv3cxDWcoUwJHBGAl2h/duhm5SS6OwVI2rz0xaIDspL4gTohSzqg1OVa3fvnl2L26 /GTWkatjM9RBJjAqKBe7R9pEAnZ15OWpRnm4zxoxnfo/2Hm2IkiDPy6nwCiSxaUvnEm+vBg3YXz WeB4dnVgYo9I8MXmMff7NSvHfJRUX3DpxwRJxeKK6Dn2YWIewauyYtUnbZyt69EXJal3LaXtAQc AdbrIe3yPn/t2//KDoteaURWRJ+vZkO/UU2bfjT2FhFZm2r3gLKtKrtld/8ld17C2Beb7/howhI 39 X-Google-Smtp-Source: AGHT+IEcgVk9tVcLruf5PYqQZRtZFzdaqWGCohValC9Aw6pmRxH0sM9m8K8y2YfTPEivEuP7ViNpPA== X-Received: by 2002:a05:6512:3d0f:b0:57c:90fc:7d3 with SMTP id 2adb3069b0e04-58cbc7764f4mr132824e87.53.1759437091706; Thu, 02 Oct 2025 13:31:31 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-58b0113f3ddsm1127316e87.52.2025.10.02.13.31.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 13:31:31 -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 Subject: [PATCH v2 2/4] NFSD/blocklayout: Extract extent mapping from proc_layoutget Date: Thu, 2 Oct 2025 23:31:12 +0300 Message-ID: <20251002203121.182395-3-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002203121.182395-1-sergeybashirov@gmail.com> References: <20251002203121.182395-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 Sat Feb 7 23:23:25 2026 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 09AC5296BC8 for ; Thu, 2 Oct 2025 20:31:35 +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=1759437097; cv=none; b=SYDZMdyeS/an/jgkGWnH+8u6FvaQyDjolbEs3m76CBkoPfRRShNVIENGO5jEZ5E8FW3CLtjy3J4LZULBwvquL8cS2HsakoJyrsDbxxvJPNC5opjPcR0PMQLKJ0luzJU0vUJeU6/Quwaab7EtsKDegFhYS4vIZ7+FibXJmrZ4cNk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759437097; c=relaxed/simple; bh=I6rdzfWZcPvJgyeOvLi+c+eLBQbKBQcDt5Nq6d7BpO8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kfZtsj8G/MDgqyFw1itmIM9bPS/HdIYc03OeAHoEy5jeMRIsTDJkv+iAbzhDvjXuOYCQKVdW3tpoRXqg3vVB6nH3VioOxRcIjaA7buhkafRsX9eutSOM7DHqdk6+S26JgZaLxhiYEKOF1v1IEMX3iQn2nwv9GqlGIE9QjCRyftI= 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=ksl+zng1; 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="ksl+zng1" Received: by mail-lf1-f44.google.com with SMTP id 2adb3069b0e04-57b8fc6097fso1983631e87.1 for ; Thu, 02 Oct 2025 13:31:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759437094; x=1760041894; 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=URqcz1PqBiajUpbWyyVEtzMSrXQenRBULzsl914p9Po=; b=ksl+zng1u11CfgZoTQqtSDgDfh/TYHHl5AEaVeayb5Me6Lf985cacFKHfcfHf6fn0E W/nM58KgR6t0SqBbPNQAl+tFBpQJla0yB9A7FomQSY+w2hLTzIviiN+8fGW0Zni0E4jj /WJcJiZtsfL6cqjWUR70ckco7bsc4OAj2QVYAt/8ix+dROslb4CFC+dgdEWdiEDNRQF0 5H0cuWcziVv070KWTcGSP9dWi7GACriPdvft7NmLYaLPpP28hDGsXC5fVFZwWVY16b7Y SftGDf33haxBNuO3N1YAiPRsZsC8nm559VyBO6wHrlUHsMJJToBne5V4W+mQfVg+aFPo C+xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759437094; x=1760041894; 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=URqcz1PqBiajUpbWyyVEtzMSrXQenRBULzsl914p9Po=; b=MiLv1zWgGcXlWFGHzqsTZsILXMEBOlKlvpdzZSN2DF0RowDxqU5PsjpoTz1MwQ03Lk J1bLa0c5Zx71NEnEDMOLrNhkyfq7RqAfaLGAvweA9hR/63WjZo7AcSiv6WPvGZ1cYB02 xm47+8JfMzoD76lo/ChiIVl66Si/nsvvf3hgAca5goMoKC9FA2GUTeVxtOcQRl46DwxE kauzJaSYrvwG/xT6lYK0G9icuyaZ1AkZkXqv8d7ssx2mvKu0CQg6S0LNu8N/5cpBvgAM bXNBxE3BKimKm1qJByxLNNXtZLbPxkRpWWh3BXqugf2K5P8bMKX+nCds7DNx7fJroVmy qqig== X-Forwarded-Encrypted: i=1; AJvYcCWIFLAFAdyH6DPqYys0VU3Pk7mc/J75eH/hd16lCFp6kiULSKiOenAhw8f0luqbfgqUszEuNe/beipUb8c=@vger.kernel.org X-Gm-Message-State: AOJu0YyMxAidBMYC4TTSRQBiPpGh28w8ve19wYeHVVtT6ZDkkoRJJE9y ro8D4Q55MgaY6EItl2T2ZvYbtLc90gOOozGs1URBDYM5UhwdfVMkqQIA X-Gm-Gg: ASbGnct2EJC+bYvK090zQ7SqAX930lf170g4p4LKlnAiyWvyOcoFSPLKmnLEFVCzh5W ykWTfJR1DI4pTWhnGCOdvULpPpKjqhcUUPy0xL8EIlT8Wk58ZMnZto7zlT9/IybLBck2IZIiIQ3 uvlNVVinioM6RpNqqslTMGK7y1G2z1D1ctW8mne3J47NLbP59LcGUjNBltrbNoxU4/x8cVGEGT3 u1rBM1zDbyGmhc239SvrIV8LIXp3XXSYpT9jcsykXkQEdXahQENrQgNhIyXq3Se83GoBpd3WRoo vjMw/ej8rkjPJ3YsFOodnHpteGJT2ICWtyMJp5dYmAUJvqgeR1b3bnOHYE56DrbihOlJrvGIHcM cnMjZvZpGu5aJA9K2eqaqI3IZxqRVEKTyJxCq0nTLPYJo9wqYaNXXCYR2BIA0bZrdKiwAcas3dJ WK X-Google-Smtp-Source: AGHT+IHWKAwAUfJW+XD+5V5RcRh9IVpwmdya52Ikx8ywWGkiirBkd8RMVHMZ7lX5+YUZDXR0SH0zSQ== X-Received: by 2002:a05:6512:1322:b0:57d:77a1:715d with SMTP id 2adb3069b0e04-58cbb4417d0mr145968e87.32.1759437094010; Thu, 02 Oct 2025 13:31:34 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-58b0113f3ddsm1127316e87.52.2025.10.02.13.31.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 13:31:33 -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 Subject: [PATCH v2 3/4] NFSD/blocklayout: Introduce layout content structure Date: Thu, 2 Oct 2025 23:31:13 +0300 Message-ID: <20251002203121.182395-4-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002203121.182395-1-sergeybashirov@gmail.com> References: <20251002203121.182395-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 Sat Feb 7 23:23:25 2026 Received: from mail-lf1-f45.google.com (mail-lf1-f45.google.com [209.85.167.45]) (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 6EA8629BDB5 for ; Thu, 2 Oct 2025 20:31:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759437100; cv=none; b=sJ2bF4DUe/RBJtAHG+WS1+jNo0FkijNzOMFuRA1mTD5y1UITzu4+sM+KhLn6nQbzMkDZe2+CvKZ3cOOU5Jw8EixGsH5bNgZ0hxeBoE984WSDsu3HTVRf8eiQDugmpeZSTU64qxKcWyvMJs05zuf8i18nPeZFQ6KtdP4NC6Nsmjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759437100; c=relaxed/simple; bh=Xz/6eqYYcI2AeHdk/uSMvcnM84/4fheOZAIWCeZxUfI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lOykAmtd/nlEYCVG2qdVeQ0Yi9q6Jh0n3hDLNdJ/AbcQFPbwZ089mgGBl57hkDNYVLSvpwQbd3WnG05VekWK06HhTPQCqlC9Ch0WOlqEzMrCJuYXYGAWec9aLQ2d/p2LKfFRNSEzYIJk3Bn21pdEK4LKvuaRvUrVYB0IXqsBUn0= 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=hfhsP7Vz; arc=none smtp.client-ip=209.85.167.45 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="hfhsP7Vz" Received: by mail-lf1-f45.google.com with SMTP id 2adb3069b0e04-57e36125e8aso1426829e87.2 for ; Thu, 02 Oct 2025 13:31:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759437097; x=1760041897; 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=W6mwD1k8tJtPn/oG49qeOmgMB45GcYhaofTWn8l5t9A=; b=hfhsP7VzIrcad/G4SP2x+lSEDvZr4ZGvgbDyfQoJsmNCygESjPFW8vS/haOVuc+UGK iNv6IDj9f9ZlawTFwsIkgR487iOs/0iOp3MLrd2nWagFsJWqUsCZrv2huOVvF27Rb6B6 kEEpqkJf3KH5yQbNaC1/u2Ref/eIpls38Frdr8VxlAKc21P7i3j3lVltFxstyFWYanB7 r6bDVyKctgXJ0gf7dtwxKWGYNY31VB8+CwwHH/YMxqQfdhgRRIUOEA7n1EHt4VRDUc+9 FTK2qSs9SWSfXbePVwlX+QN5QYChMvqKdV8NXMGhBMmsg0cK0HExYyowVras8jO+TbbU Dsyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759437097; x=1760041897; 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=W6mwD1k8tJtPn/oG49qeOmgMB45GcYhaofTWn8l5t9A=; b=r7J4EBpYv9gKDKlAClOF9lGE5SSRtcFCLZ+/wb0Y4S4ESqZ2QPz5W7RT/FcvRToy3X VMNk1FO592wWOdZUw3aQosW6EdiYEIMk3U2HgLcKKthYn3G4IXfE8TWtkgdEofXZ1K3H fGDjoJc24tQ0/wJ6o/6ickihruioeH/PueUvFX0zfsaQY2oqScF0Q/qJGtaBuTMn4PJ9 2LhSGohX9CAQxZTAbRyMt+C3utc4CEypIelLQPbbCjYVZwQd02zWuXPkBavF1NRHgAYJ bTnyQxuz26KEXFBeZTqwZ7zcnUEoRXw32Z0CmMmibBj/rsjtnqrL9kx8ze6TzQdj9Xo6 jVZg== X-Forwarded-Encrypted: i=1; AJvYcCVxG1rETx3nQUw6jQAc96B0sVe29MTI1uSjFWF4s0SA0PDV1mw5e/O2p00t7crM48q+JTMr21gebQCFJ4s=@vger.kernel.org X-Gm-Message-State: AOJu0YwHwllVqBfnyVjEKW1LvVmHUamGgl1dmI4SufLeim6tAEtobSqI QxOXfvVtjAeZxCeexdn7xrumh4fah1ahesoWtGZZhn453CMHSyr1JoXv X-Gm-Gg: ASbGncsnGOt/lOU14rwE27HpxMgAQyg7hJcGDEKTxIBgxGdKL4gx91UcsOcWdgqsLQo dO3aDDJ9xmOiYLFMxBdsZEssiw3ve2ybPNaiE13k08CIqlfog+HY8xJwCRpRrrQF4YMT2ottKeJ NJ/TOEy76Vroq4/ry1qMDUYhIGOA5BrdoKTiTTxgQKk+gZWi4zM/FZlXYmThdjRkObVkuOaHIuj quThOmokH2JLGlZZNJnNfUba/t3vwTsbihBIJzi8SWnlXpmDp1mEicDxXlbBLFjR0XJO0qndMsv LLKmYbC/wmXqLl+pwt1Dr1z1UX26MC5kAtmIdeWdFbSuGFVHxVW9XzsbjNE8UihcRUBOwMIPkFd Rc+E/OXMIyZctJqrkCGXlgIEbcFzOrStAKA/fVkL3MTBT/zNuSzm6KyYy9Y8j7RkoBJ9DCHdqcu hIkVt6IIEe50o= X-Google-Smtp-Source: AGHT+IENhMFofFuRpfmNhDfNDvAuH5eKkEts3QazVzdgUeI7rcIWdGPMuHSPpz9M6PfoWCIBMKvLsw== X-Received: by 2002:a05:6512:2396:b0:55f:6f5b:8e65 with SMTP id 2adb3069b0e04-58cbb4416c2mr109330e87.30.1759437096449; Thu, 02 Oct 2025 13:31:36 -0700 (PDT) Received: from SC-WS-02452.corp.sbercloud.ru ([46.159.163.120]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-58b0113f3ddsm1127316e87.52.2025.10.02.13.31.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 13:31:35 -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 Subject: [PATCH v2 4/4] NFSD/blocklayout: Support multiple extents per LAYOUTGET Date: Thu, 2 Oct 2025 23:31:14 +0300 Message-ID: <20251002203121.182395-5-sergeybashirov@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002203121.182395-1-sergeybashirov@gmail.com> References: <20251002203121.182395-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