[PATCH 07/11] xfstests: randholes: use posix_memalign()
Alex Elder
aelder at sgi.com
Thu Oct 14 09:50:36 CDT 2010
Use posix_memalign() rather than memalign() regardless of whether
direct I/O is to be used. Don't store the dioattr data in a global
variable.
Signed-off-by: Alex Elder <aelder at sgi.com>
---
src/randholes.c | 71 +++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 47 insertions(+), 24 deletions(-)
Index: b/src/randholes.c
===================================================================
--- a/src/randholes.c
+++ b/src/randholes.c
@@ -25,6 +25,7 @@ int nvalid; /* number of bytes in valid
#define SETBIT(ARRAY, N) ((ARRAY)[(N)/8] |= (1 << ((N)%8)))
#define BITVAL(ARRAY, N) ((ARRAY)[(N)/8] & (1 << ((N)%8)))
+#define power_of_2(x) ((x) && !((x) & ((x) - 1)))
#define DEFAULT_FILESIZE ((__uint64_t) (256 * 1024 * 1024))
#define DEFAULT_BLOCKSIZE 512
@@ -41,7 +42,7 @@ int extsize; /* used only for real-time
int preserve;
int test;
__uint64_t fileoffset;
-struct dioattr diob;
+
struct fsxattr rtattr;
#define READ_XFER 10 /* block to read at a time when checking */
@@ -115,7 +116,7 @@ dumpblock(int *buffer, __uint64_t offset
}
void
-writeblks(char *fname, int fd)
+writeblks(char *fname, int fd, size_t alignment)
{
__uint64_t offset;
char *buffer;
@@ -125,11 +126,7 @@ writeblks(char *fname, int fd)
if (test)
buffer = NULL;
else {
- if (direct)
- buffer = memalign(diob.d_mem, blocksize);
- else
- buffer = malloc(blocksize);
- if (buffer == NULL) {
+ if (posix_memalign((void **) &buffer, alignment, blocksize)) {
perror("malloc");
exit(1);
}
@@ -192,7 +189,7 @@ writeblks(char *fname, int fd)
}
int
-readblks(int fd)
+readblks(int fd, size_t alignment)
{
unsigned long offset;
char *buffer, *tmp;
@@ -202,11 +199,7 @@ readblks(int fd)
if (alloconly)
return 0;
xfer = READ_XFER*blocksize;
- if (direct)
- buffer = memalign(diob.d_mem, xfer);
- else
- buffer = malloc(xfer);
- if (buffer == NULL) {
+ if (posix_memalign((void **) &buffer, alignment, xfer)) {
perror("malloc");
exit(1);
}
@@ -270,20 +263,48 @@ readblks(int fd)
return err;
}
-int
-direct_setup(char *filename, int fd)
+/*
+ * Determine the memory alignment required for I/O buffers. For
+ * direct I/O we request the needed information from the file
+ * system; otherwise pointer alignment is fine. Returns the
+ * alignment multiple, or 0 if an error occurs.
+ */
+size_t
+get_alignment(char *filename, int fd)
{
- if (xfscntl(filename, fd, DIOINFO, &diob) < 0) {
+ struct dioattr dioattr;
+
+ if (! direct)
+ return sizeof (void *);
+
+ memset(&dioattr, 0, sizeof dioattr);
+ if (xfscntl(filename, fd, DIOINFO, &dioattr) < 0) {
perror("xfscntl(FIOINFO)");
- return 1;
+ return 0;
+ }
+
+ /* Make sure the alignment meets the needs of posix_memalign() */
+
+ if (dioattr.d_mem % sizeof (void *) || ! power_of_2(dioattr.d_mem)) {
+ perror("d_mem bad");
+ return 0;
+ }
+
+ /*
+ * Also make sure user doesn't specify a block size that's
+ * incompatible with the underlying file system.
+ */
+ if (! dioattr.d_miniosz) {
+ perror("miniosz == 0!");
+ return 0;
}
- if (blocksize % diob.d_miniosz) {
+ if (blocksize % dioattr.d_miniosz) {
fprintf(stderr, "blocksize %d must be a multiple of "
- "%d for direct I/O\n", blocksize, diob.d_miniosz);
- return 1;
+ "%d for direct I/O\n", blocksize, dioattr.d_miniosz);
+ return 0;
}
- return 0;
+ return (size_t) dioattr.d_mem;
}
int
@@ -292,6 +313,7 @@ main(int argc, char *argv[])
int seed, ch, fd, oflags;
char *filename = NULL;
int r;
+ size_t alignment;
filesize = DEFAULT_FILESIZE;
blocksize = DEFAULT_BLOCKSIZE;
@@ -390,13 +412,14 @@ main(int argc, char *argv[])
}
}
- if (direct && direct_setup(filename, fd))
+ alignment = get_alignment(filename, fd);
+ if (! alignment)
return 1;
printf(test?"write (skipped)\n":"write\n");
- writeblks(filename, fd);
+ writeblks(filename, fd, alignment);
printf("readback\n");
- r=readblks(fd);
+ r = readblks(fd, alignment);
if (close(fd) < 0) {
perror("close");
return 1;
More information about the xfs
mailing list