From owner-svn-src-head@FreeBSD.ORG Thu Sep 23 11:18:02 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AE3C8106564A; Thu, 23 Sep 2010 11:18:02 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 937048FC17; Thu, 23 Sep 2010 11:18:02 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o8NBI2PQ067149; Thu, 23 Sep 2010 11:18:02 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o8NBI25C067147; Thu, 23 Sep 2010 11:18:02 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201009231118.o8NBI25C067147@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Thu, 23 Sep 2010 11:18:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r213060 - head/sbin/geom/class/eli X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Sep 2010 11:18:02 -0000 Author: pjd Date: Thu Sep 23 11:18:02 2010 New Revision: 213060 URL: http://svn.freebsd.org/changeset/base/213060 Log: - When trashing metadata, repeat overwrite kern.geom.eli.overwrites times. - Flush write cache after each write. MFC after: 1 week Modified: head/sbin/geom/class/eli/geom_eli.c Modified: head/sbin/geom/class/eli/geom_eli.c ============================================================================== --- head/sbin/geom/class/eli/geom_eli.c Thu Sep 23 11:04:50 2010 (r213059) +++ head/sbin/geom/class/eli/geom_eli.c Thu Sep 23 11:18:02 2010 (r213060) @@ -27,6 +27,9 @@ #include __FBSDID("$FreeBSD$"); +#include +#include + #include #include #include @@ -1015,11 +1018,54 @@ eli_delkey(struct gctl_req *req) eli_delkey_detached(req, prov); } +static int +eli_trash_metadata(struct gctl_req *req, const char *prov, int fd, off_t offset) +{ + unsigned int overwrites; + unsigned char *sector; + ssize_t size; + int error; + + size = sizeof(overwrites); + if (sysctlbyname("kern.geom.eli.overwrites", &overwrites, &size, + NULL, 0) == -1 || overwrites == 0) { + overwrites = G_ELI_OVERWRITES; + } + + size = g_sectorsize(fd); + if (size <= 0) { + gctl_error(req, "Cannot obtain provider sector size %s: %s.", + prov, strerror(errno)); + return (-1); + } + sector = malloc(size); + if (sector == NULL) { + gctl_error(req, "Cannot allocate %zd bytes of memory.", size); + return (-1); + } + + error = 0; + do { + arc4rand(sector, size); + if (pwrite(fd, sector, size, offset) != size) { + if (error == 0) + error = errno; + } + (void)g_flush(fd); + } while (--overwrites > 0); + if (error != 0) { + gctl_error(req, "Cannot trash metadata on provider %s: %s.", + prov, strerror(error)); + return (-1); + } + return (0); +} + static void eli_kill_detached(struct gctl_req *req, const char *prov) { - struct g_eli_metadata md; - int error; + off_t offset; + int fd; /* * NOTE: Maybe we should verify if this is geli provider first, @@ -1036,12 +1082,22 @@ eli_kill_detached(struct gctl_req *req, } #endif - arc4rand((unsigned char *)&md, sizeof(md)); - error = g_metadata_store(prov, (unsigned char *)&md, sizeof(md)); - if (error != 0) { - gctl_error(req, "Cannot write metadata to %s: %s.", prov, - strerror(error)); + fd = g_open(prov, 1); + if (fd == -1) { + gctl_error(req, "Cannot open provider %s: %s.", prov, + strerror(errno)); + return; } + offset = g_mediasize(fd) - g_sectorsize(fd); + if (offset <= 0) { + gctl_error(req, + "Cannot obtain media size or sector size for provider %s: %s.", + prov, strerror(errno)); + (void)g_close(fd); + return; + } + (void)eli_trash_metadata(req, prov, fd, offset); + (void)g_close(fd); } static void @@ -1336,12 +1392,8 @@ eli_resize(struct gctl_req *req) (void)g_flush(provfd); /* Now trash the old metadata. */ - arc4rand(sector, secsize); - if (pwrite(provfd, sector, secsize, oldsize - secsize) != secsize) { - gctl_error(req, "Failed to clobber old metadata: %s.", - strerror(errno)); + if (eli_trash_metadata(req, prov, provfd, oldsize - secsize) == -1) goto out; - } out: if (provfd >= 0) (void)g_close(provfd);