Skip to content

Instantly share code, notes, and snippets.

@ArtemGr
Created September 28, 2011 14:32
Show Gist options
  • Save ArtemGr/1248085 to your computer and use it in GitHub Desktop.
Save ArtemGr/1248085 to your computer and use it in GitHub Desktop.
testing btrfs FS_COMPR_FL and FS_NOCOMP_FL ioctl
// Usage: ioctlGetCompression {file}
// Install: g++ -O2 ioctlGetCompression.cc -o /usr/local/bin/ioctlGetCompression
// Discussion: http://thread.gmane.org/gmane.comp.file-systems.btrfs/13259
// See also: http://radudi.com/index.php/2011/08/31/using-btrfs-per-file-and-per-directory-compression/
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main (int argc, char** argv) {
if (argc <= 1) {fprintf (stderr, "Usage: ioctlGetCompression {file}\n"); return -1;}
const char* path = argv[1];
int fd = open (path, 0);
if (fd < 0) {fprintf (stderr, "open error: %i, %s\n", errno, strerror (errno)); return -1;}
unsigned int flags = 0;
if (ioctl (fd, FS_IOC_GETFLAGS, &flags) < 0) {
fprintf (stderr, "ioctl FS_IOC_GETFLAGS failed: %i, %s\n", errno, strerror (errno));
close (fd); return -1;
}
printf ("present flags (0x%X); compression on? %i; compression off? %i\n",
flags, (flags & FS_COMPR_FL) > 0, (flags & FS_NOCOMP_FL) > 0);
close (fd);
if (flags & FS_COMPR_FL) return 1;
if (flags & FS_NOCOMP_FL) return 2;
return 0;
}
// Usage: ioctlSetCompression {file} {-1|0|1}
// Install: g++ -O2 ioctlSetCompression.cc -o /usr/local/bin/ioctlSetCompression
// Discussion: http://thread.gmane.org/gmane.comp.file-systems.btrfs/13259
// Source: https://gist.github.com/1248085
// See also: http://radudi.com/index.php/2011/08/31/using-btrfs-per-file-and-per-directory-compression/
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main (int argc, char** argv) {
if (argc <= 2) {fprintf (stderr, "Usage: ioctlGetCompression {file} {-1|0|1}\n"); return -1;}
const char* path = argv[1];
int mode = atoi (argv[2]);
int fd = open (path, 0);
if (fd < 0) {fprintf (stderr, "open error: %i, %s\n", errno, strerror (errno)); return -1;}
unsigned int flags = 0;
if (ioctl (fd, FS_IOC_GETFLAGS, &flags) < 0) {
fprintf (stderr, "ioctl FS_IOC_GETFLAGS failed: %i, %s\n", errno, strerror (errno));
close (fd); return -1;
}
printf ("present flags (0x%X); compression on? %i; compression off? %i\n",
flags, (flags & FS_COMPR_FL) > 0, (flags & FS_NOCOMP_FL) > 0);
if (mode < 0) {
flags &= ~FS_COMPR_FL; flags |= FS_NOCOMP_FL;
} else if (mode == 0) {
flags &= ~FS_COMPR_FL; flags &= ~FS_NOCOMP_FL;
} else if (mode > 0) {
flags |= FS_COMPR_FL; flags &= ~FS_NOCOMP_FL;
}
if (ioctl (fd, FS_IOC_SETFLAGS, &flags)) {
fprintf (stderr, "ioctl FS_IOC_SETFLAGS failed: %i, %s\n", errno, strerror (errno));
close (fd); return -1;}
flags = 0;
if (ioctl (fd, FS_IOC_GETFLAGS, &flags) < 0) {
fprintf (stderr, "ioctl FS_IOC_GETFLAGS failed: %i, %s\n", errno, strerror (errno));
close (fd); return -1;
}
printf ("new flags (0x%X); compression on? %i; compression off? %i\n",
flags, (flags & FS_COMPR_FL) > 0, (flags & FS_NOCOMP_FL) > 0);
close (fd);
if (flags & FS_COMPR_FL) return 1;
if (flags & FS_NOCOMP_FL) return 2;
return 0;
}
// Usage: {file} {gibibytes} {compression: 1 or 0}
// Example: g++ -O2 ioctlTest.cc && ./a.out /mnt/ssd/no-compression-test 20 0
// Discussion: http://thread.gmane.org/gmane.comp.file-systems.btrfs/13259
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main (int argc, char** argv) {
const char* path = argc > 1 ? argv[1] : "/mnt/ssd/no-compression-test";
int64_t maxSize = argc > 2 ? atoi (argv[2]) : 9999;
bool compression = argc > 3 ? atoi (argv[3]) : false;
printf ("filling %s up to %lli GiB\n", path, maxSize);
int fd = open (path, O_CREAT | O_RDWR | O_TRUNC);
if (fd < 0) {printf ("open error: %i, %s\n", errno, strerror (errno)); return 1;}
unsigned int flags = 0;
if (ioctl (fd, FS_IOC_GETFLAGS, &flags) < 0) {
printf ("ioctl FS_IOC_GETFLAGS failed: %i, %s\n", errno, strerror (errno));
close (fd); return 1;
}
printf ("present flags (0x%X); compression on? %i; compression off? %i\n", flags, (flags & FS_COMPR_FL) > 0, (flags & FS_NOCOMP_FL) > 0);
printf ("ioctl: setting compression = %s\n", compression ? "on" : "off");
if (compression) {
flags |= FS_COMPR_FL;
flags &= ~FS_NOCOMP_FL;
} else {
flags &= ~FS_COMPR_FL;
flags |= FS_NOCOMP_FL;
}
int ret = ioctl (fd, FS_IOC_SETFLAGS, &flags);
if (ret) {printf ("ioctl error: %i, %s\n", errno, strerror (errno)); close (fd); return 1;}
const int len = 1024; char buf[len];
buf[len/2] = 1; // some data to be safe and avoid "sparce file" compression.
for (int64_t size = 0, count = 0;;) {
ssize_t wret = write (fd, buf, len);
if (wret != len) {
printf ("error writing %i bytes\n", len);
if (wret == -1) printf ("errno %i, %s\n", errno, strerror (errno));
printf ("size: %lli\n", size);
close (fd); return 1;
} else {
size += wret;
++count;
if (count % (1024 * 1024) == 0) printf ("size: %lli (%lli GiB)\n", size, size / 1024 / 1024 / 1024);
if (maxSize != -1 && size >= maxSize * 1024 * 1024 * 1024) {
printf ("target size reached!\n");
break;
}
}
}
close (fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment