diff -Nru dpkg-1.15.5.6ubuntu1/debian/changelog dpkg-1.15.5.6ubuntu2/debian/changelog --- dpkg-1.15.5.6ubuntu1/debian/changelog 2010-02-14 02:40:26.000000000 +0100 +++ dpkg-1.15.5.6ubuntu2/debian/changelog 2010-02-14 12:56:27.000000000 +0100 @@ -1,3 +1,14 @@ +dpkg (1.15.5.6ubuntu2) lucid; urgency=low + + * Add fsync on files and directories to prevent delayed allocation and the + zero-length file problem after a system crash LP: #512096 (Debian #567089) + - dpkg-deb/extract.c: fsync control files + - src/archive.c: fsync newly extracted files + - lib/dpkg/cleanup.c: fsync directory before closing + - lib/dpkg/dump.c: fsync db directory + + -- Jean-Baptiste Lallement Sun, 14 Feb 2010 12:44:38 +0100 + dpkg (1.15.5.6ubuntu1) lucid; urgency=low * Resynchronise with Debian. Remaining changes: diff -Nru dpkg-1.15.5.6ubuntu1/dpkg-deb/extract.c dpkg-1.15.5.6ubuntu2/dpkg-deb/extract.c --- dpkg-1.15.5.6ubuntu1/dpkg-deb/extract.c 2010-02-14 02:40:26.000000000 +0100 +++ dpkg-1.15.5.6ubuntu2/dpkg-deb/extract.c 2010-02-14 12:19:16.000000000 +0100 @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef WITH_ZLIB #include #endif @@ -337,6 +338,30 @@ movecontrolfiles(OLDDEBDIR); } } + + /* fsync extracted files to prevent delayed allocation and the zero-length + * file problem */ + if (taroption && directory) { + DIR *dsd; + struct dirent *de; + int fd; + + dsd= opendir(directory); + if (!dsd) ohshite(_("cannot read directory `%.250s'"),directory); + if (chdir(directory)) + ohshite(_("failed to chdir to `%.255s'"), directory); + + while ((de = readdir(dsd)) != NULL){ + if (strchr(de->d_name,'.')) + continue; + + if ((fd = open( de->d_name, O_RDONLY )) != -1) { + fsync(fd); + close(fd); + } + } + closedir( dsd ); + } } static void controlextractvextract(int admin, diff -Nru dpkg-1.15.5.6ubuntu1/lib/dpkg/cleanup.c dpkg-1.15.5.6ubuntu2/lib/dpkg/cleanup.c --- dpkg-1.15.5.6ubuntu1/lib/dpkg/cleanup.c 2010-02-14 02:40:26.000000000 +0100 +++ dpkg-1.15.5.6ubuntu2/lib/dpkg/cleanup.c 2010-02-14 12:30:21.000000000 +0100 @@ -51,8 +51,10 @@ { DIR *d = (DIR *)(argv[0]); - if (d) + if (d) { + fsync(dirfd(d)); closedir(d); + } } void diff -Nru dpkg-1.15.5.6ubuntu1/lib/dpkg/dump.c dpkg-1.15.5.6ubuntu2/lib/dpkg/dump.c --- dpkg-1.15.5.6ubuntu1/lib/dpkg/dump.c 2010-02-14 02:40:26.000000000 +0100 +++ dpkg-1.15.5.6ubuntu2/lib/dpkg/dump.c 2010-02-14 12:08:08.000000000 +0100 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -362,6 +363,8 @@ FILE *file; struct varbuf vb = VARBUF_INIT; int old_umask; + char *fname, *dname; + DIR *dirp; which= available ? "available" : "status"; oldfn= m_malloc(strlen(filename)+sizeof(OLDDBEXT)); @@ -409,4 +412,17 @@ newfn, filename, which); free(newfn); free(oldfn); + + /* We need to sync the directory */ + fname = strdup( filename ); + dname = strrchr( fname, '/' ); + if ( dname && *dname ) + *dname = '\0'; + + if ( (dirp = opendir(fname))==NULL) + ohshite(_("failed to opendir `%.250s'"), fname ); + if ( fsync(dirfd(dirp)) == -1 ) + ohshite(_("failed to fsync `%.250s'"), fname ); + closedir( dirp ); + free( fname ); } diff -Nru dpkg-1.15.5.6ubuntu1/src/archives.c dpkg-1.15.5.6ubuntu2/src/archives.c --- dpkg-1.15.5.6ubuntu1/src/archives.c 2010-02-14 02:40:27.000000000 +0100 +++ dpkg-1.15.5.6ubuntu2/src/archives.c 2010-02-14 12:14:20.000000000 +0100 @@ -655,6 +655,8 @@ if (fchmod(fd,am)) ohshite(_("error setting permissions of `%.255s'"),ti->Name); pop_cleanup(ehflag_normaltidy); /* fd= open(fnamenewvb.buf) */ + if (fsync(fd)) + ohshite(_("unable to fsync new file `%.250s'"), fnamenewvb.buf ); if (close(fd)) ohshite(_("error closing/writing `%.255s'"),ti->Name); newtarobject_utime(fnamenewvb.buf,ti);