Re: [Jfs-discussion] accessing files created by OS/2 under Linux on JFS-partitition
Brought to you by:
blaschke-oss,
shaggyk
From: Dave K. <dkl...@gm...> - 2006-02-09 22:05:11
|
On Fri, 2006-02-03 at 22:28 +0100, Ingo wrote: > >I'm sure SUSE has a way to build a kernel module without rebuilding the > >whole kernel. I'll look into it. > > In that case I am sure I can do it, years ago I updated jfs.o?? in 2.4 kernel of SUSE 8.0 > Thanks, > Ingo Okay, I think this patch is ready to test: JFS: add uid, gid, and umask mount options OS/2 doesn't initialize the uid, gid, or unix-style permission bits. The uid, gid, & umask mount options perform pretty much like those for the fat file system, overriding what is stored on disk. This is useful for users sharing the file system with OS/2. I implemented a little feature so that if you mask the execute bit, it will be re-enabled on directories when the appropriate read bit is unmasked. I didn't want to implement an fmask & dmask option. Signed-off-by: Dave Kleikamp <sh...@au...> diff -urp linux-2.6.13-15.7/fs/jfs/acl.c linux/fs/jfs/acl.c --- linux-2.6.13-15.7/fs/jfs/acl.c 2005-08-28 18:41:01.000000000 -0500 +++ linux/fs/jfs/acl.c 2006-02-09 15:22:54.000000000 -0600 @@ -180,6 +180,9 @@ cleanup: posix_acl_release(acl); } else inode->i_mode &= ~current->fs->umask; + + JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | + inode->i_mode; return rc; } diff -urp linux-2.6.13-15.7/fs/jfs/jfs_imap.c linux/fs/jfs/jfs_imap.c --- linux-2.6.13-15.7/fs/jfs/jfs_imap.c 2005-08-28 18:41:01.000000000 -0500 +++ linux/fs/jfs/jfs_imap.c 2006-02-09 15:22:54.000000000 -0600 @@ -3072,14 +3072,40 @@ static void duplicateIXtree(struct super static int copy_from_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); jfs_ip->fileset = le32_to_cpu(dip->di_fileset); jfs_ip->mode2 = le32_to_cpu(dip->di_mode); ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; + if (sbi->umask != -1) { + ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask); + /* For directories, add x permission if r is allowed by umask */ + if (S_ISDIR(ip->i_mode)) { + if (ip->i_mode & 0400) + ip->i_mode |= 0100; + if (ip->i_mode & 0040) + ip->i_mode |= 0010; + if (ip->i_mode & 0004) + ip->i_mode |= 0001; + } + } ip->i_nlink = le32_to_cpu(dip->di_nlink); - ip->i_uid = le32_to_cpu(dip->di_uid); - ip->i_gid = le32_to_cpu(dip->di_gid); + + jfs_ip->saved_uid = le32_to_cpu(dip->di_uid); + if (sbi->uid == -1) + ip->i_uid = jfs_ip->saved_uid; + else { + ip->i_uid = sbi->uid; + } + + jfs_ip->saved_gid = le32_to_cpu(dip->di_gid); + if (sbi->gid == -1) + ip->i_gid = jfs_ip->saved_gid; + else { + ip->i_gid = sbi->gid; + } + ip->i_size = le64_to_cpu(dip->di_size); ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); @@ -3130,21 +3156,33 @@ static int copy_from_dinode(struct dinod static void copy_to_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); dip->di_fileset = cpu_to_le32(jfs_ip->fileset); - dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); + dip->di_inostamp = cpu_to_le32(sbi->inostamp); dip->di_number = cpu_to_le32(ip->i_ino); dip->di_gen = cpu_to_le32(ip->i_generation); dip->di_size = cpu_to_le64(ip->i_size); dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); dip->di_nlink = cpu_to_le32(ip->i_nlink); - dip->di_uid = cpu_to_le32(ip->i_uid); - dip->di_gid = cpu_to_le32(ip->i_gid); + if (sbi->uid == -1) + dip->di_uid = cpu_to_le32(ip->i_uid); + else + dip->di_uid = cpu_to_le32(jfs_ip->saved_uid); + if (sbi->gid == -1) + dip->di_gid = cpu_to_le32(ip->i_gid); + else + dip->di_gid = cpu_to_le32(jfs_ip->saved_gid); /* * mode2 is only needed for storing the higher order bits. * Trust i_mode for the lower order ones */ - dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode); + if (sbi->umask == -1) + dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | + ip->i_mode); + else /* Leave the original permissions alone */ + dip->di_mode = cpu_to_le32(jfs_ip->mode2); + dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec); dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec); dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec); diff -urp linux-2.6.13-15.7/fs/jfs/jfs_incore.h linux/fs/jfs/jfs_incore.h --- linux-2.6.13-15.7/fs/jfs/jfs_incore.h 2005-08-28 18:41:01.000000000 -0500 +++ linux/fs/jfs/jfs_incore.h 2006-02-09 15:22:54.000000000 -0600 @@ -37,6 +37,8 @@ struct jfs_inode_info { int fileset; /* fileset number (always 16)*/ uint mode2; /* jfs-specific mode */ + uint saved_uid; /* saved for uid mount option */ + uint saved_gid; /* saved for gid mount option */ pxd_t ixpxd; /* inode extent descriptor */ dxd_t acl; /* dxd describing acl */ dxd_t ea; /* dxd describing ea */ @@ -169,6 +171,9 @@ struct jfs_sb_info { uint state; /* mount/recovery state */ unsigned long flag; /* mount time flags */ uint p_state; /* state prior to going no integrity */ + uint uid; /* uid to override on-disk uid */ + uint gid; /* gid to override on-disk gid */ + uint umask; /* umask to override on-disk umask */ }; /* jfs_sb_info commit_state */ diff -urp linux-2.6.13-15.7/fs/jfs/jfs_inode.c linux/fs/jfs/jfs_inode.c --- linux-2.6.13-15.7/fs/jfs/jfs_inode.c 2005-08-28 18:41:01.000000000 -0500 +++ linux/fs/jfs/jfs_inode.c 2006-02-09 15:22:54.000000000 -0600 @@ -63,6 +63,13 @@ struct inode *ialloc(struct inode *paren inode->i_gid = current->fsgid; /* + * New inodes need to save sane values on disk when + * uid & gid mount options are used + */ + jfs_inode->saved_uid = inode->i_uid; + jfs_inode->saved_gid = inode->i_gid; + + /* * Allocate inode to quota. */ if (DQUOT_ALLOC_INODE(inode)) { diff -urp linux-2.6.13-15.7/fs/jfs/super.c linux/fs/jfs/super.c --- linux-2.6.13-15.7/fs/jfs/super.c 2005-08-28 18:41:01.000000000 -0500 +++ linux/fs/jfs/super.c 2006-02-09 15:29:01.000000000 -0600 @@ -192,7 +192,8 @@ static void jfs_put_super(struct super_b enum { Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, - Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, + Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_uid, Opt_gid, Opt_umask, + Opt_err, }; static match_table_t tokens = { @@ -206,6 +207,9 @@ static match_table_t tokens = { {Opt_ignore, "quota"}, {Opt_ignore, "usrquota"}, {Opt_ignore, "grpquota"}, + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_umask, "umask=%u"}, {Opt_err, NULL} }; @@ -293,6 +297,29 @@ static int parse_options(char *options, } break; } + case Opt_uid: + { + char *uid = args[0].from; + sbi->uid = simple_strtoul(uid, &uid, 0); + break; + } + case Opt_gid: + { + char *gid = args[0].from; + sbi->gid = simple_strtoul(gid, &gid, 0); + break; + } + case Opt_umask: + { + char *umask = args[0].from; + sbi->umask = simple_strtoul(umask, &umask, 8); + if (sbi->umask & ~0777) { + printk(KERN_ERR + "JFS: Invalid value of umask\n"); + goto cleanup; + } + break; + } default: printk("jfs: Unrecognized mount option \"%s\" " " or missing value\n", p); @@ -381,6 +408,7 @@ static int jfs_fill_super(struct super_b memset(sbi, 0, sizeof (struct jfs_sb_info)); sb->s_fs_info = sbi; sbi->sb = sb; + sbi->uid = sbi->gid = sbi->umask = -1; /* initialize the mount flag and determine the default error handler */ flag = JFS_ERR_REMOUNT_RO; -- David Kleikamp IBM Linux Technology Center |