On Wed, Nov 09, 2011 at 10:01:13AM +0900, dima wrote: > Just for the record - I could find a solution thanks to the btrfs wiki > being online again. In Gotchas it says > > mount -o nodatacow also disables compression > > and indeed it does. Remounting with this option and re-saving the file > makes it uncompressed. However, I could not find how to remount the > filesystem afterwards without nodatacow.
I saw this mentioned on irc today (that nodatacow diasables compression). There is a way how to turn off compression on a file -- with help of the NOCOW _file_ attribute, ie. you don't have to remount. * create the file, compression enabled * set NOCOW (with the attached single-purpose nocow.c utility) * btrfs fi defrag the_file Make sure you have enough free space for the uncompressed file size. You can compare the extent layout before and after the defrag with "filefrag -v" . I did a test first, here's what I saw with a ~60M file (filled with zeros, suitable for compression): # filefrag -v zerofile2 Filesystem type is: 9123683e File size of zerofile2 is 69927424 (17073 blocks, blocksize 4096) ext logical physical expected length flags 0 0 2700 32 1 32 2942 2731 32 2 64 2943 2973 32 3 96 2944 2974 32 4 128 2945 2975 32 ... 533 17039 2641 2671 32 534 17071 2643 2672 2 eof zerofile2: 535 extents found # btrfs fi defrag zerofile2 # filefrag -v zerofile2 Filesystem type is: 9123683e File size of zerofile2 is 69927424 (17073 blocks, blocksize 4096) ext logical physical expected length flags 0 0 20992 2107 1 2107 23552 23098 1581 2 3688 16400 25132 1185 3 4873 12410 17584 889 4 5762 14762 13298 667 5 6429 15881 15428 500 6 6929 17585 16380 751 7 7680 23099 18335 375 8 8055 25133 23473 376 9 8431 3072 25508 2160 10 10591 5632 5231 1620 11 12211 8192 7251 2431 12 14642 18432 10622 2431 eof zerofile2: 13 extents found david
#include <fcntl.h> #include <stdlib.h> #include <sys/ioctl.h> #include <string.h> #include <linux/types.h> #include <stdio.h> #include <errno.h> #ifndef FS_IOC_SETFLAGS #define FS_IOC_SETFLAGS _IOW('f', 2, long) #warning defining SETFLAGS locally #endif #ifndef FS_IOC_GETFLAGS #define FS_IOC_GETFLAGS _IOR('f', 1, long) #warning defining GETFLAGS locally #endif #ifndef FS_NOCOW_FL #define FS_NOCOW_FL 0x00800000 /* Do not cow file */ #endif int main(int argc, char **argv) { int fd; int r; long flags; if (argc < 2) { printf("usage: %s file\n", argv[0]); exit(1); } fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("open()"); return 1; } printf("GETFLAGS ioctl 0x%x\n", FS_IOC_GETFLAGS); printf("SETFLAGS ioctl 0x%x\n", FS_IOC_SETFLAGS); r = ioctl(fd, FS_IOC_GETFLAGS, &flags); if (r == -1) { perror("ioctl(GETFLAGS)"); return 1; } else { printf("file flags: 0x%lx\n", flags); } printf("Set NOCOW flag for %s\n", argv[1]); flags |= FS_NOCOW_FL; r = ioctl(fd, FS_IOC_SETFLAGS, &flags); printf("ioctl returned: %d\n", r); if (r == -1) { perror("ioctl()"); return 1; } return 0; }