本文最后更新于2017年8月19日,已超过 1 年没有更新,如果文章内容失效,还请反馈给我,谢谢!







/* setflags.c - set the ext2 attributes for a set of files */
/* The first parameter to this program is a string consisting of
   0 (an empty string is okay) or more of the letters I, A, S, and
   N. This string specifies which ext2 attributes should be turned
   on for the files which are specified on the rest of the command
   line -- the rest of the attributes are turned off. The letters
   stand for immutable, append-only, sync, and nodump, respectively.
   For example, the command "setflags IN file1 file2" turns on the
   immutable and nodump flags for files file1 and file2, but turns
   off the sync and append-only flags for those files. */
#include <errno.h>
#include <fcntl.h>
#include <linux/ext2_fs.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char ** argv) {
    char ** filename = argv + 1;
    int fd;
    int old_flags = 0;
    /* make sure the flags to set were specified, along with
       some file names */
    if (argc < 3) {
        fprintf(stderr, "setflags usage: [I][A][S][N] <filenames>\n");
        return 1;
    printf("FS_IMMUTABLE_FL = 0x%08x, %d\n", FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
    printf("FS_APPEND_FL = 0x%08x, %d\n", FS_APPEND_FL, FS_APPEND_FL);
    printf("FS_SYNC_FL = 0x%08x, %d\n", FS_SYNC_FL, FS_SYNC_FL);
    printf("FS_NODUMP_FL = 0x%08x, %d\n", FS_NODUMP_FL, FS_NODUMP_FL);
    /* iterate over all of the file names in argv[] */
    while (*(++filename)) {
        /* Unlike normal attributes, ext2 attributes can only
         be set if we have a file descriptor (a file name isn't sufficient).
         We don't need write access to set the ext2 attributes, so O_RDONLY is fine. */
        fd = open(*filename, O_RDONLY);
        if (fd < 0) {
            fprintf(stderr, "cannot open %s: %s\n", *filename, strerror(errno));
        /* Sets the attributes as specified by the contents of flags. */
        if (ioctl(fd, FS_IOC_GETFLAGS, &old_flags) == -1) {
            fprintf(stderr, "ioctl failed on %s: %s\n", *filename, strerror(errno));
        else {
            printf("current attrs: 0x%08x\n", old_flags);
            // old_flags |= FS_IMMUTABLE_FL;
            // printf("\nold_flags |= FS_IMMUTABLE_FL >>> old_flags = 0x%08x\n", old_flags);
        if (strchr(argv[1], 'I')) old_flags |= FS_IMMUTABLE_FL;
        if (strchr(argv[1], 'A')) old_flags |= FS_APPEND_FL;
        if (strchr(argv[1], 'S')) old_flags |= FS_SYNC_FL;
        if (strchr(argv[1], 'N')) old_flags |= FS_NODUMP_FL;
        printf("\nold_flags = 0x%08x\n", old_flags);
        /* Sets the attributes as specified by the contents of flags. */
        if (ioctl(fd, FS_IOC_SETFLAGS, &old_flags) == -1) {
            fprintf(stderr, "ioctl failed on %s: %s\n", *filename, strerror(errno));
    return 0;



/usr/include/linux/ext2_fs.h: In function ‘ext2_mask_flags’:
/usr/include/linux/ext2_fs.h:182: error: ‘FS_DIRSYNC_FL’ undeclared (first use in this function)
/usr/include/linux/ext2_fs.h:182: error: (Each undeclared identifier is reported only once
/usr/include/linux/ext2_fs.h:182: error: for each function it appears in.)
/usr/include/linux/ext2_fs.h:182: error: ‘FS_TOPDIR_FL’ undeclared (first use in this function)
/usr/include/linux/ext2_fs.h:184: error: ‘FS_NODUMP_FL’ undeclared (first use in this function)
/usr/include/linux/ext2_fs.h:184: error: ‘FS_NOATIME_FL’ undeclared (first use in this function)


需要在「#include <linux/ext2_fs.h>」之前先引入「#include <linux/fs.h>」,有一个顺序关系!

问题二:执行「ioctl(fd, FS_IOC_SETFLAGS, &flags)」时报错「Operation not supported」
current flags: 0x00080000
desire flags = 0x00080010
ioctl(flags) = 0x00000010
ioctl failed on filename: Operation not supported


在语句「ioctl(fd, FS_IOC_SETFLAGS, &flags)」里面使用的flags变量的值不能是0和FS_IMMUTABLE_FL等变量的异或值,flags的初始值最好为文件原先的属性值(一般为524288,十六进制表示为0x00080000),再和需要设置的FS_IMMUTABLE_FL等变量进行异或,然后作为ioctl的参数才不会报错。

所以,推荐的解决办法就是先「ioctl(fd, FS_IOC_GETFLAGS, &old_flags)」,然后对old_flags进行异或,最后执行「ioctl(fd, FS_IOC_SETFLAGS, &old_flags)」。







声明: 除非注明,ixyzero.com文章均为原创,转载请以链接形式标明本文地址,谢谢!


电子邮件地址不会被公开。 必填项已用*标注