linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch] e4defrag: relevant file fragmentation with base_file
@ 2010-08-29 19:47 Andreas Rid
  2010-09-01  8:30 ` Kazuya Mio
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rid @ 2010-08-29 19:47 UTC (permalink / raw)
  To: k-mio; +Cc: linux-ext4

hi Kazuya Mio,

as I promised the implementation of the new interface
   e4defrag  -r  base_file  move_file..

Feel free to change.

 Andreas

diff --git a/misc/e4defrag.c b/misc/e4defrag.c
index 6022758..b7813d7 100644
--- a/misc/e4defrag.c
+++ b/misc/e4defrag.c
@@ -125,7 +125,8 @@
 #define MSG_USAGE		\
 "Usage	: e4defrag [-v] file...| directory...| device...\n\
 	: e4defrag  -c  file...| directory...| device...\n\
-	: e4defrag  -r  directory...| device...\n"
+	: e4defrag  -r  directory...| device...\n\
+	: e4defrag  -r  base_file move_file...\n"
 
 #define NGMSG_EXT4		"Filesystem is not ext4 filesystem"
 #define NGMSG_FILE_EXTENT	"Failed to get file extents"
@@ -133,7 +134,6 @@
 #define NGMSG_FILE_OPEN		"Failed to open"
 #define NGMSG_FILE_UNREG	"File is not regular file"
 #define NGMSG_LOST_FOUND	"Can not process \"lost+found\""
-#define NGMSG_FILE_UNDIR	"Target is not directory"
 
 /* Data type for filesystem-wide blocks number */
 typedef unsigned long long ext4_fsblk_t;
@@ -1593,7 +1593,7 @@ static int call_defrag(int fd, int donor_fd, const char *file,
 	return 0;
 }
 
-static unsigned long long get_dir_offset(const int fd, int *ret)
+static unsigned long long get_physical_offset(const int fd, int *ret)
 {
 	struct fiemap	*fiemap_buf;
 	char *fiebuf;
@@ -2129,13 +2129,6 @@ int main(int argc, char *argv[])
 			continue;
 		}
 
-		/* -r mode can defrag only directory. */
-		if ((mode_flag & RELEVANT) && arg_type == FILENAME) {
-			PRINT_ERR_MSG(NGMSG_FILE_UNDIR);
-			PRINT_FILE_NAME(argv[i]);
-			continue;
-		}
-
 		/* Set blocksize */
 		block_size = buf.st_blksize;
 
@@ -2223,7 +2216,7 @@ int main(int argc, char *argv[])
 					continue;
 				}
 
-				r_pstart = get_dir_offset(fd, &ret);
+				r_pstart = get_physical_offset(fd, &ret);
 				if (ret < 0) {
 					if (mode_flag & DETAIL) {
 						perror("failed to fiemap\n");
@@ -2327,8 +2320,44 @@ int main(int argc, char *argv[])
 			} else
 				printf("ext4 defragmentation for %s\n",
 								 argv[i]);
-			/* Defrag single file process */
-			file_defrag(argv[i], &buf, FTW_F, NULL);
+
+			if (mode_flag & RELEVANT && i == optind) {
+				if (i - argc == 1)
+					/* not enought arguemnts */
+					goto out;
+
+				/*
+				 * call defrag for base_file
+				 * don't move extents to r_pstart
+				 */
+				mode_flag &= ~RELEVANT;
+				file_defrag(argv[i], &buf, FTW_F, NULL);
+				mode_flag |= RELEVANT;
+
+				/* get physical start of base_file for PA */
+				int fd, ret;
+				fd = open(argv[i], O_RDONLY);
+				if (fd < 0) {
+					if (mode_flag & DETAIL) {
+						PRINT_FILE_NAME(argv[i]);
+						STATISTIC_ERR_MSG_WITH_ERRNO(NGMSG_FILE_OPEN);
+					}
+					goto out;
+				}
+				
+				r_pstart = get_physical_offset(fd, &ret);
+				if (ret < 0) {
+					if (mode_flag & DETAIL) {
+						perror("failed to fiemap\n");
+						PRINT_FILE_NAME(dir_name);
+					}
+					goto out;
+				}
+				close(fd);
+			} else 
+				/* Defrag single file process */
+				file_defrag(argv[i], &buf, FTW_F, NULL);
+			
 			if (succeed_cnt != 0)
 				printf(" Success:\t\t\t[1/1]\n");
 			else

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [patch] e4defrag: relevant file fragmentation with base_file
  2010-08-29 19:47 [patch] e4defrag: relevant file fragmentation with base_file Andreas Rid
@ 2010-09-01  8:30 ` Kazuya Mio
  0 siblings, 0 replies; 2+ messages in thread
From: Kazuya Mio @ 2010-09-01  8:30 UTC (permalink / raw)
  To: Andreas Rid; +Cc: ext4

2010/08/30 4:47, Andreas Rid wrote:
> @@ -2327,8 +2320,44 @@ int main(int argc, char *argv[])
>   			} else
>   				printf("ext4 defragmentation for %s\n",
>   								 argv[i]);
> -			/* Defrag single file process */
> -			file_defrag(argv[i],&buf, FTW_F, NULL);
> +
> +			if (mode_flag&  RELEVANT&&  i == optind) {
> +				if (i - argc == 1)
> +					/* not enought arguemnts */
> +					goto out;

I think this condition should be "argc - optind == 1" because "i" is smaller
than argc at all times.

> +					goto out;
> +				}
> +				
> +				r_pstart = get_physical_offset(fd,&ret);

If e4defrag is executed with the following arguments, e4defrag will move the
extents of "move_file" near the "directory".
# e4defrag -r base_file directory move_file

To prevent this case, r_pstart should not be changed even if directories or
devices are set to the argument of e4defrag after the physical block number of
the "base_file" was assigned to r_pstart.

I will fix your patch in above way. Any comments?

Regards,
Kazuya Mio


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-09-01  8:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-29 19:47 [patch] e4defrag: relevant file fragmentation with base_file Andreas Rid
2010-09-01  8:30 ` Kazuya Mio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).