aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/ops_file.c138
-rw-r--r--include/linux/gfs2_ondisk.h16
-rw-r--r--include/linux/iflags.h104
3 files changed, 156 insertions, 102 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index ac8e1238cb6f..db4484a3efcc 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -21,6 +21,7 @@
21#include <linux/gfs2_ondisk.h> 21#include <linux/gfs2_ondisk.h>
22#include <linux/ext2_fs.h> 22#include <linux/ext2_fs.h>
23#include <linux/crc32.h> 23#include <linux/crc32.h>
24#include <linux/iflags.h>
24#include <asm/semaphore.h> 25#include <asm/semaphore.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26 27
@@ -536,110 +537,44 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
536 return error; 537 return error;
537} 538}
538 539
539const struct gfs2_flag_eattr { 540static const u32 iflags_to_gfs2[32] = {
540 u32 flag; 541 [iflag_Sync] = GFS2_DIF_SYNC,
541 u32 ext2; 542 [iflag_Immutable] = GFS2_DIF_IMMUTABLE,
542} gfs2_flag_eattrs[] = { 543 [iflag_Append] = GFS2_DIF_APPENDONLY,
543 { 544 [iflag_NoAtime] = GFS2_DIF_NOATIME,
544 .flag = GFS2_DIF_IMMUTABLE, 545 [iflag_Index] = GFS2_DIF_EXHASH,
545 .ext2 = EXT2_IMMUTABLE_FL, 546 [iflag_JournalData] = GFS2_DIF_JDATA,
546 }, { 547 [iflag_DirectIO] = GFS2_DIF_DIRECTIO,
547 .flag = GFS2_DIF_APPENDONLY, 548 [iflag_InheritDirectIO] = GFS2_DIF_INHERIT_DIRECTIO,
548 .ext2 = EXT2_APPEND_FL, 549 [iflag_InheritJdata] = GFS2_DIF_INHERIT_JDATA,
549 }, {
550 .flag = GFS2_DIF_JDATA,
551 .ext2 = EXT2_JOURNAL_DATA_FL,
552 }, {
553 .flag = GFS2_DIF_EXHASH,
554 .ext2 = EXT2_INDEX_FL,
555 }, {
556 .flag = GFS2_DIF_EA_INDIRECT,
557 }, {
558 .flag = GFS2_DIF_DIRECTIO,
559 }, {
560 .flag = GFS2_DIF_NOATIME,
561 .ext2 = EXT2_NOATIME_FL,
562 }, {
563 .flag = GFS2_DIF_SYNC,
564 .ext2 = EXT2_SYNC_FL,
565 }, {
566 .flag = GFS2_DIF_SYSTEM,
567 }, {
568 .flag = GFS2_DIF_TRUNC_IN_PROG,
569 }, {
570 .flag = GFS2_DIF_INHERIT_JDATA,
571 }, {
572 .flag = GFS2_DIF_INHERIT_DIRECTIO,
573 }, {
574 },
575}; 550};
576 551
577static const struct gfs2_flag_eattr *get_by_ext2(u32 ext2) 552static const u32 gfs2_to_iflags[32] = {
578{ 553 [gfs2fl_Sync] = IFLAG_SYNC,
579 const struct gfs2_flag_eattr *p = gfs2_flag_eattrs; 554 [gfs2fl_Immutable] = IFLAG_IMMUTABLE,
580 for(; p->flag; p++) { 555 [gfs2fl_AppendOnly] = IFLAG_APPEND,
581 if (ext2 == p->ext2) 556 [gfs2fl_NoAtime] = IFLAG_NOATIME,
582 return p; 557 [gfs2fl_ExHash] = IFLAG_INDEX,
583 } 558 [gfs2fl_Jdata] = IFLAG_JOURNAL_DATA,
584 return NULL; 559 [gfs2fl_Directio] = IFLAG_DIRECTIO,
585} 560 [gfs2fl_InheritDirectio] = IFLAG_INHERITDIRECTIO,
586 561 [gfs2fl_InheritJdata] = IFLAG_INHERITJDATA,
587static const struct gfs2_flag_eattr *get_by_gfs2(u32 gfs2) 562};
588{
589 const struct gfs2_flag_eattr *p = gfs2_flag_eattrs;
590 for(; p->flag; p++) {
591 if (gfs2 == p->flag)
592 return p;
593 }
594 return NULL;
595}
596
597static u32 gfs2_flags_to_ext2(u32 gfs2)
598{
599 const struct gfs2_flag_eattr *ea;
600 u32 ext2 = 0;
601 u32 mask = 1;
602
603 for(; mask != 0; mask <<=1) {
604 if (mask & gfs2) {
605 ea = get_by_gfs2(mask);
606 if (ea)
607 ext2 |= ea->ext2;
608 }
609 }
610 return ext2;
611}
612
613static int gfs2_flags_from_ext2(u32 *gfs2, u32 ext2)
614{
615 const struct gfs2_flag_eattr *ea;
616 u32 mask = 1;
617
618 for(; mask != 0; mask <<= 1) {
619 if (mask & ext2) {
620 ea = get_by_ext2(mask);
621 if (ea == NULL)
622 return -EINVAL;
623 *gfs2 |= ea->flag;
624 }
625 }
626 return 0;
627}
628 563
629static int get_ext2_flags(struct inode *inode, u32 __user *ptr) 564static int gfs2_get_flags(struct inode *inode, u32 __user *ptr)
630{ 565{
631 struct gfs2_inode *ip = inode->u.generic_ip; 566 struct gfs2_inode *ip = inode->u.generic_ip;
632 struct gfs2_holder gh; 567 struct gfs2_holder gh;
633 int error; 568 int error;
634 u32 ext2; 569 u32 iflags;
635 570
636 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); 571 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
637 error = gfs2_glock_nq_m_atime(1, &gh); 572 error = gfs2_glock_nq_m_atime(1, &gh);
638 if (error) 573 if (error)
639 return error; 574 return error;
640 575
641 ext2 = gfs2_flags_to_ext2(ip->i_di.di_flags); 576 iflags = iflags_cvt(gfs2_to_iflags, ip->i_di.di_flags);
642 if (put_user(ext2, ptr)) 577 if (put_user(iflags, ptr))
643 error = -EFAULT; 578 error = -EFAULT;
644 579
645 gfs2_glock_dq_m(1, &gh); 580 gfs2_glock_dq_m(1, &gh);
@@ -665,7 +600,7 @@ static int get_ext2_flags(struct inode *inode, u32 __user *ptr)
665 * @mask: Indicates which flags are valid 600 * @mask: Indicates which flags are valid
666 * 601 *
667 */ 602 */
668static int gfs2_set_flags(struct inode *inode, u32 flags, u32 mask) 603static int do_gfs2_set_flags(struct inode *inode, u32 flags, u32 mask)
669{ 604{
670 struct gfs2_inode *ip = inode->u.generic_ip; 605 struct gfs2_inode *ip = inode->u.generic_ip;
671 struct buffer_head *bh; 606 struct buffer_head *bh;
@@ -717,24 +652,23 @@ out:
717 return error; 652 return error;
718} 653}
719 654
720static int set_ext2_flags(struct inode *inode, u32 __user *ptr) 655static int gfs2_set_flags(struct inode *inode, u32 __user *ptr)
721{ 656{
722 u32 ext2, gfs2; 657 u32 iflags, gfsflags;
723 if (get_user(ext2, ptr)) 658 if (get_user(iflags, ptr))
724 return -EFAULT; 659 return -EFAULT;
725 if (gfs2_flags_from_ext2(&gfs2, ext2)) 660 gfsflags = iflags_cvt(iflags_to_gfs2, iflags);
726 return -EINVAL; 661 return do_gfs2_set_flags(inode, gfsflags, ~0);
727 return gfs2_set_flags(inode, gfs2, ~0);
728} 662}
729 663
730int gfs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 664int gfs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
731 unsigned long arg) 665 unsigned long arg)
732{ 666{
733 switch(cmd) { 667 switch(cmd) {
734 case EXT2_IOC_GETFLAGS: 668 case IFLAGS_GET_IOC:
735 return get_ext2_flags(inode, (u32 __user *)arg); 669 return gfs2_get_flags(inode, (u32 __user *)arg);
736 case EXT2_IOC_SETFLAGS: 670 case IFLAGS_SET_IOC:
737 return set_ext2_flags(inode, (u32 __user *)arg); 671 return gfs2_set_flags(inode, (u32 __user *)arg);
738 } 672 }
739 return -ENOTTY; 673 return -ENOTTY;
740} 674}
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index a5fb4f99aa45..3ab40917383f 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -197,6 +197,22 @@ struct gfs2_quota {
197#define DT2IF(dt) (((dt) << 12) & S_IFMT) 197#define DT2IF(dt) (((dt) << 12) & S_IFMT)
198#define IF2DT(sif) (((sif) & S_IFMT) >> 12) 198#define IF2DT(sif) (((sif) & S_IFMT) >> 12)
199 199
200enum {
201 gfs2fl_Jdata = 0,
202 gfs2fl_ExHash = 1,
203 gfs2fl_Unused = 2,
204 gfs2fl_EaIndirect = 3,
205 gfs2fl_Directio = 4,
206 gfs2fl_Immutable = 5,
207 gfs2fl_AppendOnly = 6,
208 gfs2fl_NoAtime = 7,
209 gfs2fl_Sync = 8,
210 gfs2fl_System = 9,
211 gfs2fl_TruncInProg = 29,
212 gfs2fl_InheritDirectio = 30,
213 gfs2fl_InheritJdata = 31,
214};
215
200/* Dinode flags */ 216/* Dinode flags */
201#define GFS2_DIF_JDATA 0x00000001 217#define GFS2_DIF_JDATA 0x00000001
202#define GFS2_DIF_EXHASH 0x00000002 218#define GFS2_DIF_EXHASH 0x00000002
diff --git a/include/linux/iflags.h b/include/linux/iflags.h
new file mode 100644
index 000000000000..1b4d9ef5d62b
--- /dev/null
+++ b/include/linux/iflags.h
@@ -0,0 +1,104 @@
1#ifndef _LINUX_IFLAGS_H
2#define _LINUX_IFLAGS_H
3
4/*
5 * A universal set of inode flags.
6 *
7 * Originally taken from ext2/3 with additions for other filesystems.
8 * Filesystems supporting this interface should interoperate with
9 * the lsattr and chattr command line tools.
10 *
11 * This interface is supported in whole or in part by:
12 * ext2
13 * ext3
14 * xfs
15 * jfs
16 * gfs2
17 *
18 */
19
20#define IFLAGS_GET_IOC _IOR('f', 1, long)
21#define IFLAGS_SET_IOC _IOW('f', 2, long)
22
23/*
24 * These values are provided for use as indices of an array
25 * for use with the iflags_cvt function below
26 */
27enum {
28 iflag_SecureRm = 0, /* Secure deletion */
29 iflag_Unrm = 1, /* Undelete */
30 iflag_Compress = 2, /* Compress file */
31 iflag_Sync = 3, /* Synchronous updates */
32 iflag_Immutable = 4, /* Immutable */
33 iflag_Append = 5, /* Append */
34 iflag_NoDump = 6, /* Don't dump file */
35 iflag_NoAtime = 7, /* No atime updates */
36 /* Reserved for compression usage */
37 iflag_Dirty = 8,
38 iflag_ComprBlk = 9, /* One or more compressed clusters */
39 iflag_NoComp = 10, /* Don't compress */
40 iflag_Ecompr = 11, /* Compression error */
41 /* End of compression flags */
42 iflag_Btree = 12, /* btree format dir */
43 iflag_Index = 12, /* hash-indexed directory */
44 iflag_Imagic = 13, /* AFS directory */
45 iflag_JournalData = 14, /* file data should be journaled */
46 iflag_NoTail = 15, /* file tail should not be merged */
47 iflag_DirSync = 16, /* dirsync behaviour */
48 iflag_TopDir = 17, /* Top of directory hierarchies */
49 iflag_DirectIO = 18, /* Always use direct I/O on this file */
50 iflag_InheritDirectIO = 19, /* Set DirectIO on new files in dir */
51 iflag_InheritJdata = 20, /* Set JournalData on create in dir */
52 iflag_Reserved = 31 /* reserved for ext2/3 lib */
53};
54
55#define __IFL(x) (1<<(iflag_##x))
56#define IFLAG_SECRM __IFL(SecureRm) /* 0x00000001 */
57#define IFLAG_UNRM __IFL(Unrm) /* 0x00000002 */
58#define IFLAG_COMPR __IFL(Compr) /* 0x00000004 */
59#define IFLAG_SYNC __IFL(Sync) /* 0x00000008 */
60#define IFLAG_IMMUTABLE __IFL(Immutable) /* 0x00000010 */
61#define IFLAG_APPEND __IFL(Append) /* 0x00000020 */
62#define IFLAG_NODUMP __IFL(NoDump) /* 0x00000040 */
63#define IFLAG_NOATIME __IFL(NoAtime) /* 0x00000080 */
64#define IFLAG_DIRTY __IFL(Dirty) /* 0x00000100 */
65#define IFLAG_COMPRBLK __IFL(ComprBlk) /* 0x00000200 */
66#define IFLAG_NOCOMP __IFL(NoComp) /* 0x00000400 */
67#define IFLAG_ECOMPR __IFL(Ecompr) /* 0x00000800 */
68#define IFLAG_BTREE __IFL(Btree) /* 0x00001000 */
69#define IFLAG_INDEX __IFL(Index) /* 0x00001000 */
70#define IFLAG_IMAGIC __IFL(Imagic) /* 0x00002000 */
71#define IFLAG_JOURNAL_DATA __IFL(JournalData) /* 0x00004000 */
72#define IFLAG_NOTAIL __IFL(NoTail) /* 0x00008000 */
73#define IFLAG_DIRSYNC __IFL(DirSync) /* 0x00010000 */
74#define IFLAG_TOPDIR __IFL(TopDir) /* 0x00020000 */
75#define IFLAG_DIRECTIO __IFL(DirectIO) /* 0x00040000 */
76#define IFLAG_INHERITDIRECTIO __IFL(InheritDirectIO) /* 0x00080000 */
77#define IFLAG_INHERITJDATA __IFL(InheritJdata) /* 0x00100000 */
78#define IFLAG_RESERVED __IFL(Reserved) /* 0x80000000 */
79
80#ifdef __KERNEL__
81/**
82 * iflags_cvt
83 * @table: A table of 32 u32 flags
84 * @val: a 32 bit value to convert
85 *
86 * This function can be used to convert between IFLAGS values and
87 * the filesystem's own flags values.
88 *
89 * Returns: the converted flags
90 */
91static inline u32 iflags_cvt(const u32 *table, u32 val)
92{
93 u32 res = 0;
94 while(val) {
95 if (val & 1)
96 res |= *table;
97 table++;
98 val >>= 1;
99 }
100 return res;
101}
102#endif /* __KERNEL__ */
103
104#endif /* _LINUX_IFLAGS_H */