Skip to content

Commit

Permalink
udf: implement mode and dmode mounting options
Browse files Browse the repository at this point in the history
"dmode" allows overriding permissions of directories and
"mode" allows overriding permissions of files.

Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Jan Kara <jack@suse.cz>
  • Loading branch information
Marcin Slusarz authored and Jan Kara committed Apr 2, 2009
1 parent 530f1a5 commit 7ac9bcd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Documentation/filesystems/udf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ The following mount options are supported:

gid= Set the default group.
umask= Set the default umask.
mode= Set the default file permissions.
dmode= Set the default directory permissions.
uid= Set the default user.
bs= Set the block size.
unhide Show otherwise hidden files.
Expand Down
11 changes: 9 additions & 2 deletions fs/udf/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,8 +1222,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_size = le64_to_cpu(fe->informationLength);
iinfo->i_lenExtents = inode->i_size;

inode->i_mode = udf_convert_permissions(fe);
inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
sbi->s_fmode != -1)
inode->i_mode = sbi->s_fmode;
else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY &&
sbi->s_dmode != -1)
inode->i_mode = sbi->s_dmode;
else
inode->i_mode = udf_convert_permissions(fe);
inode->i_mode &= ~sbi->s_umask;

if (iinfo->i_efe == 0) {
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
Expand Down
31 changes: 30 additions & 1 deletion fs/udf/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ struct udf_options {
mode_t umask;
gid_t gid;
uid_t uid;
mode_t fmode;
mode_t dmode;
struct nls_table *nls_map;
};

Expand Down Expand Up @@ -282,6 +284,10 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
seq_printf(seq, ",gid=%u", sbi->s_gid);
if (sbi->s_umask != 0)
seq_printf(seq, ",umask=%o", sbi->s_umask);
if (sbi->s_fmode != -1)
seq_printf(seq, ",mode=%o", sbi->s_fmode);
if (sbi->s_dmode != -1)
seq_printf(seq, ",dmode=%o", sbi->s_dmode);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
seq_printf(seq, ",session=%u", sbi->s_session);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
Expand Down Expand Up @@ -317,6 +323,8 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
*
* gid= Set the default group.
* umask= Set the default umask.
* mode= Set the default file permissions.
* dmode= Set the default directory permissions.
* uid= Set the default user.
* bs= Set the block size.
* unhide Show otherwise hidden files.
Expand Down Expand Up @@ -366,7 +374,8 @@ enum {
Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
Opt_rootdir, Opt_utf8, Opt_iocharset,
Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
Opt_fmode, Opt_dmode
};

static const match_table_t tokens = {
Expand Down Expand Up @@ -395,6 +404,8 @@ static const match_table_t tokens = {
{Opt_rootdir, "rootdir=%u"},
{Opt_utf8, "utf8"},
{Opt_iocharset, "iocharset=%s"},
{Opt_fmode, "mode=%o"},
{Opt_dmode, "dmode=%o"},
{Opt_err, NULL}
};

Expand Down Expand Up @@ -531,6 +542,16 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
case Opt_gforget:
uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
break;
case Opt_fmode:
if (match_octal(args, &option))
return 0;
uopt->fmode = option & 0777;
break;
case Opt_dmode:
if (match_octal(args, &option))
return 0;
uopt->dmode = option & 0777;
break;
default:
printk(KERN_ERR "udf: bad mount option \"%s\" "
"or missing value\n", p);
Expand Down Expand Up @@ -560,6 +581,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
uopt.uid = sbi->s_uid;
uopt.gid = sbi->s_gid;
uopt.umask = sbi->s_umask;
uopt.fmode = sbi->s_fmode;
uopt.dmode = sbi->s_dmode;

if (!udf_parse_options(options, &uopt, true))
return -EINVAL;
Expand All @@ -568,6 +591,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
sbi->s_uid = uopt.uid;
sbi->s_gid = uopt.gid;
sbi->s_umask = uopt.umask;
sbi->s_fmode = uopt.fmode;
sbi->s_dmode = uopt.dmode;

if (sbi->s_lvid_bh) {
int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev);
Expand Down Expand Up @@ -1869,6 +1894,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
uopt.uid = -1;
uopt.gid = -1;
uopt.umask = 0;
uopt.fmode = -1;
uopt.dmode = -1;

sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
if (!sbi)
Expand Down Expand Up @@ -1906,6 +1933,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sbi->s_uid = uopt.uid;
sbi->s_gid = uopt.gid;
sbi->s_umask = uopt.umask;
sbi->s_fmode = uopt.fmode;
sbi->s_dmode = uopt.dmode;
sbi->s_nls_map = uopt.nls_map;

/* Set the block size for all transfers */
Expand Down
2 changes: 2 additions & 0 deletions fs/udf/udf_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ struct udf_sb_info {
mode_t s_umask;
gid_t s_gid;
uid_t s_uid;
mode_t s_fmode;
mode_t s_dmode;

/* Root Info */
struct timespec s_record_time;
Expand Down

0 comments on commit 7ac9bcd

Please sign in to comment.