pNFS: Handle RPC size limit for layoutcommits

[ Upstream commit d897d81671 ]

When there are too many block extents for a layoutcommit, they may not
all fit into the maximum-sized RPC. This patch allows the generic pnfs
code to properly handle -ENOSPC returned by the block/scsi layout driver
and trigger additional layoutcommits if necessary.

Co-developed-by: Konstantin Evtushenko <koevtushenko@yandex.com>
Signed-off-by: Konstantin Evtushenko <koevtushenko@yandex.com>
Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20250630183537.196479-5-sergeybashirov@gmail.com
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Sergey Bashirov 2025-06-30 21:35:29 +03:00 committed by Greg Kroah-Hartman
parent 1ba621a636
commit f47b0662bd

View File

@ -3216,6 +3216,7 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
loff_t end_pos; loff_t end_pos;
int status; int status;
bool mark_as_dirty = false;
if (!pnfs_layoutcommit_outstanding(inode)) if (!pnfs_layoutcommit_outstanding(inode))
return 0; return 0;
@ -3267,19 +3268,23 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
if (ld->prepare_layoutcommit) { if (ld->prepare_layoutcommit) {
status = ld->prepare_layoutcommit(&data->args); status = ld->prepare_layoutcommit(&data->args);
if (status) { if (status) {
put_cred(data->cred); if (status != -ENOSPC)
put_cred(data->cred);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags); set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags);
if (end_pos > nfsi->layout->plh_lwb) if (end_pos > nfsi->layout->plh_lwb)
nfsi->layout->plh_lwb = end_pos; nfsi->layout->plh_lwb = end_pos;
goto out_unlock; if (status != -ENOSPC)
goto out_unlock;
spin_unlock(&inode->i_lock);
mark_as_dirty = true;
} }
} }
status = nfs4_proc_layoutcommit(data, sync); status = nfs4_proc_layoutcommit(data, sync);
out: out:
if (status) if (status || mark_as_dirty)
mark_inode_dirty_sync(inode); mark_inode_dirty_sync(inode);
dprintk("<-- %s status %d\n", __func__, status); dprintk("<-- %s status %d\n", __func__, status);
return status; return status;