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 /fs/jfs | |
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>
Diffstat (limited to 'fs/jfs')
-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) |