Re: [PATCH] btrfs: add better -ENOSPC handling VERSION 3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Josef.

> Thank you, what tool are you using to create these files and such?

I use an original tool.
I do not make the document.

ex.
./mkfbmt -d /btrfs -f 10000000 -x 10000
This makes a file under 10,000 directories with 10,000,000 files in /btrfs.

make 10,000 files under 100 directories each.
100dir * 10000files = 10000000

/btrfs/0/0
/btrfs/0/1
 ...
/btrfs/0/9998
/btrfs/0/9999
/btrfs/1/0
 ...
/btrfs/99/9999

defaults file size is zero byte.
When make a file of 4,096 bytes, please appoint -w 4096.
defaults option is all test.
-m mkdir
-c open(O_CREAT | O_EXCL | O_WRONLY) test
-o open test
-p utime test
-s stat test
-u unlink test
-r rmdir

# ./mkfbmt -d /btrfs/ -f 1000000 -x 10000
## __linuxfs_init(91) [0x401fc8]
mkfbmt 100 directry 1000000 files , one directry 10000 files
make files for /btrfs

mkdir : 0.004923 sec , 1 file mkdir  for 0.000000 sec
creat : 179.155566 sec , 1 file creat  for 0.000179 sec
open  : 26.696062 sec , 1 file open   for 0.000027 sec
utime : 55.143818 sec , 1 file utime   for 0.000055 sec
stat  : 4.692097 sec , 1 file stat   for 0.000005 sec
unlink: 210.624820 sec , 1 file unlink for 0.000211 sec
rmdir : 0.806472 sec , 1 file rmdir  for 0.000001 sec
file        creat       open        utime       stat        unlink
     50000       4.08       1.18       2.17       0.13      14.18
    100000      10.70       1.86       4.78       0.25      22.57
    150000      55.87       2.42       7.57       0.37      30.99
    200000      63.74       3.23       9.81       0.49      42.35
    250000      69.72       4.93      12.16       0.60      55.71
    300000      76.37       7.16      14.56       0.72      64.03
    350000      83.60      10.34      17.01       0.83      91.18
    400000      90.23      15.36      19.60       0.94     103.36
    450000      97.47      20.07      22.17       1.06     111.07
    500000     103.99      22.14      24.56       1.38     118.84
    550000     110.85      22.36      26.93       1.88     126.66
    600000     118.49      22.58      29.70       2.30     136.47
    650000     125.26      23.08      32.05       2.50     148.96
    700000     132.34      23.65      34.28       3.01     156.62
    750000     138.89      24.22      36.80       3.54     164.49
    800000     146.38      24.78      44.05       4.05     172.23
    850000     155.14      25.34      46.81       4.28     180.48
    900000     163.21      26.25      49.85       4.41     195.99
    950000     171.81      26.47      52.22       4.55     203.47
   1000000     179.16      26.70      55.14       4.69     210.62

Best regards,

On Tue, 17 Feb 2009 08:42:19 -0500
Josef Bacik <josef@xxxxxxxxxx> wrote:

