Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Jul 2018 21:01:52 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r336049 - projects/pnfs-planb-server/sys/fs/nfsserver
Message-ID:  <201807062101.w66L1qGn021104@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 			}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807062101.w66L1qGn021104>