Author: mckusick
Date: Thu May 20 06:05:40 2010
New Revision: 208330
URL: http://svn.freebsd.org/changeset/base/208330

Log:
  Add support to background fsck to delete zero-length directories.

Modified:
  head/sbin/fsck_ffs/pass2.c
  head/sbin/fsck_ffs/pass4.c

Modified: head/sbin/fsck_ffs/pass2.c
==============================================================================
--- head/sbin/fsck_ffs/pass2.c  Thu May 20 05:38:54 2010        (r208329)
+++ head/sbin/fsck_ffs/pass2.c  Thu May 20 06:05:40 2010        (r208330)
@@ -274,6 +274,7 @@ static int
 pass2check(struct inodesc *idesc)
 {
        struct direct *dirp = idesc->id_dirp;
+       char dirname[MAXPATHLEN + 1];
        struct inoinfo *inp;
        int n, entrysize, ret = 0;
        union dinode *dp;
@@ -436,9 +437,37 @@ again:
                                errmsg = "DUP/BAD";
                        else if (!preen && !usedsoftdep)
                                errmsg = "ZERO LENGTH DIRECTORY";
-                       else {
+                       else if (cursnapshot == 0) {
                                n = 1;
                                break;
+                       } else {
+                               getpathname(dirname, idesc->id_number,
+                                   dirp->d_ino);
+                               pwarn("ZERO LENGTH DIRECTORY %s I=%d",
+                                       dirname, dirp->d_ino);
+                               /*
+                                * We need to:
+                                *    setcwd(idesc->id_parent);
+                                *    rmdir(dirp->d_name);
+                                */
+                               cmd.value = idesc->id_number;
+                               if (sysctlbyname("vfs.ffs.setcwd", 0, 0,
+                                   &cmd, sizeof cmd) == -1) {
+                                       /* kernel lacks support */
+                                       printf(" (IGNORED)\n");
+                                       n = 1;
+                                       break;
+                               }
+                               if (rmdir(dirp->d_name) == -1) {
+                                       printf(" (REMOVAL FAILED: %s)\n",
+                                           strerror(errno));
+                                       n = 1;
+                                       break;
+                               }
+                               /* ".." reference to parent is removed */
+                               inoinfo(idesc->id_number)->ino_linkcnt--;
+                               printf(" (REMOVED)\n");
+                               break;
                        }
                        fileerror(idesc->id_number, dirp->d_ino, errmsg);
                        if ((n = reply("REMOVE")) == 1)

Modified: head/sbin/fsck_ffs/pass4.c
==============================================================================
--- head/sbin/fsck_ffs/pass4.c  Thu May 20 05:38:54 2010        (r208329)
+++ head/sbin/fsck_ffs/pass4.c  Thu May 20 06:05:40 2010        (r208330)
@@ -97,6 +97,9 @@ pass4(void)
                                break;
 
                        case DCLEAR:
+                               /* if on snapshot, already cleared */
+                               if (cursnapshot != 0)
+                                       break;
                                dp = ginode(inumber);
                                if (DIP(dp, di_size) == 0) {
                                        clri(&idesc, "ZERO LENGTH", 1);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to