Merge lp:~psusi/ubuntu/precise/ureadahead/faster into lp:ubuntu/precise/ureadahead

Proposed by Phillip Susi
Status: Work in progress
Proposed branch: lp:~psusi/ubuntu/precise/ureadahead/faster
Merge into: lp:ubuntu/precise/ureadahead
Diff against target: 222 lines (+61/-31)
5 files modified
debian/changelog (+10/-0)
debian/ureadahead.postinst (+1/-4)
src/pack.c (+31/-22)
src/pack.h (+1/-0)
src/trace.c (+18/-5)
To merge this branch: bzr merge lp:~psusi/ubuntu/precise/ureadahead/faster
Reviewer Review Type Date Requested Status
Luke Yelavich (community) Needs Fixing
James Hunt Pending
Ubuntu branches Pending
Review via email: mp+84556@code.launchpad.net

Description of the change

These are some changes I developed a year ago to make ureadahead even faster. I forgot to propose merging them in oneiric, so I've rebased them for precise.

To post a comment you must log in.
Revision history for this message
Luke Yelavich (themuso) wrote :

This FTBF in precise. As per IRC, this will be looked into.

review: Needs Fixing
Revision history for this message
Evan Broder (broder) wrote :

Changing the status of this to "Work in progress" to remove it from the sponsor queue, as it still FTBFS. Please feel free to change the status back to "Needs review" when it's ready to be reviewed.

Unmerged revisions

29. By Phillip Susi

Force reprofile on upgrade

28. By Phillip Susi

* Read all directories optimally
* trace_add_path(): accept directories
* Readahead on the raw block device
* Made preload_inode_group() smarter

27. By Phillip Susi

Read all directories optimally

When tracing, add each directory in the path to a file when
adding it to the pack. When booting, read the directories
via the block device, and normal files the old way, in two
phases. This is required because ext3/4 cache directories
via the block device mapping and normal files via file
mappings. Reading the directories into the cache speeds up
the open() calls to the normal files. To facillitate this,
the st_mode has been added to the file entry in the pack
file so ureadahead can see if the file is a regular file
or a directory.

26. By Phillip Susi

trace_add_path(): accept directories

Rather than bail out and ignore a directory, it now
directly adds the extents for the entire directory
to the pack file.

25. By Phillip Susi

Readahead on the raw block device

As long as we managed to open the raw block device and preload
the inode tables, don't bother open()ing the files and instead
call readahead() on the raw block device with the physical
offsets instead. This makes sure we don't block in the open()
calls.

24. By Phillip Susi

Made preload_inode_group() smarter

