Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Apr 2004 19:10:23 -0700 (PDT)
From:      "Dorr H. Clark" <dclark@applmath.scu.edu>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/53475: cp(1) copies files in reverse order to destination
Message-ID:  <200404280210.i3S2ANNO083319@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/53475; it has been noted by GNATS.

From: "Dorr H. Clark" <dclark@applmath.scu.edu>
To: freebsd-gnats-submit@FreeBSD.org, louie@TransSys.COM
Cc:  
Subject: Re: bin/53475: cp(1) copies files in reverse order to destination
Date: Tue, 27 Apr 2004 19:03:14 -0700

 --- cp.c_orig   Sun Apr 25 06:32:27 2004
 +++ cp.c        Sun Apr 25 06:33:50 2004
 @@ -94,7 +94,6 @@
  enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
  
  static int copy(char *[], enum op, int);
 -static int mastercmp(const FTSENT * const *, const FTSENT * const *);
  static void siginfo(int __unused);
  
  int
 @@ -274,7 +273,7 @@
         mask = ~umask(0777);
         umask(~mask);
  
 -       if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL)
 +       if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
                 err(1, "fts_open");
         for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp =
 0) {
                 switch (curr->fts_info) {
 @@ -478,32 +477,6 @@
         if (errno)
                 err(1, "fts_read");
         return (rval);
 -}
 -
 -/*
 - * mastercmp --
 - *     The comparison function for the copy order.  The order is to
 copy
 - *     non-directory files before directory files.  The reason for this
 - *     is because files tend to be in the same cylinder group as their
 - *     parent directory, whereas directories tend not to be.  Copying
 the
 - *     files first reduces seeking.
 - */
 -static int
 -mastercmp(const FTSENT * const *a, const FTSENT * const *b)
 -{
 -       int a_info, b_info;
 -
 -       a_info = (*a)->fts_info;
 -       if (a_info == FTS_ERR || a_info == FTS_NS || a_info == FTS_DNR)
 -               return (0);
 -       b_info = (*b)->fts_info;
 -       if (b_info == FTS_ERR || b_info == FTS_NS || b_info == FTS_DNR)
 -               return (0);
 -       if (a_info == FTS_D)
 -               return (-1);
 -       if (b_info == FTS_D)
 -               return (1);
 -       return (0);
  }
  
  static void
 
 
 As quoted above, the comments in cp.c tell us the function 
 mastercmp() is an attempt to improve performance based on 
 knowing something about physical disks.
  
 This is an old optimization strategy (it's in the original 
 version of cp.c).  AFAIK, in the updated BSD filesystem, 
 when we copy a file, we don't actually move the
 physical data block of the file but change the information in its
 inode such as the address of its data block and owner.  
 
 Deleting mastercmp() and setting the comparison paramter to NULL 
 for the function fts_open() suppresses the behavior 
 in the bug.
 
 The next question is whether deleting mastercmp eliminates
 an optimization.  Our testing shows the exact opposite,
 mastercmp is degrading performance.  We did several experiments
 with cp -R to measure elapsed time on transfers between devices
 of differing file system types (to avoid UFS2 optimizations).
 Our results show removing mastercmp yields a small performance
 gain (note: we had no SCSI devices available, and second note:
 variability in file system performance seems dominated 
 by other factors).
 
 M. K. McKusick has indicated in seminars that modern disk drives
 lie to the driver about their physical layouts.  The use of
 mastercmp in cp.c is a legacy optimization from a different
 era of disk technology.  We recommend removing this call
 from cp.c to address 53475.
 
 Ting Hui, engineer
 Dorr H. Clark, advisor
 Graduate School of Engineering
 Santa Clara University



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