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