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 <[EMAIL PROTECTED]>

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



-------------------------------------------------------
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&kid=103432&bid=230486&dat=121642
_______________________________________________
Jfs-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jfs-discussion

Reply via email to