diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2002-04-06 05:02:54 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2002-04-06 05:02:54 +0000 |
commit | 65528d17826ca7dd6b516112ee5dbda7829ad8ab (patch) | |
tree | fdb822739530583e19f544f6f40dfe82b4dc759a /usr.sbin | |
parent | 5e022fc6f0b7d803e1bd1e48cebf5d5af4883eb4 (diff) | |
download | src-65528d17826ca7dd6b516112ee5dbda7829ad8ab.tar.gz src-65528d17826ca7dd6b516112ee5dbda7829ad8ab.zip |
Simplify and optimize. This speeds up 'initattr' enormously for small
attribute sizes (up to two orders of magnitude!)
Notes
Notes:
svn path=/head/; revision=93928
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/extattrctl/extattrctl.c | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/usr.sbin/extattrctl/extattrctl.c b/usr.sbin/extattrctl/extattrctl.c index 98e1d35edd94..c066712c2287 100644 --- a/usr.sbin/extattrctl/extattrctl.c +++ b/usr.sbin/extattrctl/extattrctl.c @@ -83,26 +83,26 @@ num_inodes_by_path(char *path) return (buf.f_files); } +static const char zero_buf[8192]; + int initattr(int argc, char *argv[]) { struct ufs_extattr_fileheader uef; char *fs_path = NULL; - char *zero_buf = NULL; - long loop, num_inodes; - int ch, i, error, chunksize, overwrite = 0, flags; + int ch, i, error, flags; + ssize_t wlen; + size_t easize; + flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL; optind = 0; while ((ch = getopt(argc, argv, "fp:r:w:")) != -1) switch (ch) { case 'f': - overwrite = 1; + flags &= ~O_EXCL; break; case 'p': - if ((fs_path = strdup(optarg)) == NULL) { - perror("strdup"); - return(-1); - } + fs_path = optarg; break; case '?': default: @@ -115,44 +115,32 @@ initattr(int argc, char *argv[]) if (argc != 2) usage(); - if (overwrite) - flags = O_CREAT | O_WRONLY; - else - flags = O_CREAT | O_EXCL | O_WRONLY; - error = 0; - if ((i = open(argv[1], flags, 0600)) != -1) { - uef.uef_magic = UFS_EXTATTR_MAGIC; - uef.uef_version = UFS_EXTATTR_VERSION; - uef.uef_size = atoi(argv[0]); - if (write(i, &uef, sizeof(uef)) == -1) - error = -1; - else if (fs_path) { - chunksize = sizeof(struct ufs_extattr_header) + - uef.uef_size; - zero_buf = (char *) (malloc(chunksize)); - if (zero_buf == NULL) { - perror("malloc"); - unlink(argv[1]); - return (-1); - } - memset(zero_buf, 0, chunksize); - num_inodes = num_inodes_by_path(fs_path); - for (loop = 0; loop < num_inodes; loop++) { - error = write(i, zero_buf, chunksize); - if (error != chunksize) { - perror("write"); - unlink(argv[1]); - return (-1); - } - } - } - } - if (i == -1) { + if ((i = open(argv[1], flags, 0600)) == -1) { /* unable to open file */ perror(argv[1]); return (-1); } + uef.uef_magic = UFS_EXTATTR_MAGIC; + uef.uef_version = UFS_EXTATTR_VERSION; + uef.uef_size = atoi(argv[0]); + if (write(i, &uef, sizeof(uef)) == -1) + error = -1; + else if (fs_path != NULL) { + easize = (sizeof uef + uef.uef_size) * + num_inodes_by_path(fs_path); + while (easize > 0) { + if (easize > sizeof zero_buf) + wlen = write(i, zero_buf, sizeof zero_buf); + else + wlen = write(i, zero_buf, easize); + if (wlen == -1) { + error = -1; + break; + } + easize -= wlen; + } + } if (error == -1) { perror(argv[1]); unlink(argv[1]); |