svn commit: r336049 - projects/pnfs-planb-server/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Fri Jul 6 21:01:53 UTC 2018
Author: rmacklem
Date: Fri Jul 6 21:01:52 2018
New Revision: 336049
URL: https://svnweb.freebsd.org/changeset/base/336049
Log:
Fix the kernel part of pnfsdscopymr() to handle holes in the file being copied.
If a mirrored DS is being recovered that has a lot of large sparse files,
pnfsdscopymr(8) would use a lot of space on the recovered mirror since it
would write the "holes" in the file being mirrored.
This patch adds code to check for a "hole" and skip doing the write.
Modified:
projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdkrpc.c
projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c
Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdkrpc.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdkrpc.c Fri Jul 6 19:55:14 2018 (r336048)
+++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdkrpc.c Fri Jul 6 21:01:52 2018 (r336049)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
NFSDLOCKMUTEX;
NFSV4ROOTLOCKMUTEX;
struct nfsv4lock nfsd_suspend_lock;
+char *nfsrv_zeropnfsdat = NULL;
/*
* Mapping of old NFS Version 2 RPC numbers to generic numbers.
@@ -565,6 +566,8 @@ nfsrvd_init(int terminating)
nfsrv_freealllayoutsanddevids();
nfsrv_freeallbackchannel_xprts();
svcpool_close(nfsrvd_pool);
+ free(nfsrv_zeropnfsdat, M_TEMP);
+ nfsrv_zeropnfsdat = NULL;
NFSD_LOCK();
} else {
NFSD_UNLOCK();
Modified: projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Fri Jul 6 19:55:14 2018 (r336048)
+++ projects/pnfs-planb-server/sys/fs/nfsserver/nfs_nfsdstate.c Fri Jul 6 21:01:52 2018 (r336049)
@@ -60,6 +60,7 @@ NFSSTATESPINLOCK;
extern struct nfsdontlisthead nfsrv_dontlisthead;
extern volatile int nfsrv_devidcnt;
extern struct nfslayouthead nfsrv_recalllisthead;
+extern char *nfsrv_zeropnfsdat;
SYSCTL_DECL(_vfs_nfsd);
int nfsrv_statehashsize = NFSSTATEHASHSIZE;
@@ -8124,9 +8125,15 @@ tryagain2:
if (retacl != 0 && retacl != ENOATTR)
NFSD_DEBUG(1, "nfsrv_copymr: vop_getacl=%d\n", retacl);
dat = malloc(PNFSDS_COPYSIZ, M_TEMP, M_WAITOK);
+ /* Malloc a block of 0s used to check for holes. */
+ if (nfsrv_zeropnfsdat == NULL)
+ nfsrv_zeropnfsdat = malloc(PNFSDS_COPYSIZ, M_TEMP,
+ M_WAITOK | M_ZERO);
rdpos = wrpos = 0;
mp = NULL;
ret = vn_start_write(tvp, &mp, V_WAIT | PCATCH);
+ if (ret == 0)
+ ret = VOP_GETATTR(fvp, &va, cred);
aresid = 0;
while (ret == 0 && aresid == 0) {
ret = vn_rdwr(UIO_READ, fvp, dat, PNFSDS_COPYSIZ,
@@ -8135,9 +8142,16 @@ tryagain2:
xfer = PNFSDS_COPYSIZ - aresid;
if (ret == 0 && xfer > 0) {
rdpos += xfer;
- ret = vn_rdwr(UIO_WRITE, tvp, dat, xfer,
- wrpos, UIO_SYSSPACE, IO_NODELOCKED,
- cred, NULL, NULL, p);
+ /*
+ * Skip the write for holes, except for the
+ * last block.
+ */
+ if (xfer < PNFSDS_COPYSIZ || rdpos ==
+ va.va_size || NFSBCMP(dat,
+ nfsrv_zeropnfsdat, PNFSDS_COPYSIZ) != 0)
+ ret = vn_rdwr(UIO_WRITE, tvp, dat, xfer,
+ wrpos, UIO_SYSSPACE, IO_NODELOCKED,
+ cred, NULL, NULL, p);
if (ret == 0)
wrpos += xfer;
}
More information about the svn-src-projects
mailing list