> On Tue, Feb 17, 2009 at 06:21:10PM +0900, Yoshihiro Takahashi wrote:
> > Hi Josef.
> > 
> > I created file till return of ENOSPC.
> > I created 18874027 files of size zero on btrfs of 16Gbyte in 1609 seconds.
> > I test to cause ENOSPC-problem but there was not the problem.
> > ENOSPC-problem were fixed in linux-2.6.29-rc5 and this patch.
> > This is a good patch.
> > 
> > Next.
> > I created 2758939 files of size 4096 on btrfs of 16Gbyte in 431 seconds.
> > And I received the following messages when I unlink files.
> > 
> >  btrfs searching for 4096 bytes, num_bytes 4096, loop 2, allowed_alloc 0
> >  btrfs allocation failed flags 36, wanted 4096
> >  space_info has 65536 free, is full
> >  space_info total=1932853248, pinned=164216832, delalloc=0, may_use=0, used=1768570880
> >  block group 29360128 has 1073741824 bytes, 942583808 used 131092480 pinned 0 reserved
> >  0 blocks of free space at or bigger than bytes is
> >  block group 8619294720 has 859111424 bytes, 825987072 used 33124352 pinned 0 reserved
> >  0 blocks of free space at or bigger than bytes is
> >  ------------[ cut here ]------------
> >  kernel BUG at fs/btrfs/extent-tree.c:3360!
> >  invalid opcode: 0000 [#1] SMP
> >  last sysfs file: /sys/devices/pci0000:80/0000:80:0e.0/0000:84:00.0/local_cpus
> >  CPU 3
> >  Modules linked in: btrfs zlib_deflate nls_utf8 hfsplus autofs4 hidp rfcomm l2cap bluetooth sunrpc ib_iser libiscsi scsi_transport_iscsi ib_srp scsi_transport_srp ib_ipoib inet_lro rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm ib_addr ib_sa ib_mad ib_core dm_mirror dm_region_hash dm_log dm_multipath dm_mod sbs sbshc battery acpi_memhotplug ac ipv6 lp floppy snd_intel8x0 snd_ac97_codec ac97_bus snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss sg rtc_cmos snd_mixer_oss snd_pcm snd_timer rtc_core parport_pc tg3 libphy ide_cd_mod snd button parport cdrom serio_raw rtc_lib i2c_amd8111 i2c_amd756 k8temp soundcore hwmon snd_page_alloc shpchp amd_rng i2c_core pcspkr sata_sil libata aic79xx scsi_transport_spi sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd
> >  Pid: 20535, comm: rm Tainted: G   M       2.6.29-rc5 #1 -[62176J7]-
> >  RIP: 0010:[<ffffffffa041e529>]  [<ffffffffa041e529>] __btrfs_reserve_extent+0x25b/0x270 [btrfs]
> >  RSP: 0018:ffff8800acd6d3d8  EFLAGS: 00010246
> >  RAX: ffff88011996ca38 RBX: ffff88011996c960 RCX: 0000000000008610
> >  RDX: 000000000000e1e1 RSI: 0000000000000246 RDI: ffff88011996ca34
> >  RBP: ffff8800acd6d448 R08: 0000000000000000 R09: 00000000ffffff00
> >  R10: 000000000000000a R11: 0000000000000000 R12: ffff88011996c9c0
> >  R13: 0000000000001000 R14: ffff88011996ca30 R15: 0000000000001000
> >  FS:  00007fea3f7486e0(0000) GS:ffff88012ecffcc0(0000) knlGS:00000000f7fa38d0
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> >  CR2: 00007f651b793000 CR3: 00000000c64be000 CR4: 00000000000006e0
> >  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> >  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> >  Process rm (pid: 20535, threadinfo ffff8800acd6c000, task ffff88012ed8c970)
> >  Stack:
> >   0000000000000000 ffff8800acd6d4f8 0000000000000000 0000000000000000
> >   ffffe20000000024 ffff880000000000 0000000000000000 0000000000000000
> >   ffff88010c0c4000 0000000000001000 ffff8800acd6d4f8 ffff88012a516000
> >  Call Trace:
> >   [<ffffffffa0421005>] btrfs_alloc_extent+0x48/0xa7 [btrfs]
> >   [<ffffffffa04210c0>] btrfs_alloc_free_block+0x5c/0x87 [btrfs]
> >   [<ffffffffa04155e1>] __btrfs_cow_block+0x1e7/0x82e [btrfs]
> >   [<ffffffffa04162d9>] btrfs_cow_block+0x1ed/0x1fc [btrfs]
> >   [<ffffffffa0419cb2>] btrfs_search_slot+0x31a/0x90f [btrfs]
> >   [<ffffffffa041add4>] btrfs_insert_some_items+0xb2/0x570 [btrfs]
> >   [<ffffffff80279fa3>] ? unlock_page+0x22/0x27
> >   [<ffffffffa04482df>] ? set_extent_buffer_dirty+0x102/0x131 [btrfs]
> >   [<ffffffffa041f50b>] insert_extents+0x162/0x36f [btrfs]
> >   [<ffffffffa0420105>] finish_current_insert+0x4de/0x553 [btrfs]
> >   [<ffffffffa04228dc>] __btrfs_inc_extent_ref+0x1b5/0x1e4 [btrfs]
> >   [<ffffffff8034a2fe>] ? generic_swap+0x0/0x1c
> >   [<ffffffffa04256fb>] btrfs_inc_ref+0x42d/0x4ce [btrfs]
> >   [<ffffffffa0422727>] ? __btrfs_inc_extent_ref+0x0/0x1e4 [btrfs]
> >   [<ffffffffa0445c95>] ? copy_extent_buffer+0x115/0x149 [btrfs]
> >   [<ffffffffa0415834>] __btrfs_cow_block+0x43a/0x82e [btrfs]
> >   [<ffffffffa04162d9>] btrfs_cow_block+0x1ed/0x1fc [btrfs]
> >   [<ffffffffa0419cb2>] btrfs_search_slot+0x31a/0x90f [btrfs]
> >   [<ffffffff8034d5e8>] ? crc32c+0x4c/0x60
> >   [<ffffffffa0427d8d>] btrfs_lookup_dir_item+0x71/0xe7 [btrfs]
> >   [<ffffffffa04337e4>] btrfs_unlink_inode+0x60/0x26f [btrfs]
> >   [<ffffffffa042f0e5>] ? start_transaction+0xf9/0x105 [btrfs]
> >   [<ffffffffa0433dbc>] btrfs_unlink+0x55/0x97 [btrfs]
> >   [<ffffffff802af53b>] vfs_unlink+0xb9/0x12c
> >   [<ffffffff802b197e>] do_unlinkat+0xc1/0x173
> >   [<ffffffff802b4063>] ? vfs_readdir+0x9a/0xaf
> >   [<ffffffff8026855b>] ? audit_syscall_entry+0x16b/0x19e
> >   [<ffffffff802b1a41>] sys_unlink+0x11/0x13
> >   [<ffffffff8020c05b>] system_call_fastpath+0x16/0x1b
> >  Code: 00 48 81 eb b8 00 00 00 48 8b 83 b8 00 00 00 48 8d 93 b8 00 00 00 0f 18 08 49 8d 44 24 58 48 39 c2 75 9f 4c 89 f7 e8 29 1e e3 df <0f> 0b eb fe 48 83 c4 48 31 c0 5b 41 5c 41 5d 41 5e 41 5f c9 c3
> >  RIP  [<ffffffffa041e529>] __btrfs_reserve_extent+0x25b/0x270 [btrfs]
> >   RSP <ffff8800acd6d3d8>
> >  ---[ end trace b5c34207a1ecc394 ]---
> > 
> > And, I received the following messages when I utime(2) files.
> > 
> >  btrfs searching for 4096 bytes, num_bytes 4096, loop 2, allowed_alloc 1
> >  btrfs allocation failed flags 36, wanted 4096
> >  space_info has 65536 free, is full
> >  space_info total=1932853248, pinned=54943744, delalloc=0, may_use=0, used=1877843968
> >  block group 29360128 has 1073741824 bytes, 1041494016 used 32182272 pinned 0 reserved
> >  0 blocks of free space at or bigger than bytes is
> >  block group 8619294720 has 859111424 bytes, 836349952 used 22761472 pinned 0 reserved
> >  0 blocks of free space at or bigger than bytes is
> >  ------------[ cut here ]------------
> >  kernel BUG at fs/btrfs/extent-tree.c:3360!
> >  invalid opcode: 0000 [#1] SMP
> >  last sysfs file: /sys/devices/pci0000:80/0000:80:0e.0/0000:84:00.0/local_cpus
> >  CPU 3
> >  Modules linked in: btrfs zlib_deflate autofs4 hidp rfcomm l2cap bluetooth sunrpc ib_iser libiscsi scsi_transport_iscsi ib_srp scsi_transport_srp ib_ipoib inet_lro rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm ib_addr ib_sa ib_mad ib_core dm_mirror dm_region_hash dm_log dm_multipath dm_mod sbs sbshc battery acpi_memhotplug ac ipv6 lp floppy snd_intel8x0 snd_ac97_codec ac97_bus snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss k8temp button sg snd_pcm i2c_amd8111 snd_timer snd serio_raw parport_pc rtc_cmos tg3 i2c_amd756 soundcore rtc_core parport hwmon libphy i2c_core ide_cd_mod cdrom rtc_lib amd_rng pcspkr snd_page_alloc shpchp sata_sil libata aic79xx scsi_transport_spi sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd
> >  Pid: 14421, comm: mkfbmt Tainted: G   M       2.6.29-rc5 #1 -[62176J7]-
> >  RIP: 0010:[<ffffffffa0407529>]  [<ffffffffa0407529>] __btrfs_reserve_extent+0x25b/0x270 [btrfs]
> >  RSP: 0018:ffff88010010d968  EFLAGS: 00010246
> >  RAX: ffff880026bed8f8 RBX: ffff880026bed820 RCX: 0000000000008689
> >  RDX: 0000000000005959 RSI: 0000000000000246 RDI: ffff880026bed8f4
> >  RBP: ffff88010010d9d8 R08: 0000000000000000 R09: 00000000ffffff00
> >  R10: 000000000000000a R11: 0000000000000000 R12: ffff880026bed880
> >  R13: 0000000000001000 R14: ffff880026bed8f0 R15: 0000000000001000
> >  FS:  00007fb97df446e0(0000) GS:ffff88012ecffcc0(0000) knlGS:00000000f7f4f8d0
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> >  CR2: 000000342e614ce5 CR3: 000000011557b000 CR4: 00000000000006e0
> >  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> >  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> >  Process mkfbmt (pid: 14421, threadinfo ffff88010010c000, task ffff88011f9738d0)
> >  Stack:
> >   0000000000000000 ffff88010010da88 0000000000000000 0000000000000000
> >   ffff880100000024 ffff88010010dad4 0000000000000000 0000000000000000
> >   ffff8801145c0000 0000000000001000 ffff88010010da88 ffff8801149cd000
> >  Call Trace:
> >   [<ffffffffa040a005>] btrfs_alloc_extent+0x48/0xa7 [btrfs]
> >   [<ffffffffa040a0c0>] btrfs_alloc_free_block+0x5c/0x87 [btrfs]
> >   [<ffffffffa03fe5e1>] __btrfs_cow_block+0x1e7/0x82e [btrfs]
> >   [<ffffffffa03ff2d9>] btrfs_cow_block+0x1ed/0x1fc [btrfs]
> >   [<ffffffffa0402cb2>] btrfs_search_slot+0x31a/0x90f [btrfs]
> >   [<ffffffffa0419b89>] ? btrfs_lookup_dentry+0x159/0x16f [btrfs]
> >   [<ffffffff802cd6a1>] ? inotify_d_instantiate+0x1a/0x43
> >   [<ffffffff802b6984>] ? d_splice_alias+0xc4/0xd0
> >   [<ffffffffa0412a8c>] btrfs_lookup_inode+0x2c/0x90 [btrfs]
> >   [<ffffffffa041bb13>] btrfs_update_inode+0x46/0xbd [btrfs]
> >   [<ffffffffa041c770>] btrfs_dirty_inode+0x3e/0x52 [btrfs]
> >   [<ffffffff802c0f3c>] __mark_inode_dirty+0x33/0x178
> >   [<ffffffff802b998c>] inode_setattr+0x11b/0x125
> >   [<ffffffffa041ace0>] btrfs_setattr+0x56/0x6e [btrfs]
> >   [<ffffffff802b9b2a>] notify_change+0x194/0x2d6
> >   [<ffffffff802c3969>] utimes_common+0x121/0x163
> >   [<ffffffff802c3a64>] do_utimes+0xb9/0xda
> >   [<ffffffff802c3c0f>] sys_utime+0x66/0x7b
> >   [<ffffffff8020c05b>] system_call_fastpath+0x16/0x1b
> >  Code: 00 48 81 eb b8 00 00 00 48 8b 83 b8 00 00 00 48 8d 93 b8 00 00 00 0f 18 08 49 8d 44 24 58 48 39 c2 75 9f 4c 89 f7 e8 29 8e e4 df <0f> 0b eb fe 48 83 c4 48 31 c0 5b 41 5c 41 5d 41 5e 41 5f c9 c3
> >  RIP  [<ffffffffa0407529>] __btrfs_reserve_extent+0x25b/0x270 [btrfs]
> >   RSP <ffff88010010d968>
> >  ---[ end trace 16075f4743156c16 ]---
> > 
> > Thanks, regards,
> > 
> 
> Thank you, what tool are you using to create these files and such?
> 
> Josef
/*
 *      mkfbmt.c
 *      http://wiki.livedoor.jp/linuxfs/
 *      yos.takahashi@xxxxxxxxx
 *
 *      2005.09.14  updated by ytakahashi
 *      2007.01.05  updated by ytakahashi
 *                  creat -> open(O_CREAT | O_EXCL | O_WRONLY)
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <inttypes.h>

#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <utime.h>

#define KEEP_FILE 20
#define CHECK_ENTRY 6

#define MK_ALL		  0
#define MK_MKDIR	  1
#define MK_CREATE	  2
#define MK_OPEN		  4
#define MK_UTIME	 16
#define MK_STAT		 32
#define MK_UNLINK	 64
#define MK_RMDIR	128

/* grobal config */
typedef struct mkfbmt_conf {
	int files;
	uint64_t max_files;
	int directry;
	int time_out;
	int total;
	int mk_files;
	int entry;
	int loops;
	int modis;
	size_t w_size;
} mkfbmt_conf_t;

double table[KEEP_FILE][CHECK_ENTRY];
struct timeval g_rtime;
struct timeval g_etime;

struct mkfbmt_conf conf = {
	.files = 10000,
	.max_files = 0xffffffffffffffffULL,
	.directry = 0,
	.time_out = 0,
	.total = 0,
	.mk_files = 0,
	.entry = 0,
	.loops = 1,
	.modis = 1000,
	.w_size = 0,
};

char *w_buf = NULL;

void handler(int sig);

/* usage */
void Bform()
{
	fprintf(stderr, "Usage:[-d directry][-f targetfile count][-t signal][-x file count][-l count][-mcosur][-w size]\n"
			"       -d test directry\n"
			"       -f targetfile count\n"
			"       -t time_out print time\n"
			"       -x max file for directry\n"
			"       -l test loop count\n"
			"       -m mkdir  test\n"
			"       -c creat  test\n"
			"       -o open   test\n"
			"       -p utime  test\n"
			"       -s stat   test\n"
			"       -u unlink test\n"
			"       -r rmdir  test\n"
			"       -w write  test\n");
	exit(1);
}

void __linuxfs_init(void)
{
	fprintf(stderr, "## %s(%d) [%p] \n", __FUNCTION__, __LINE__, __builtin_return_address(0));
}

/* error */
void Berror(int errs)
{
	fprintf(stderr, "ERROR : %s \n", strerror(errs));
	exit(1);
}

void Berror2(int errs)
{
	fprintf(stderr, "ERROR : %s \n", strerror(errs));
}

/* e_time */
double e_time(struct timeval first, struct timeval second)
{
	if (first.tv_usec > second.tv_usec) {
		second.tv_usec += 1000000;
		second.tv_sec--;
	}
	return((double)(second.tv_sec - first.tv_sec) * 1000000.0
		+ (double)(second.tv_usec - first.tv_usec));
}

/* for timeout setting */
void set_sigalrm(void)
{
	struct sigaction act;
	sigset_t full_mask;
	conf.mk_files = 0;


	if (sigfillset(&full_mask)) {
		fprintf(stderr, "Cannot fill signal mask\n");
		exit(1);
	}

	if (sigdelset(&full_mask, SIGALRM)) {
		fprintf(stderr, "Cannot reset signal mask\n");
		exit(1);
	}

	if (sigprocmask(SIG_BLOCK, &full_mask, NULL)) {
		fprintf(stderr, "Cannot set signal proc mask\n");
		exit(1);
	}

	act.sa_handler = handler;
	act.sa_flags = SA_RESTART;
	act.sa_mask = full_mask;

	if (sigaction(SIGALRM,  &act, NULL)) {
		fprintf(stderr, "Cannot set signal action\n");
		exit(1);
	}
	alarm(conf.time_out);
}

/* unset timeout */
void unset_sigalrm(void)
{
	alarm(0);
}

/* signal handler */
void handler(int sig)
{
	if (sig == SIGALRM) {
		unset_sigalrm();
		conf.total += conf.mk_files;
		printf("make %8d(+%8d) / %8d  \n", conf.total, conf.mk_files, conf.files);
		conf.mk_files = 0;
		set_sigalrm();
	}
}

/* make dir */
void ll_mkdir(void)
{
	int i;
	char file_name[PATH_MAX + 1];

	for (i = 0; i < conf.directry; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		if (mkdir(file_name, 0777)) {
			Berror(errno);
		}
		conf.entry++;
		conf.mk_files++;
	}
}

/* rmdir */
void ll_rmdir(void)
{
	int i;
	char file_name[PATH_MAX + 1];

	for (i = 0; i < conf.directry; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		if (rmdir(file_name)) {
			Berror(errno);
		}
		conf.entry++;
		conf.mk_files++;
	}
}

/* create */
void ll_creat(int files)
{
	int fd, i, x;
	char file_name[PATH_MAX + 1];

	for (i = 0; i < files; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
		if (fd < 0) {
			Berror2(errno);
			return;
		}
		if (conf.w_size) {
			write(fd, w_buf, conf.w_size);
		}
		close(fd);
		conf.entry++;
		conf.mk_files++;
		if (!(conf.entry % conf.modis)) {
			gettimeofday (&g_etime, NULL);
			x = ((conf.entry / conf.modis) > 0) ? ((conf.entry / conf.modis) - 1) : 0;
			table[x][1] = (double)(e_time(g_rtime, g_etime)) / 1000000.0;
		}
	}
}

/* open */
void ll_open(int files)
{
	int i, fd, x;
	char file_name[PATH_MAX + 1];

	for (i = 0; i < files; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		fd = open(file_name, O_RDONLY);
		if (fd < 0) {
			Berror2(errno);
			return;
		}
		close(fd);
		conf.entry++;
		conf.mk_files++;
		if (!(conf.entry % conf.modis)) {
			gettimeofday (&g_etime, NULL);
			x = ((conf.entry / conf.modis) > 0) ? ((conf.entry / conf.modis) - 1) : 0;
			table[x][2] = (double)(e_time(g_rtime, g_etime)) / 1000000.0;
		}
	}
}

void ll_utime(int files)
{
	int i, x;
	struct utimbuf ut;
	char file_name[PATH_MAX + 1];
	ut.actime = 0;
	ut.modtime = 0;

	for (i = 0; i < files; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		if (utime(file_name, &ut) < 0) {
			Berror2(errno);
			return;
		}

		conf.entry++;
		conf.mk_files++;
		if (!(conf.entry % conf.modis)) {
			gettimeofday (&g_etime, NULL);
			x = ((conf.entry / conf.modis) > 0) ? ((conf.entry / conf.modis) - 1) : 0;
			table[x][3] = (double)(e_time(g_rtime, g_etime)) / 1000000.0;
		}
	}
}

/* stat */
void ll_stat(int files)
{
	int i, x;
	char file_name[PATH_MAX + 1];
	struct stat sb;

	for (i = 0; i < files; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		if (stat(file_name, &sb)) {
			Berror2(errno);
			return;
		}
		conf.entry++;
		conf.mk_files++;
		if (!(conf.entry % conf.modis)) {
			gettimeofday (&g_etime, NULL);
			x = ((conf.entry / conf.modis) > 0) ? ((conf.entry / conf.modis) - 1) : 0;
			table[x][4] = (double)(e_time(g_rtime, g_etime)) / 1000000.0;
		}
	}
}

/* unlink */
void ll_unlink(int files)
{
	int i, x;
	char file_name[PATH_MAX + 1];

	for (i = 0; i < files; i++) {
		snprintf(file_name, PATH_MAX, "%d", i);
		unlink(file_name);
		conf.entry++;
		conf.mk_files++;
		if (!(conf.entry % conf.modis)) {
			gettimeofday (&g_etime, NULL);
			x = ((conf.entry / conf.modis) > 0) ? ((conf.entry / conf.modis) - 1) : 0;
			table[x][5] = (double)(e_time(g_rtime, g_etime)) / 1000000.0;
		}
	}
}

void creat_op(const char *directry)
{
	int i, files, sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	if (conf.directry == 0) {
		snprintf(path, PATH_MAX, "%s", directry);
		chdir(path);
		ll_creat(sv_files);
	} else {
		for (i = 0; i < conf.directry; i++) {
			sv_files > conf.max_files ? (files = conf.max_files) : (files = sv_files);
			sv_files -= conf.max_files;
			snprintf(path, PATH_MAX, "%s/%d", directry, i);
			chdir(path);
			ll_creat(files);
		}
	}
	gettimeofday (&stop, NULL);
	unset_sigalrm();
	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("creat : %lf sec , 1 file creat  for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void open_op(const char *directry)
{
	int i, files, sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	if (conf.directry == 0) {
		snprintf(path, PATH_MAX, "%s", directry);
		chdir(path);
		ll_open(sv_files);
	} else {
		for (i = 0; i < conf.directry; i++) {
			sv_files > conf.max_files ? (files = conf.max_files) : (files = sv_files);
			sv_files -= conf.max_files;
			snprintf(path, PATH_MAX, "%s/%d", directry, i);
			chdir(path);
			ll_open(files);
		}
	}
	gettimeofday (&stop, NULL);
	unset_sigalrm();

	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("open  : %lf sec , 1 file open   for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void stat_op(const char *directry)
{
	int i, files, sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	if (conf.directry == 0) {
		snprintf(path, PATH_MAX, "%s", directry);
		chdir(path);
		ll_stat(sv_files);
	} else {
		for (i = 0; i < conf.directry; i++) {
			sv_files > conf.max_files ? (files = conf.max_files) : (files = sv_files);
			sv_files -= conf.max_files;
			snprintf(path, PATH_MAX, "%s/%d", directry, i);
			chdir(path);
			ll_stat(files);
		}
	}
	gettimeofday (&stop, NULL);
	unset_sigalrm();

	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("stat  : %lf sec , 1 file stat   for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void utime_op(const char *directry)
{
	int i, files, sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	if (conf.directry == 0) {
		snprintf(path, PATH_MAX, "%s", directry);
		chdir(path);
		ll_utime(sv_files);
	} else {
		for (i = 0; i < conf.directry; i++) {
			sv_files > conf.max_files ? (files = conf.max_files) : (files = sv_files);
			sv_files -= conf.max_files;
			snprintf(path, PATH_MAX, "%s/%d", directry, i);
			chdir(path);
			ll_utime(files);
		}
	}
	gettimeofday (&stop, NULL);
	unset_sigalrm();

	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("utime : %lf sec , 1 file utime   for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void unlink_op(const char *directry)
{
	int i, files, sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	if (conf.directry == 0) {
		snprintf(path, PATH_MAX, "%s", directry);
		chdir(path);
		ll_unlink(sv_files);
	} else {
		for (i = 0; i < conf.directry; i++) {
			sv_files > conf.max_files ? (files = conf.max_files) : (files = sv_files);
			sv_files -= conf.max_files;
			snprintf(path, PATH_MAX, "%s/%d", directry, i);
			chdir(path);
			ll_unlink(files);
		}
	}
	gettimeofday (&stop, NULL);
	unset_sigalrm();

	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("unlink: %lf sec , 1 file unlink for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void mkdir_op(const char *directry)
{
	int sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	snprintf(path, PATH_MAX, "%s", directry);
	chdir(path);
	ll_mkdir();

	gettimeofday (&stop, NULL);
	unset_sigalrm();

	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("mkdir : %lf sec , 1 file mkdir  for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void rmdir_op(const char *directry)
{
	int sv_files;
	char path[PATH_MAX + 1];
	double sec;
	struct timeval start, stop;

	conf.entry = 0;
	conf.total = 0;
	sv_files = conf.files;
	set_sigalrm();
	gettimeofday (&start, NULL);
	gettimeofday (&g_rtime, NULL);

	snprintf(path, PATH_MAX, "%s", directry);
	chdir(path);
	ll_rmdir();

	gettimeofday (&stop, NULL);
	unset_sigalrm();

	sec = (double)(e_time(start, stop)) / 1000000.0 / conf.files;
	printf("rmdir : %lf sec , 1 file rmdir  for %lf sec\n", (double)(e_time(start, stop)) / 1000000.0, sec);
}

void print(void)
{
	int i, j;
	printf("file        creat       open        utime       stat        unlink\n");
	for (i = 0; i < KEEP_FILE; i++) {
		printf("%10.0lf ", table[i][0]);
		for (j = 1; j < CHECK_ENTRY; j++) {
			printf("%10.2lf ", table[i][j]);
		}
		printf("\n");
	}
}

/* main */
int main(int argc, char *argv[])
{
	int c, i, j;
	char directry[PATH_MAX + 1];
	char *realpath_ptr;
	unsigned int submit = MK_ALL;

	__linuxfs_init();
	strncpy(directry, "./\0", PATH_MAX);

	for (i = 0; i < KEEP_FILE; i++) {
		for (j = 0; j < CHECK_ENTRY; j++) {
			table[i][j] = 0;
		}
		table[i][0] = (double) i * conf.modis;
	}

	while ((c = getopt(argc, argv, "d:f:x:t:l:w:mcosurp")) != EOF) {
		switch (c) {
		case 'd':
			strncpy(directry, optarg, PATH_MAX);
			break;
		case 'f':
			conf.files = atoi(optarg);
			if (conf.files < 0) {
				Berror(EINVAL);
			}
			break;
		case 'x':
			conf.max_files = atoi(optarg);
			if (conf.max_files < 0) {
				Berror(EINVAL);
			}
			break;
		case 't':
			conf.time_out = atoi(optarg);
			if (conf.time_out < 0) {
				Berror(EINVAL);
			}
			break;
		case 'l':
			conf.loops = atoi(optarg);
			if (conf.loops < 0) {
				Berror(EINVAL);
			}
			break;
		case 'w':
			conf.w_size = atoi(optarg);
			if (conf.w_size < 0) {
				Berror(EINVAL);
			}
			w_buf = (char *)malloc(conf.w_size);
			if (!w_buf) {
				Berror(errno);
			}
			break;
		case 'm':
			submit |= MK_MKDIR;
			break;
		case 'c':
			submit |= MK_CREATE;
			break;
		case 'o':
			submit |= MK_OPEN;
			break;
		case 'p':
			submit |= MK_UTIME;
			break;
		case 's':
			submit |= MK_STAT;
			break;
		case 'u':
			submit |= MK_UNLINK;
			break;
		case 'r':
			submit |= MK_RMDIR;
			break;
		default:
			Bform();
		}
	}

	if (conf.max_files > 0) {
		conf.directry = conf.files / conf.max_files;
		conf.modis = conf.files / KEEP_FILE;
	} else {
		Berror(EINVAL);
	}

	for (i = 0; i < KEEP_FILE; i++) {
		for (j = 0; j < CHECK_ENTRY; j++) {
			table[i][j] = 0;
		}
		table[i][0] = (double) (i + 1) * conf.modis;
	}

	realpath_ptr = realpath(directry, NULL);
	if (realpath_ptr == NULL) {
		Berror(errno);
	}

	printf("mkfbmt %d directry %d files , one directry %"PRIu64" files\n",
		conf.directry, conf.files, conf.max_files);
	printf("make files for %s\n\n", realpath_ptr);

	for (i = 0; i < conf.loops; i++) {
		if (submit == MK_ALL || submit & MK_MKDIR) {
			mkdir_op(realpath_ptr);
		}
		if (submit == MK_ALL || submit & MK_CREATE) {
			creat_op(realpath_ptr);
		}
		if (submit == MK_ALL || submit & MK_OPEN) {
			open_op(realpath_ptr);
		}
		if (submit == MK_ALL || submit & MK_UTIME) {
			utime_op(realpath_ptr);
		}
		if (submit == MK_ALL || submit & MK_STAT) {
			stat_op(realpath_ptr);
		}
		if (submit == MK_ALL || submit & MK_UNLINK) {
			unlink_op(realpath_ptr);
		}
		if (submit == MK_ALL || submit & MK_RMDIR) {
			rmdir_op(realpath_ptr);
		}
		print();
	}
	return 0;
}

[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux