diff options
| author | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-03-09 14:59:30 -0500 |
|---|---|---|
| committer | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-03-09 14:59:30 -0500 |
| commit | 69eb66d7da7dba2696281981347698e1693c2340 (patch) | |
| tree | ba699dc7a1a80efe159f4a4401b174a7e80779fc | |
| parent | be0bf7da19135a7a0f8c275f20c819940be218d9 (diff) | |
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 <shaggy@austin.ibm.com>
| -rw-r--r-- | fs/jfs/acl.c | 3 | ||||
| -rw-r--r-- | fs/jfs/jfs_imap.c | 50 | ||||
| -rw-r--r-- | fs/jfs/jfs_incore.h | 5 | ||||
| -rw-r--r-- | fs/jfs/jfs_inode.c | 7 | ||||
| -rw-r--r-- | fs/jfs/super.c | 38 |
5 files changed, 93 insertions, 10 deletions
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index e0b6fdab200c..e2281300979c 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
| @@ -183,6 +183,9 @@ cleanup: | |||
| 183 | posix_acl_release(acl); | 183 | posix_acl_release(acl); |
| 184 | } else | 184 | } else |
| 185 | inode->i_mode &= ~current->fs->umask; | 185 | inode->i_mode &= ~current->fs->umask; |
| 186 | |||
| 187 | JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | | ||
| 188 | inode->i_mode; | ||
| 186 | 189 | ||
| 187 | return rc; | 190 | return rc; |
| 188 | } | 191 | } |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index b62a048b6881..ccbe60aff83d 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
| @@ -3074,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, | |||
| 3074 | static int copy_from_dinode(struct dinode * dip, struct inode *ip) | 3074 | static int copy_from_dinode(struct dinode * dip, struct inode *ip) |
| 3075 | { | 3075 | { |
| 3076 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); | 3076 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
| 3077 | struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); | ||
| 3077 | 3078 | ||
| 3078 | jfs_ip->fileset = le32_to_cpu(dip->di_fileset); | 3079 | jfs_ip->fileset = le32_to_cpu(dip->di_fileset); |
| 3079 | jfs_ip->mode2 = le32_to_cpu(dip->di_mode); | 3080 | jfs_ip->mode2 = le32_to_cpu(dip->di_mode); |
| 3080 | 3081 | ||
| 3081 | ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; | 3082 | ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; |
| 3083 | if (sbi->umask != -1) { | ||
| 3084 | ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask); | ||
| 3085 | /* For directories, add x permission if r is allowed by umask */ | ||
| 3086 | if (S_ISDIR(ip->i_mode)) { | ||
| 3087 | if (ip->i_mode & 0400) | ||
| 3088 | ip->i_mode |= 0100; | ||
| 3089 | if (ip->i_mode & 0040) | ||
| 3090 | ip->i_mode |= 0010; | ||
| 3091 | if (ip->i_mode & 0004) | ||
| 3092 | ip->i_mode |= 0001; | ||
| 3093 | } | ||
| 3094 | } | ||
| 3082 | ip->i_nlink = le32_to_cpu(dip->di_nlink); | 3095 | ip->i_nlink = le32_to_cpu(dip->di_nlink); |
| 3083 | ip->i_uid = le32_to_cpu(dip->di_uid); | 3096 | |
| 3084 | ip->i_gid = le32_to_cpu(dip->di_gid); | 3097 | jfs_ip->saved_uid = le32_to_cpu(dip->di_uid); |
| 3098 | if (sbi->uid == -1) | ||
| 3099 | ip->i_uid = jfs_ip->saved_uid; | ||
| 3100 | else { | ||
| 3101 | ip->i_uid = sbi->uid; | ||
| 3102 | } | ||
| 3103 | |||
| 3104 | jfs_ip->saved_gid = le32_to_cpu(dip->di_gid); | ||
| 3105 | if (sbi->gid == -1) | ||
| 3106 | ip->i_gid = jfs_ip->saved_gid; | ||
| 3107 | else { | ||
| 3108 | ip->i_gid = sbi->gid; | ||
| 3109 | } | ||
| 3110 | |||
| 3085 | ip->i_size = le64_to_cpu(dip->di_size); | 3111 | ip->i_size = le64_to_cpu(dip->di_size); |
| 3086 | ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); | 3112 | ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); |
| 3087 | ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); | 3113 | ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); |
| @@ -3132,21 +3158,33 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) | |||
| 3132 | static void copy_to_dinode(struct dinode * dip, struct inode *ip) | 3158 | static void copy_to_dinode(struct dinode * dip, struct inode *ip) |
| 3133 | { | 3159 | { |
| 3134 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); | 3160 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
| 3161 | struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); | ||
| 3135 | 3162 | ||
| 3136 | dip->di_fileset = cpu_to_le32(jfs_ip->fileset); | 3163 | dip->di_fileset = cpu_to_le32(jfs_ip->fileset); |
| 3137 | dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); | 3164 | dip->di_inostamp = cpu_to_le32(sbi->inostamp); |
| 3138 | dip->di_number = cpu_to_le32(ip->i_ino); | 3165 | dip->di_number = cpu_to_le32(ip->i_ino); |
| 3139 | dip->di_gen = cpu_to_le32(ip->i_generation); | 3166 | dip->di_gen = cpu_to_le32(ip->i_generation); |
| 3140 | dip->di_size = cpu_to_le64(ip->i_size); | 3167 | dip->di_size = cpu_to_le64(ip->i_size); |
| 3141 | dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); | 3168 | dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); |
| 3142 | dip->di_nlink = cpu_to_le32(ip->i_nlink); | 3169 | dip->di_nlink = cpu_to_le32(ip->i_nlink); |
| 3143 | dip->di_uid = cpu_to_le32(ip->i_uid); | 3170 | if (sbi->uid == -1) |
| 3144 | dip->di_gid = cpu_to_le32(ip->i_gid); | 3171 | dip->di_uid = cpu_to_le32(ip->i_uid); |
| 3172 | else | ||
| 3173 | dip->di_uid = cpu_to_le32(jfs_ip->saved_uid); | ||
| 3174 | if (sbi->gid == -1) | ||
| 3175 | dip->di_gid = cpu_to_le32(ip->i_gid); | ||
| 3176 | else | ||
| 3177 | dip->di_gid = cpu_to_le32(jfs_ip->saved_gid); | ||
| 3145 | /* | 3178 | /* |
| 3146 | * mode2 is only needed for storing the higher order bits. | 3179 | * mode2 is only needed for storing the higher order bits. |
| 3147 | * Trust i_mode for the lower order ones | 3180 | * Trust i_mode for the lower order ones |
| 3148 | */ | 3181 | */ |
| 3149 | dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode); | 3182 | if (sbi->umask == -1) |
| 3183 | dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | | ||
| 3184 | ip->i_mode); | ||
| 3185 | else /* Leave the original permissions alone */ | ||
| 3186 | dip->di_mode = cpu_to_le32(jfs_ip->mode2); | ||
| 3187 | |||
| 3150 | dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec); | 3188 | dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec); |
| 3151 | dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec); | 3189 | dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec); |
| 3152 | dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec); | 3190 | dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec); |
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index a97ead889a68..54d73716ca8c 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h | |||
| @@ -38,6 +38,8 @@ | |||
| 38 | struct jfs_inode_info { | 38 | struct jfs_inode_info { |
| 39 | int fileset; /* fileset number (always 16)*/ | 39 | int fileset; /* fileset number (always 16)*/ |
| 40 | uint mode2; /* jfs-specific mode */ | 40 | uint mode2; /* jfs-specific mode */ |
| 41 | uint saved_uid; /* saved for uid mount option */ | ||
| 42 | uint saved_gid; /* saved for gid mount option */ | ||
| 41 | pxd_t ixpxd; /* inode extent descriptor */ | 43 | pxd_t ixpxd; /* inode extent descriptor */ |
| 42 | dxd_t acl; /* dxd describing acl */ | 44 | dxd_t acl; /* dxd describing acl */ |
| 43 | dxd_t ea; /* dxd describing ea */ | 45 | dxd_t ea; /* dxd describing ea */ |
| @@ -170,6 +172,9 @@ struct jfs_sb_info { | |||
| 170 | uint state; /* mount/recovery state */ | 172 | uint state; /* mount/recovery state */ |
| 171 | unsigned long flag; /* mount time flags */ | 173 | unsigned long flag; /* mount time flags */ |
| 172 | uint p_state; /* state prior to going no integrity */ | 174 | uint p_state; /* state prior to going no integrity */ |
| 175 | uint uid; /* uid to override on-disk uid */ | ||
| 176 | uint gid; /* gid to override on-disk gid */ | ||
| 177 | uint umask; /* umask to override on-disk umask */ | ||
| 173 | }; | 178 | }; |
| 174 | 179 | ||
| 175 | /* jfs_sb_info commit_state */ | 180 | /* jfs_sb_info commit_state */ |
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index ffd2a8a00787..495df402916d 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c | |||
| @@ -83,6 +83,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
| 83 | inode->i_gid = current->fsgid; | 83 | inode->i_gid = current->fsgid; |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| 86 | * New inodes need to save sane values on disk when | ||
| 87 | * uid & gid mount options are used | ||
| 88 | */ | ||
| 89 | jfs_inode->saved_uid = inode->i_uid; | ||
| 90 | jfs_inode->saved_gid = inode->i_gid; | ||
| 91 | |||
| 92 | /* | ||
| 86 | * Allocate inode to quota. | 93 | * Allocate inode to quota. |
| 87 | */ | 94 | */ |
| 88 | if (DQUOT_ALLOC_INODE(inode)) { | 95 | if (DQUOT_ALLOC_INODE(inode)) { |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index ab6333347004..18f69e6aa719 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
| @@ -194,7 +194,7 @@ static void jfs_put_super(struct super_block *sb) | |||
| 194 | enum { | 194 | enum { |
| 195 | Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, | 195 | Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, |
| 196 | Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, | 196 | Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, |
| 197 | Opt_usrquota, Opt_grpquota | 197 | Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask |
| 198 | }; | 198 | }; |
| 199 | 199 | ||
| 200 | static match_table_t tokens = { | 200 | static match_table_t tokens = { |
| @@ -208,6 +208,9 @@ static match_table_t tokens = { | |||
| 208 | {Opt_ignore, "quota"}, | 208 | {Opt_ignore, "quota"}, |
| 209 | {Opt_usrquota, "usrquota"}, | 209 | {Opt_usrquota, "usrquota"}, |
| 210 | {Opt_grpquota, "grpquota"}, | 210 | {Opt_grpquota, "grpquota"}, |
| 211 | {Opt_uid, "uid=%u"}, | ||
| 212 | {Opt_gid, "gid=%u"}, | ||
| 213 | {Opt_umask, "umask=%u"}, | ||
| 211 | {Opt_err, NULL} | 214 | {Opt_err, NULL} |
| 212 | }; | 215 | }; |
| 213 | 216 | ||
| @@ -312,7 +315,29 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, | |||
| 312 | "JFS: quota operations not supported\n"); | 315 | "JFS: quota operations not supported\n"); |
| 313 | break; | 316 | break; |
| 314 | #endif | 317 | #endif |
| 315 | 318 | case Opt_uid: | |
| 319 | { | ||
| 320 | char *uid = args[0].from; | ||
| 321 | sbi->uid = simple_strtoul(uid, &uid, 0); | ||
| 322 | break; | ||
| 323 | } | ||
| 324 | case Opt_gid: | ||
| 325 | { | ||
| 326 | char *gid = args[0].from; | ||
| 327 | sbi->gid = simple_strtoul(gid, &gid, 0); | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | case Opt_umask: | ||
| 331 | { | ||
| 332 | char *umask = args[0].from; | ||
| 333 | sbi->umask = simple_strtoul(umask, &umask, 8); | ||
| 334 | if (sbi->umask & ~0777) { | ||
| 335 | printk(KERN_ERR | ||
| 336 | "JFS: Invalid value of umask\n"); | ||
| 337 | goto cleanup; | ||
| 338 | } | ||
| 339 | break; | ||
| 340 | } | ||
| 316 | default: | 341 | default: |
| 317 | printk("jfs: Unrecognized mount option \"%s\" " | 342 | printk("jfs: Unrecognized mount option \"%s\" " |
| 318 | " or missing value\n", p); | 343 | " or missing value\n", p); |
| @@ -400,6 +425,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 400 | return -ENOSPC; | 425 | return -ENOSPC; |
| 401 | sb->s_fs_info = sbi; | 426 | sb->s_fs_info = sbi; |
| 402 | sbi->sb = sb; | 427 | sbi->sb = sb; |
| 428 | sbi->uid = sbi->gid = sbi->umask = -1; | ||
| 403 | 429 | ||
| 404 | /* initialize the mount flag and determine the default error handler */ | 430 | /* initialize the mount flag and determine the default error handler */ |
| 405 | flag = JFS_ERR_REMOUNT_RO; | 431 | flag = JFS_ERR_REMOUNT_RO; |
| @@ -562,10 +588,14 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 562 | { | 588 | { |
| 563 | struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb); | 589 | struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb); |
| 564 | 590 | ||
| 591 | if (sbi->uid != -1) | ||
| 592 | seq_printf(seq, ",uid=%d", sbi->uid); | ||
| 593 | if (sbi->gid != -1) | ||
| 594 | seq_printf(seq, ",gid=%d", sbi->gid); | ||
| 595 | if (sbi->umask != -1) | ||
| 596 | seq_printf(seq, ",umask=%03o", sbi->umask); | ||
| 565 | if (sbi->flag & JFS_NOINTEGRITY) | 597 | if (sbi->flag & JFS_NOINTEGRITY) |
| 566 | seq_puts(seq, ",nointegrity"); | 598 | seq_puts(seq, ",nointegrity"); |
| 567 | else | ||
| 568 | seq_puts(seq, ",integrity"); | ||
| 569 | 599 | ||
| 570 | #if defined(CONFIG_QUOTA) | 600 | #if defined(CONFIG_QUOTA) |
| 571 | if (sbi->flag & JFS_USRQUOTA) | 601 | if (sbi->flag & JFS_USRQUOTA) |
