From owner-freebsd-bugs@FreeBSD.ORG Sat Oct 28 20:00:40 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 69BCD16A58C for ; Sat, 28 Oct 2006 20:00:40 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id F132743D55 for ; Sat, 28 Oct 2006 20:00:39 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k9SK0dHZ076905 for ; Sat, 28 Oct 2006 20:00:39 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k9SK0d1q076904; Sat, 28 Oct 2006 20:00:39 GMT (envelope-from gnats) Date: Sat, 28 Oct 2006 20:00:39 GMT Message-Id: <200610282000.k9SK0d1q076904@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Yar Tikhiy Cc: Subject: Re: bin/104458: fts(3) can't handle very deep trees X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Yar Tikhiy List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Oct 2006 20:00:40 -0000 The following reply was made to PR bin/104458; it has been noted by GNATS. From: Yar Tikhiy To: Bruce Evans Cc: Yar Tikhiy Subject: Re: bin/104458: fts(3) can't handle very deep trees Date: Mon, 16 Oct 2006 19:38:08 +0400 Realized that there is a bug in the algo :-) On Mon, Oct 16, 2006 at 07:11:02PM +0400, Yar Tikhiy wrote: > > At least in the rm case, we are limited only by the number of files > we cannot delete IMHO. Assume we can delete everything in a tree: > no restrictive permissions, no immutable flags, etc. Then we can > traverse and remove it with the following algo, which utilizes FS > as the storage of all its state: > > /* > * removes everything in and under current directory > */ > stat(".", &st0); > again: > dp = opendir("."); > while (ep = readdir(dp)) { > /* skip . and .. here */ > stat(ep->d_name, &st); > if (S_ISDIR(st.st_mode)) { > if (rmdir(ep->d_name) == -1) { /* ENOTEMPTY */ > chdir(ep->d_name); > closedir(dp); > goto again; > } > } else > unlink(ep->d_name); > } > /* we arrive here only after we deleted all in . */ closedir(dp); > stat(".", &st); > if (st.st_dev == st0.st_dev && st.st_ino == st0.st_ino) > return; > chdir(".."); > goto again; > > Real life dictates that we should handle failures to delete something. > This can be done by keeping a list (or hash) of unremovable files > identified by st_dev and st_ino of the parent directory and the name > of the file itself. Then we can skip over them in the readdir loop > so that we don't loop forever. But all this means farewell to fts(3). -- Yar