Hi Dave!

sorry for following up on my own email instead
of your reply, but I'm not subscribed to the
jfs mailing list, and the archive does not contain
(or show?) headers so that I could 'fake' a reply

anyway, here are some thoughts about the attributes
and a patch to look at ...


ext2 inode attributes with relevance for jfs:

'a'     EXT2_APPEND_FL       -> append only             
'i'     EXT2_IMMUTABLE_FL    -> immutable file   
's'     EXT2_SECRM_FL        -> zero file           
'u'     EXT2_UNRM_FL         -> allow for unrm           
'A'     EXT2_NOATIME_FL      -> no access time
'D'     EXT2_DIRSYNC_FL      -> dirsync          
'S'     EXT2_SYNC_FL         -> sync

overview of jfs flags (partially for OS/2)


value      (OS/2)       Linux   ext2 attrs
------------------------------------------------
0x00010000 IFJOURNAL    -
0x00020000 ISPARSE      used
0x00040000 INLINEEA     used
0x00080000 -            -       JFS_NOATIME_FL 

0x00100000 -            -       JFS_DIRSYNC_FL
0x00200000 -            -       JFS_SYNC_FL
0x00400000 -            -       JFS_SECRM_FL
0x00800000 ISWAPFILE    -       JFS_UNRM_FL

0x01000000 -            -       JFS_APPEND_FL
0x02000000 IREADONLY    -       JFS_IMMUTABLE_FL
0x04000000 IHIDDEN      -       -
0x08000000 ISYSTEM      -       -

0x10000000 -            -
0x20000000 IDIRECTORY   used
0x40000000 IARCHIVE     -
0x80000000 INEWNAME     -


the implementation is straight forward, except
for the fact that the attributes have to be mapped
to match with the ext2 ones to avoid a separate
tool for manipulating them (this could be avoided
when using a separate flag field in the on-disk
representation, but the overhead is minimal)

a special jfs_ioctl is added to allow for the new
JFS_IOC_GETFLAGS and JFS_IOC_SETFLAGS calls.

a helper function jfs_set_inode_flags() to transfer
the flags from the on-disk version to the inode

minor changes to allow flag inheritance on inode
creation, as well as a cleanup of the on-disk
flags (including the new ones)

beforementioned helper to map between ext2 and jfs
versions of the new flags ...

the JFS_SECRM_FL and JFS_UNRM_FL are not done yet
and I'm not 100% sure they are worth the efford,
the rest seems to work out of the box ...

please let me know what you think

TIA,
Herbert


Signed-off-by: Herbert Pƶtzl <[EMAIL PROTECTED]>

diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/Makefile 
linux-2.6.16-rc1-jfs/fs/jfs/Makefile
--- linux-2.6.16-rc1/fs/jfs/Makefile    2004-08-14 12:56:09 +0200
+++ linux-2.6.16-rc1-jfs/fs/jfs/Makefile        2006-02-01 09:51:16 +0100
@@ -8,7 +8,8 @@ jfs-y    := super.o file.o inode.o namei
            jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
            jfs_unicode.o jfs_dtree.o jfs_inode.o \
            jfs_extent.o symlink.o jfs_metapage.o \
-           jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o resize.o xattr.o
+           jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o \
+           resize.o xattr.o ioctl.o
 
 jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o
 
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/file.c 
linux-2.6.16-rc1-jfs/fs/jfs/file.c
--- linux-2.6.16-rc1/fs/jfs/file.c      2005-08-29 22:25:31 +0200
+++ linux-2.6.16-rc1-jfs/fs/jfs/file.c  2006-02-01 09:51:16 +0100
@@ -113,4 +113,5 @@ struct file_operations jfs_file_operatio
        .sendfile       = generic_file_sendfile,
        .fsync          = jfs_fsync,
        .release        = jfs_release,
+       .ioctl          = jfs_ioctl,
 };
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/inode.c 
linux-2.6.16-rc1-jfs/fs/jfs/inode.c
--- linux-2.6.16-rc1/fs/jfs/inode.c     2005-10-28 20:49:44 +0200
+++ linux-2.6.16-rc1-jfs/fs/jfs/inode.c 2006-02-01 09:51:16 +0100
@@ -55,6 +55,7 @@ void jfs_read_inode(struct inode *inode)
                inode->i_op = &jfs_file_inode_operations;
                init_special_inode(inode, inode->i_mode, inode->i_rdev);
        }
