aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2006-03-09 14:59:30 -0500
committerDave Kleikamp <shaggy@austin.ibm.com>2006-03-09 14:59:30 -0500
commit69eb66d7da7dba2696281981347698e1693c2340 (patch)
treeba699dc7a1a80efe159f4a4401b174a7e80779fc
parentbe0bf7da19135a7a0f8c275f20c819940be218d9 (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.c3
-rw-r--r--fs/jfs/jfs_imap.c50
-rw-r--r--fs/jfs/jfs_incore.h5
-rw-r--r--fs/jfs/jfs_inode.c7
-rw-r--r--fs/jfs/super.c38
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,
3074static int copy_from_dinode(struct dinode * dip, struct inode *ip) 3074static 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)
3132static void copy_to_dinode(struct dinode * dip, struct inode *ip) 3158static 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 @@
38struct jfs_inode_info { 38struct 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)
194enum { 194enum {
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
200static match_table_t tokens = { 200static 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)