[GFS2] Update ioctl() to new interface
authorSteven Whitehouse <swhiteho@redhat.com>
Fri, 31 Mar 2006 20:01:28 +0000 (15:01 -0500)
committerSteven Whitehouse <swhiteho@redhat.com>
Fri, 31 Mar 2006 20:01:28 +0000 (15:01 -0500)
This is designed as a fs independent way to set flags on a
particular inode. The values of the ioctl() and flags are
designed to be identical to the ext2/3 values. Assuming that
this plan is acceptable to people in general, the plan is to
then move other fs across to using the same set of #defines,
etc.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
fs/gfs2/ops_file.c
include/linux/gfs2_ondisk.h
include/linux/iflags.h [new file with mode: 0644]

index ac8e1238cb6f7ce1254b96a63ffecdb49f0b606b..db4484a3efccc07add8751ce87911e8acf33525b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/ext2_fs.h>
 #include <linux/crc32.h>
+#include <linux/iflags.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -536,110 +537,44 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
        return error;
 }
 
-const struct gfs2_flag_eattr {
-       u32 flag;
-       u32 ext2;
-} gfs2_flag_eattrs[] = {
-       {
-               .flag = GFS2_DIF_IMMUTABLE,
-               .ext2 = EXT2_IMMUTABLE_FL,
-       }, {
-               .flag = GFS2_DIF_APPENDONLY,
-               .ext2 = EXT2_APPEND_FL,
-       }, {
-               .flag = GFS2_DIF_JDATA,
-               .ext2 = EXT2_JOURNAL_DATA_FL,
-       }, {
-               .flag = GFS2_DIF_EXHASH,
-               .ext2 = EXT2_INDEX_FL,
-       }, {
-               .flag = GFS2_DIF_EA_INDIRECT,
-       }, {
-               .flag = GFS2_DIF_DIRECTIO,
-       }, {
-               .flag = GFS2_DIF_NOATIME,
-               .ext2 = EXT2_NOATIME_FL,
-       }, {
-               .flag = GFS2_DIF_SYNC,
-               .ext2 = EXT2_SYNC_FL,
-       }, {
-               .flag = GFS2_DIF_SYSTEM,
-       }, {
-               .flag = GFS2_DIF_TRUNC_IN_PROG,
-       }, {
-               .flag = GFS2_DIF_INHERIT_JDATA,
-       }, {
-               .flag = GFS2_DIF_INHERIT_DIRECTIO,
-       }, {
-       },
+static const u32 iflags_to_gfs2[32] = {
+       [iflag_Sync] = GFS2_DIF_SYNC,
+       [iflag_Immutable] = GFS2_DIF_IMMUTABLE,
+       [iflag_Append] = GFS2_DIF_APPENDONLY,
+       [iflag_NoAtime] = GFS2_DIF_NOATIME,
+       [iflag_Index] = GFS2_DIF_EXHASH,
+       [iflag_JournalData] = GFS2_DIF_JDATA,
+       [iflag_DirectIO] = GFS2_DIF_DIRECTIO,
+       [iflag_InheritDirectIO] = GFS2_DIF_INHERIT_DIRECTIO,
+       [iflag_InheritJdata] = GFS2_DIF_INHERIT_JDATA,
 };
 
-static const struct gfs2_flag_eattr *get_by_ext2(u32 ext2)
-{
-       const struct gfs2_flag_eattr *p = gfs2_flag_eattrs;
-       for(; p->flag; p++) {
-               if (ext2 == p->ext2)
-                       return p;
-       }
-       return NULL;
-}
-
-static const struct gfs2_flag_eattr *get_by_gfs2(u32 gfs2)
-{
-       const struct gfs2_flag_eattr *p = gfs2_flag_eattrs;
-       for(; p->flag; p++) {
-               if (gfs2 == p->flag)
-                       return p;
-       }
-       return NULL;
-}
-
-static u32 gfs2_flags_to_ext2(u32 gfs2)
-{
-       const struct gfs2_flag_eattr *ea;
-       u32 ext2 = 0;
-       u32 mask = 1;
-
-       for(; mask != 0; mask <<=1) {
-               if (mask & gfs2) {
-                       ea = get_by_gfs2(mask);
-                       if (ea)
-                               ext2 |= ea->ext2;
-               }
-       }
-       return ext2;
-}
-
-static int gfs2_flags_from_ext2(u32 *gfs2, u32 ext2)
-{
-       const struct gfs2_flag_eattr *ea;
-       u32 mask = 1;
-
-       for(; mask != 0; mask <<= 1) {
-               if (mask & ext2) {
-                       ea = get_by_ext2(mask);
-                       if (ea == NULL)
-                               return -EINVAL;
-                       *gfs2 |= ea->flag;
-               }
-       }
-       return 0;
-}
+static const u32 gfs2_to_iflags[32] = {
+       [gfs2fl_Sync] = IFLAG_SYNC,
+       [gfs2fl_Immutable] = IFLAG_IMMUTABLE,
+       [gfs2fl_AppendOnly] = IFLAG_APPEND,
+       [gfs2fl_NoAtime] = IFLAG_NOATIME,
+       [gfs2fl_ExHash] = IFLAG_INDEX,
+       [gfs2fl_Jdata] = IFLAG_JOURNAL_DATA,
+       [gfs2fl_Directio] = IFLAG_DIRECTIO,
+       [gfs2fl_InheritDirectio] = IFLAG_INHERITDIRECTIO,
+       [gfs2fl_InheritJdata] = IFLAG_INHERITJDATA,
+};
 
-static int get_ext2_flags(struct inode *inode, u32 __user *ptr)
+static int gfs2_get_flags(struct inode *inode, u32 __user *ptr)
 {
        struct gfs2_inode *ip = inode->u.generic_ip;
        struct gfs2_holder gh;
        int error;
-       u32 ext2;
+       u32 iflags;
 
        gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
        error = gfs2_glock_nq_m_atime(1, &gh);
        if (error)
                return error;
 
-       ext2 = gfs2_flags_to_ext2(ip->i_di.di_flags);
-       if (put_user(ext2, ptr))
+       iflags = iflags_cvt(gfs2_to_iflags, ip->i_di.di_flags);
+       if (put_user(iflags, ptr))
                error = -EFAULT;
 
        gfs2_glock_dq_m(1, &gh);
@@ -665,7 +600,7 @@ static int get_ext2_flags(struct inode *inode, u32 __user *ptr)
  * @mask: Indicates which flags are valid
  *
  */
-static int gfs2_set_flags(struct inode *inode, u32 flags, u32 mask)
+static int do_gfs2_set_flags(struct inode *inode, u32 flags, u32 mask)
 {
        struct gfs2_inode *ip = inode->u.generic_ip;
        struct buffer_head *bh;
@@ -717,24 +652,23 @@ out:
        return error;
 }
 
-static int set_ext2_flags(struct inode *inode, u32 __user *ptr)
+static int gfs2_set_flags(struct inode *inode, u32 __user *ptr)
 {
-       u32 ext2, gfs2;
-       if (get_user(ext2, ptr))
+       u32 iflags, gfsflags;
+       if (get_user(iflags, ptr))
                return -EFAULT;
-       if (gfs2_flags_from_ext2(&gfs2, ext2))
-               return -EINVAL;
-       return gfs2_set_flags(inode, gfs2, ~0);
+       gfsflags = iflags_cvt(iflags_to_gfs2, iflags);
+       return do_gfs2_set_flags(inode, gfsflags, ~0);
 }
 
 int gfs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        switch(cmd) {
-       case EXT2_IOC_GETFLAGS:
-               return get_ext2_flags(inode, (u32 __user *)arg);
-       case EXT2_IOC_SETFLAGS:
-               return set_ext2_flags(inode, (u32 __user *)arg);
+       case IFLAGS_GET_IOC:
+               return gfs2_get_flags(inode, (u32 __user *)arg);
+       case IFLAGS_SET_IOC:
+               return gfs2_set_flags(inode, (u32 __user *)arg);
        }
        return -ENOTTY;
 }
index a5fb4f99aa454fcd35eb8520fe6b83115e0db9a7..3ab40917383f2ab716dd14cbac4c185a12fad3a5 100644 (file)
@@ -197,6 +197,22 @@ struct gfs2_quota {
 #define DT2IF(dt) (((dt) << 12) & S_IFMT)
 #define IF2DT(sif) (((sif) & S_IFMT) >> 12)
 
+enum {
+       gfs2fl_Jdata            = 0,
+       gfs2fl_ExHash           = 1,
+       gfs2fl_Unused           = 2,
+       gfs2fl_EaIndirect       = 3,
+       gfs2fl_Directio         = 4,
+       gfs2fl_Immutable        = 5,
+       gfs2fl_AppendOnly       = 6,
+       gfs2fl_NoAtime          = 7,
+       gfs2fl_Sync             = 8,
+       gfs2fl_System           = 9,
+       gfs2fl_TruncInProg      = 29,
+       gfs2fl_InheritDirectio  = 30,
+       gfs2fl_InheritJdata     = 31,
+};
+
 /* Dinode flags */
 #define GFS2_DIF_JDATA                 0x00000001
 #define GFS2_DIF_EXHASH                        0x00000002
diff --git a/include/linux/iflags.h b/include/linux/iflags.h
new file mode 100644 (file)
index 0000000..1b4d9ef
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef _LINUX_IFLAGS_H
+#define _LINUX_IFLAGS_H
+
+/*
+ * A universal set of inode flags.
+ *
+ * Originally taken from ext2/3 with additions for other filesystems.
+ * Filesystems supporting this interface should interoperate with
+ * the lsattr and chattr command line tools.
+ *
+ * This interface is supported in whole or in part by:
+ * ext2
+ * ext3
+ * xfs
+ * jfs
+ * gfs2
+ *
+ */
+
+#define IFLAGS_GET_IOC         _IOR('f', 1, long)
+#define IFLAGS_SET_IOC         _IOW('f', 2, long)
+
+/*
+ * These values are provided for use as indices of an array
+ * for use with the iflags_cvt function below
+ */
+enum {
+       iflag_SecureRm          = 0,    /* Secure deletion */
+       iflag_Unrm              = 1,    /* Undelete */
+       iflag_Compress          = 2,    /* Compress file */
+       iflag_Sync              = 3,    /* Synchronous updates */
+       iflag_Immutable = 4,    /* Immutable */
+       iflag_Append            = 5,    /* Append */
+       iflag_NoDump            = 6,    /* Don't dump file */
+       iflag_NoAtime           = 7,    /* No atime updates */
+       /* Reserved for compression usage */
+       iflag_Dirty             = 8,
+       iflag_ComprBlk          = 9,    /* One or more compressed clusters */
+       iflag_NoComp            = 10,   /* Don't compress */
+       iflag_Ecompr            = 11,   /* Compression error */
+       /* End of compression flags */
+       iflag_Btree             = 12,   /* btree format dir */
+       iflag_Index             = 12,   /* hash-indexed directory */
+       iflag_Imagic            = 13,   /* AFS directory */
+       iflag_JournalData       = 14,   /* file data should be journaled */
+       iflag_NoTail            = 15,   /* file tail should not be merged */
+       iflag_DirSync           = 16,   /* dirsync behaviour */
+       iflag_TopDir            = 17,   /* Top of directory hierarchies */
+       iflag_DirectIO          = 18,   /* Always use direct I/O on this file */
+       iflag_InheritDirectIO   = 19,   /* Set DirectIO on new files in dir */
+       iflag_InheritJdata      = 20,   /* Set JournalData on create in dir */
+       iflag_Reserved          = 31    /* reserved for ext2/3 lib */
+};
+
+#define __IFL(x) (1<<(iflag_##x))
+#define IFLAG_SECRM            __IFL(SecureRm)         /* 0x00000001 */
+#define IFLAG_UNRM             __IFL(Unrm)             /* 0x00000002 */
+#define IFLAG_COMPR            __IFL(Compr)            /* 0x00000004 */
+#define IFLAG_SYNC             __IFL(Sync)             /* 0x00000008 */
+#define IFLAG_IMMUTABLE                __IFL(Immutable)        /* 0x00000010 */
+#define IFLAG_APPEND           __IFL(Append)           /* 0x00000020 */
+#define IFLAG_NODUMP           __IFL(NoDump)           /* 0x00000040 */
+#define IFLAG_NOATIME          __IFL(NoAtime)          /* 0x00000080 */
+#define IFLAG_DIRTY            __IFL(Dirty)            /* 0x00000100 */
+#define IFLAG_COMPRBLK         __IFL(ComprBlk)         /* 0x00000200 */
+#define IFLAG_NOCOMP           __IFL(NoComp)           /* 0x00000400 */
+#define IFLAG_ECOMPR           __IFL(Ecompr)           /* 0x00000800 */
+#define IFLAG_BTREE            __IFL(Btree)            /* 0x00001000 */
+#define IFLAG_INDEX            __IFL(Index)            /* 0x00001000 */
+#define IFLAG_IMAGIC           __IFL(Imagic)           /* 0x00002000 */
+#define IFLAG_JOURNAL_DATA     __IFL(JournalData)      /* 0x00004000 */
+#define IFLAG_NOTAIL           __IFL(NoTail)           /* 0x00008000 */
+#define IFLAG_DIRSYNC          __IFL(DirSync)          /* 0x00010000 */
+#define IFLAG_TOPDIR           __IFL(TopDir)           /* 0x00020000 */
+#define IFLAG_DIRECTIO         __IFL(DirectIO)         /* 0x00040000 */
+#define IFLAG_INHERITDIRECTIO  __IFL(InheritDirectIO)  /* 0x00080000 */
+#define IFLAG_INHERITJDATA     __IFL(InheritJdata)     /* 0x00100000 */
+#define IFLAG_RESERVED         __IFL(Reserved)         /* 0x80000000 */
+
+#ifdef __KERNEL__
+/**
+ * iflags_cvt
+ * @table: A table of 32 u32 flags
+ * @val: a 32 bit value to convert
+ *
+ * This function can be used to convert between IFLAGS values and
+ * the filesystem's own flags values.
+ *
+ * Returns: the converted flags
+ */
+static inline u32 iflags_cvt(const u32 *table, u32 val)
+{
+       u32 res = 0;
+       while(val) {
+               if (val & 1)
+                       res |= *table;
+               table++;
+               val >>= 1;
+       }
+       return res;
+}
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_IFLAGS_H */