+       jfs_set_inode_flags(inode);
 }
 
 /*
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/ioctl.c 
linux-2.6.16-rc1-jfs/fs/jfs/ioctl.c
--- linux-2.6.16-rc1/fs/jfs/ioctl.c     1970-01-01 01:00:00 +0100
+++ linux-2.6.16-rc1-jfs/fs/jfs/ioctl.c 2006-02-01 10:05:07 +0100
@@ -0,0 +1,107 @@
+/*
+ * linux/fs/jfs/ioctl.c
+ *
+ * Copyright (C) 2006 Herbert Poetzl
+ * adapted from Remy Card's ext2/ioctl.c
+ */
+
+#include <linux/fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/ctype.h>
+#include <linux/capability.h>
+#include <linux/time.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+
+#include "jfs_incore.h"
+#include "jfs_dinode.h"
+#include "jfs_inode.h"
+
+
+static struct {
+       long jfs_flag;
+       long ext2_flag;
+} jfs_map[] = {
+       {JFS_NOATIME_FL, EXT2_NOATIME_FL},
+       {JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL},
+       {JFS_SYNC_FL, EXT2_SYNC_FL},
+       {JFS_SECRM_FL, EXT2_SECRM_FL},
+       {JFS_UNRM_FL, EXT2_UNRM_FL},
+       {JFS_APPEND_FL, EXT2_APPEND_FL},
+       {JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL},
+       {0, 0},
+};
+
+static long jfs_map_ext2(unsigned long flags, int from)
+{
+       int index=0;
+       long mapped=0;
+
+       while (jfs_map[index].jfs_flag) {
+               if (from) {
+                       if (jfs_map[index].ext2_flag & flags)
+                               mapped |= jfs_map[index].jfs_flag;
+               } else {
+                       if (jfs_map[index].jfs_flag & flags)
+                               mapped |= jfs_map[index].ext2_flag;
+               }
+               index++;
+       }
+       return mapped;
+}
+
+
+int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
+               unsigned long arg)
+{
+       struct jfs_inode_info *jfs_inode = JFS_IP(inode);
+       unsigned int flags;
+
+       switch (cmd) {
+       case JFS_IOC_GETFLAGS:
+               flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
+               flags = jfs_map_ext2(flags, 0);
+               return put_user(flags, (int __user *) arg);
+       case JFS_IOC_SETFLAGS: {
+               unsigned int oldflags;
+
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EACCES;
+
+               if (get_user(flags, (int __user *) arg))
+                       return -EFAULT;
+
+               flags = jfs_map_ext2(flags, 1);
+               if (!S_ISDIR(inode->i_mode))
+                       flags &= ~JFS_DIRSYNC_FL;
+
+               oldflags = jfs_inode->mode2;
+
+               /*
+                * The IMMUTABLE and APPEND_ONLY flags can only be changed by
+                * the relevant capability.
+                */
+               if ((oldflags & JFS_IMMUTABLE_FL) ||
+                       ((flags ^ oldflags) &
+                       (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
+                       if (!capable(CAP_LINUX_IMMUTABLE))
+                               return -EPERM;
+               }
+
+               flags = flags & JFS_FL_USER_MODIFIABLE;
+               flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
+               jfs_inode->mode2 = flags;
+
+               jfs_set_inode_flags(inode);
+               inode->i_ctime = CURRENT_TIME_SEC;
+               mark_inode_dirty(inode);
+               return 0;
+       }
+       default:
+               return -ENOTTY;
+       }
+}
+
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/jfs_dinode.h 
linux-2.6.16-rc1-jfs/fs/jfs/jfs_dinode.h
--- linux-2.6.16-rc1/fs/jfs/jfs_dinode.h        2004-12-25 01:55:20 +0100
+++ linux-2.6.16-rc1-jfs/fs/jfs/jfs_dinode.h    2006-02-01 09:51:16 +0100
@@ -139,13 +139,36 @@ struct dinode {
 
 /* more extended mode bits: attributes for OS/2 */
 #define IREADONLY      0x02000000      /* no write access to file */
-#define IARCHIVE       0x40000000      /* file archive bit */
-#define ISYSTEM                0x08000000      /* system file */
 #define IHIDDEN                0x04000000      /* hidden file */
-#define IRASH          0x4E000000      /* mask for changeable attributes */
-#define INEWNAME       0x80000000      /* non-8.3 filename format */
+#define ISYSTEM                0x08000000      /* system file */
+
 #define IDIRECTORY     0x20000000      /* directory (shadow of real bit) */
+#define IARCHIVE       0x40000000      /* file archive bit */
+#define INEWNAME       0x80000000      /* non-8.3 filename format */
+
+#define IRASH          0x4E000000      /* mask for changeable attributes */
 #define ATTRSHIFT      25      /* bits to shift to move attribute
                                   specification to mode position */
 
+/* extended attributes for Linux */
+
+#define JFS_NOATIME_FL         0x00080000 /* do not update atime */
+
+#define JFS_DIRSYNC_FL         0x00100000 /* dirsync behaviour */
+#define JFS_SYNC_FL            0x00200000 /* Synchronous updates */
+#define JFS_SECRM_FL           0x00400000 /* Secure deletion */
+#define JFS_UNRM_FL            0x00800000 /* allow for undelete */
+
+#define JFS_APPEND_FL          0x01000000 /* writes to file may only append */
+#define JFS_IMMUTABLE_FL       0x02000000 /* Immutable file */
+
+#define JFS_FL_USER_VISIBLE    0x0FF80000
+#define JFS_FL_USER_MODIFIABLE 0x03F80000
+#define JFS_FL_INHERIT         0x0BC80000
+
+
+#define JFS_IOC_GETFLAGS       _IOR('f', 1, long)
+#define JFS_IOC_SETFLAGS       _IOW('f', 2, long)
+
+
 #endif /*_H_JFS_DINODE */
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/jfs_inode.c 
linux-2.6.16-rc1-jfs/fs/jfs/jfs_inode.c
--- linux-2.6.16-rc1/fs/jfs/jfs_inode.c 2005-08-29 22:25:32 +0200
+++ linux-2.6.16-rc1-jfs/fs/jfs/jfs_inode.c     2006-02-01 10:00:09 +0100
@@ -25,6 +25,26 @@
 #include "jfs_dinode.h"
 #include "jfs_debug.h"
 
+
+void jfs_set_inode_flags(struct inode *inode)
+{
+       unsigned int flags = JFS_IP(inode)->mode2;
+
+       inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
+               S_NOATIME | S_DIRSYNC | S_SYNC);
+
+       if (flags & JFS_IMMUTABLE_FL)
+               inode->i_flags |= S_IMMUTABLE;
+       if (flags & JFS_APPEND_FL)
+               inode->i_flags |= S_APPEND;
+       if (flags & JFS_NOATIME_FL)
+               inode->i_flags |= S_NOATIME;
+       if (flags & JFS_DIRSYNC_FL)
+               inode->i_flags |= S_DIRSYNC;
+       if (flags & JFS_SYNC_FL)
+               inode->i_flags |= S_SYNC;
+}
+
 /*
  * NAME:       ialloc()
  *
@@ -74,10 +94,20 @@ struct inode *ialloc(struct inode *paren
        }
 
        inode->i_mode = mode;
-       if (S_ISDIR(mode))
-               jfs_inode->mode2 = IDIRECTORY | mode;
+       /* inherit flags from parent */
+       jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT;
+
+       if (S_ISDIR(mode)) {
+               jfs_inode->mode2 |= IDIRECTORY;
+               jfs_inode->mode2 &= ~JFS_DIRSYNC_FL;
+       }
+       else if (S_ISLNK(mode))
+               jfs_inode->mode2 &=
+                       ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL);
        else
-               jfs_inode->mode2 = INLINEEA | ISPARSE | mode;
+               jfs_inode->mode2 |= INLINEEA | ISPARSE;
+       jfs_inode->mode2 |= mode;
+
        inode->i_blksize = sb->s_blocksize;
        inode->i_blocks = 0;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
@@ -98,6 +128,7 @@ struct inode *ialloc(struct inode *paren
        jfs_inode->atlhead = 0;
        jfs_inode->atltail = 0;
        jfs_inode->xtlid = 0;
+       jfs_set_inode_flags(inode);
 
        jfs_info("ialloc returns inode = 0x%p\n", inode);
 
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/jfs_inode.h 
linux-2.6.16-rc1-jfs/fs/jfs/jfs_inode.h
--- linux-2.6.16-rc1/fs/jfs/jfs_inode.h 2005-08-29 22:25:32 +0200
+++ linux-2.6.16-rc1-jfs/fs/jfs/jfs_inode.h     2006-02-01 09:51:16 +0100
@@ -20,6 +20,8 @@
 
 extern struct inode *ialloc(struct inode *, umode_t);
 extern int jfs_fsync(struct file *, struct dentry *, int);
+extern int jfs_ioctl(struct inode *, struct file *,
+                       unsigned int, unsigned long);
 extern void jfs_read_inode(struct inode *);
 extern int jfs_commit_inode(struct inode *, int);
 extern int jfs_write_inode(struct inode*, int);
@@ -29,6 +31,7 @@ extern void jfs_truncate(struct inode *)
 extern void jfs_truncate_nolock(struct inode *, loff_t);
 extern void jfs_free_zero_link(struct inode *);
 extern struct dentry *jfs_get_parent(struct dentry *dentry);
+extern void jfs_set_inode_flags(struct inode *);
 
 extern struct address_space_operations jfs_aops;
 extern struct inode_operations jfs_dir_inode_operations;
diff -NurpP --minimal linux-2.6.16-rc1/fs/jfs/namei.c 
linux-2.6.16-rc1-jfs/fs/jfs/namei.c
--- linux-2.6.16-rc1/fs/jfs/namei.c     2006-01-03 17:29:57 +0100
+++ linux-2.6.16-rc1-jfs/fs/jfs/namei.c 2006-02-01 09:51:16 +0100
@@ -1523,6 +1523,7 @@ struct file_operations jfs_dir_operation
        .read           = generic_read_dir,
        .readdir        = jfs_readdir,
        .fsync          = jfs_fsync,
+       .ioctl          = jfs_ioctl,
 };
 
 static int jfs_ci_hash(struct dentry *dir, struct qstr *this)





-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid3432&bid#0486&dat1642
_______________________________________________
Jfs-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jfs-discussion

Reply via email to