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>
This commit is contained in:
Родитель
be0bf7da19
Коммит
69eb66d7da
|
@ -183,6 +183,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;
|
||||
}
|
||||
|
|
|
@ -3074,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
|
|||
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);
|
||||
|
@ -3132,21 +3158,33 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
|
|||
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);
|
||||
|
|
|
@ -38,6 +38,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 */
|
||||
|
@ -170,6 +172,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 */
|
||||
|
|
|
@ -82,6 +82,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
|
|||
} else
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -194,7 +194,7 @@ static void jfs_put_super(struct super_block *sb)
|
|||
enum {
|
||||
Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
|
||||
Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
|
||||
Opt_usrquota, Opt_grpquota
|
||||
Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
|
||||
};
|
||||
|
||||
static match_table_t tokens = {
|
||||
|
@ -208,6 +208,9 @@ static match_table_t tokens = {
|
|||
{Opt_ignore, "quota"},
|
||||
{Opt_usrquota, "usrquota"},
|
||||
{Opt_grpquota, "grpquota"},
|
||||
{Opt_uid, "uid=%u"},
|
||||
{Opt_gid, "gid=%u"},
|
||||
{Opt_umask, "umask=%u"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
|
||||
|
@ -312,7 +315,29 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
|
|||
"JFS: quota operations not supported\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
@ -400,6 +425,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||
return -ENOSPC;
|
||||
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;
|
||||
|
@ -562,10 +588,14 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
|||
{
|
||||
struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb);
|
||||
|
||||
if (sbi->uid != -1)
|
||||
seq_printf(seq, ",uid=%d", sbi->uid);
|
||||
if (sbi->gid != -1)
|
||||
seq_printf(seq, ",gid=%d", sbi->gid);
|
||||
if (sbi->umask != -1)
|
||||
seq_printf(seq, ",umask=%03o", sbi->umask);
|
||||
if (sbi->flag & JFS_NOINTEGRITY)
|
||||
seq_puts(seq, ",nointegrity");
|
||||
else
|
||||
seq_puts(seq, ",integrity");
|
||||
|
||||
#if defined(CONFIG_QUOTA)
|
||||
if (sbi->flag & JFS_USRQUOTA)
|
||||
|
|
Загрузка…
Ссылка в новой задаче