Before it called on e2fslibs to get the next inode until it returned
one not in the specified group. This caused sync reads of the inodes
and could read inode tables that we don't need. Now it looks up the
locations of the inode table, inode bitmap, and block bitmap and calls
readahead() on the block device for those locations to queue their
reads in the background.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2011-03-16 17:19:01 +0000
+++ debian/changelog 2011-12-06 03:33:24 +0000
@@ -1,3 +1,13 @@
1ureadahead (0.100.0-12) precise; urgency=low
2
3 * Read all directories optimally
4 * trace_add_path(): accept directories
5 * Readahead on the raw block device
6 * Made preload_inode_group() smarter
7 * Force reprofile on upgrade
8
9 -- Phillip Susi <psusi@cfl.rr.com> Thu, 23 Dec 2010 19:48:59 -0500
10
1ureadahead (0.100.0-11) natty; urgency=low11ureadahead (0.100.0-11) natty; urgency=low
212
3 * src/trace.c: leave room for string termination on reads (LP: #485194).13 * src/trace.c: leave room for string termination on reads (LP: #485194).
414
=== modified file 'debian/ureadahead.postinst'
--- debian/ureadahead.postinst 2009-11-09 18:38:51 +0000
+++ debian/ureadahead.postinst 2011-12-06 03:33:24 +0000
@@ -20,10 +20,7 @@
2020
2121
22case "$1" in22case "$1" in
23 configure)23 configure|triggered)
24 ;;
25
26 triggered)
27 # Force a reprofile24 # Force a reprofile
28 if [ -f /var/lib/ureadahead/pack ]; then25 if [ -f /var/lib/ureadahead/pack ]; then
29 echo "ureadahead will be reprofiled on next reboot"26 echo "ureadahead will be reprofiled on next reboot"
3027
=== modified file 'src/pack.c'
--- src/pack.c 2010-06-25 12:00:39 +0000
+++ src/pack.c 2011-12-06 03:33:24 +0000
@@ -88,7 +88,7 @@
88/* Prototypes for static functions */88/* Prototypes for static functions */
89static void print_time (const char *message, struct timespec *start);89static void print_time (const char *message, struct timespec *start);
90static int do_readahead_hdd (PackFile *file, int daemonise);90static int do_readahead_hdd (PackFile *file, int daemonise);
91static void preload_inode_group (ext2_filsys fs, int group);91static void preload_inode_group (ext2_filsys fs, int fd, int group);
92static int do_readahead_ssd (PackFile *file, int daemonise);92static int do_readahead_ssd (PackFile *file, int daemonise);
93static void *ra_thread (void *ptr);93static void *ra_thread (void *ptr);
9494
@@ -689,6 +689,7 @@
689 const char * devname;689 const char * devname;
690 ext2_filsys fs = NULL;690 ext2_filsys fs = NULL;
691 nih_local int * fds = NULL;691 nih_local int * fds = NULL;
692 int blockdev;
692693
693 nih_assert (file != NULL);694 nih_assert (file != NULL);
694695
@@ -713,26 +714,33 @@
713 */714 */
714 devname = blkid_devno_to_devname (file->dev);715 devname = blkid_devno_to_devname (file->dev);
715 if (devname716 if (devname
716 && (! ext2fs_open (devname, 0, 0, 0, unix_io_manager, &fs))) {717 && (! ext2fs_open (devname, 0, 0, 0, unix_io_manager, &fs))
718 && ((blockdev = open (devname, O_RDONLY )) > 0)) {
717 nih_assert (fs != NULL);719 nih_assert (fs != NULL);
718720
719 for (size_t i = 0; i < file->num_groups; i++)721 for (size_t i = 0; i < file->num_groups; i++)
720 preload_inode_group (fs, file->groups[i]);722 preload_inode_group (fs, blockdev, file->groups[i]);
721723
722 ext2fs_close (fs);724 ext2fs_close (fs);
723 }725 }
724726
725 print_time ("Preload ext2fs inodes", &start);727 print_time ("Preload ext2fs inodes", &start);
726728 if (blockdev > 0)
729 for (size_t i = 0; i < file->num_blocks; i++)
730 if (S_ISDIR(file->paths[file->blocks[i].pathidx].st_mode))
731 readahead (blockdev,
732 file->blocks[i].physical,
733 file->blocks[i].length);
727 /* Open all of the files */734 /* Open all of the files */
728 fds = NIH_MUST (nih_alloc (NULL, sizeof (int) * file->num_paths));735 fds = NIH_MUST (nih_alloc (NULL, sizeof (int) * file->num_paths));
729 for (size_t i = 0; i < file->num_paths; i++) {736 for (size_t i = 0; i < file->num_paths; i++) {
737 if (S_ISDIR(file->paths[i].st_mode))
738 continue;
730 fds[i] = open (file->paths[i].path, O_RDONLY | O_NOATIME);739 fds[i] = open (file->paths[i].path, O_RDONLY | O_NOATIME);
731 if (fds[i] < 0)740 if (fds[i] < 0)
732 nih_warn ("%s: %s", file->paths[i].path,741 nih_warn ("%s: %s", file->paths[i].path,
733 strerror (errno));742 strerror (errno));
734 }743 }
735
736 print_time ("Open files", &start);744 print_time ("Open files", &start);
737745
738 /* Read in all of the blocks in a single pass for rotational746 /* Read in all of the blocks in a single pass for rotational
@@ -741,9 +749,9 @@
741 */749 */
742 for (size_t i = 0; i < file->num_blocks; i++) {750 for (size_t i = 0; i < file->num_blocks; i++) {
743 if ((fds[file->blocks[i].pathidx] < 0)751 if ((fds[file->blocks[i].pathidx] < 0)
752 || S_ISDIR(file->paths[file->blocks[i].pathidx].st_mode)
744 || (file->blocks[i].pathidx >= file->num_paths))753 || (file->blocks[i].pathidx >= file->num_paths))
745 continue;754 continue;
746
747 readahead (fds[file->blocks[i].pathidx],755 readahead (fds[file->blocks[i].pathidx],
748 file->blocks[i].offset,756 file->blocks[i].offset,
749 file->blocks[i].length);757 file->blocks[i].length);
@@ -756,26 +764,27 @@
756764
757static void765static void
758preload_inode_group (ext2_filsys fs,766preload_inode_group (ext2_filsys fs,
759 int group)767 int fd,
768 int group)
760{769{
761 ext2_inode_scan scan = NULL;770 ext2_inode_scan scan = NULL;
762771
763 nih_assert (fs != NULL);772 nih_assert (fs != NULL);
764773 int itable_size;
765 if (! ext2fs_open_inode_scan (fs, 0, &scan)) {774 if (EXT2_HAS_RO_COMPAT_FEATURE (fs->super, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
766 nih_assert (scan != NULL);775 itable_size = ((EXT2_INODES_PER_GROUP(fs->super)
767776 -fs->group_desc[group].bg_itable_unused)
768 if (! ext2fs_inode_scan_goto_blockgroup (scan, group)) {777 * EXT2_INODE_SIZE(fs->super));
769 struct ext2_inode inode;778 } else itable_size = EXT2_INODES_PER_GROUP(fs->super) * EXT2_INODE_SIZE(fs->super);
770 ext2_ino_t ino = 0;779 readahead (fd,
771780 fs->group_desc[group].bg_block_bitmap * EXT2_BLOCK_SIZE(fs->super),
772 while ((! ext2fs_get_next_inode (scan, &ino, &inode))781 (EXT2_BLOCKS_PER_GROUP(fs->super)+7) >> 3);
773 && (ext2fs_group_of_ino (fs, ino) == group))782 readahead (fd,
774 ;783 fs->group_desc[group].bg_inode_bitmap * EXT2_BLOCK_SIZE(fs->super),
775 }784 (EXT2_INODES_PER_GROUP(fs->super)+7) >> 3);
776785 readahead (fd,
777 ext2fs_close_inode_scan (scan);786 fs->group_desc[group].bg_inode_table * EXT2_BLOCK_SIZE(fs->super),
778 }787 itable_size);
779}788}
780789
781790
782791
=== modified file 'src/pack.h'
--- src/pack.h 2009-11-09 18:38:51 +0000
+++ src/pack.h 2011-12-06 03:33:24 +0000
@@ -42,6 +42,7 @@
42typedef struct pack_path {42typedef struct pack_path {
43 int group;43 int group;
44 ino_t ino;44 ino_t ino;
45 mode_t st_mode;
45 char path[PACK_PATH_MAX+1];46 char path[PACK_PATH_MAX+1];
46} PackPath;47} PackPath;
4748
4849
=== modified file 'src/trace.c'
--- src/trace.c 2010-09-20 17:27:30 +0000
+++ src/trace.c 2011-12-06 03:33:24 +0000
@@ -374,7 +374,12 @@
374374
375 fix_path (ptr);375 fix_path (ptr);
376 trace_add_path (parent, ptr, files, num_files);376 trace_add_path (parent, ptr, files, num_files);
377377 for (int i = strlen (ptr) - 1; i; i--) {
378 if (ptr[i] == '/') {
379 ptr[i] = 0;
380 trace_add_path (parent, ptr, files, num_files);
381 }
382 }
378 nih_free (line);383 nih_free (line);
379 }384 }
380385
@@ -496,7 +501,8 @@
496 if ((lstat (pathname, &statbuf) < 0)501 if ((lstat (pathname, &statbuf) < 0)
497 || (S_ISLNK (statbuf.st_mode)502 || (S_ISLNK (statbuf.st_mode)
498 && (stat (pathname, &statbuf) < 0))503 && (stat (pathname, &statbuf) < 0))
499 || (! S_ISREG (statbuf.st_mode)))504 || (!( S_ISREG (statbuf.st_mode)
505 || S_ISDIR (statbuf.st_mode))))
500 return 0;506 return 0;
501507
502 /* Open and stat again to get the genuine details, in case it508 /* Open and stat again to get the genuine details, in case it
@@ -519,7 +525,8 @@
519 }525 }
520526
521 /* Double-check that it's really still a file */527 /* Double-check that it's really still a file */
522 if (! S_ISREG (statbuf.st_mode)) {528 if (! (S_ISREG (statbuf.st_mode)
529 || S_ISDIR (statbuf.st_mode))) {
523 close (fd);530 close (fd);
524 return 0;531 return 0;
525 }532 }
@@ -545,6 +552,7 @@
545552
546 path->group = -1;553 path->group = -1;
547 path->ino = statbuf.st_ino;554 path->ino = statbuf.st_ino;
555 path->st_mode = statbuf.st_mode;
548556
549 strncpy (path->path, pathname, PACK_PATH_MAX);557 strncpy (path->path, pathname, PACK_PATH_MAX);
550 path->path[PACK_PATH_MAX] = '\0';558 path->path[PACK_PATH_MAX] = '\0';
@@ -585,9 +593,14 @@
585 }593 }
586594
587 /* Now read the in-memory chunks of this file and add those to595 /* Now read the in-memory chunks of this file and add those to
588 * the pack file too.596 * the pack file too. For directories, just add the whole
597 * thing for rotational disks.
589 */598 */
590 trace_add_chunks (*files, file, path, fd, statbuf.st_size);599 if (S_ISREG (statbuf.st_mode))
600 trace_add_chunks (*files, file, path, fd, statbuf.st_size);
601 else if (file->rotational)
602 trace_add_extents (*files, file, path, fd, statbuf.st_size,
603 0, statbuf.st_size);
591 close (fd);604 close (fd);
592605
593 return 0;606 return 0;

Subscribers

People subscribed via source and target branches

to all changes: