Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ac9bcd5 authored by Marcin Slusarz's avatar Marcin Slusarz Committed by Jan Kara
Browse files

udf: implement mode and dmode mounting options



"dmode" allows overriding permissions of directories and
"mode" allows overriding permissions of files.

Signed-off-by: default avatarMarcin Slusarz <marcin.slusarz@gmail.com>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 530f1a5e
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,8 @@ The following mount options are supported:


	gid=		Set the default group.
	gid=		Set the default group.
	umask=		Set the default umask.
	umask=		Set the default umask.
	mode=		Set the default file permissions.
	dmode=		Set the default directory permissions.
	uid=		Set the default user.
	uid=		Set the default user.
	bs=		Set the block size.
	bs=		Set the block size.
	unhide		Show otherwise hidden files.
	unhide		Show otherwise hidden files.
+9 −2
Original line number Original line Diff line number Diff line
@@ -1222,8 +1222,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
	inode->i_size = le64_to_cpu(fe->informationLength);
	inode->i_size = le64_to_cpu(fe->informationLength);
	iinfo->i_lenExtents = inode->i_size;
	iinfo->i_lenExtents = inode->i_size;


	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 = udf_convert_permissions(fe);
	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
	inode->i_mode &= ~sbi->s_umask;


	if (iinfo->i_efe == 0) {
	if (iinfo->i_efe == 0) {
		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
+30 −1
Original line number Original line Diff line number Diff line
@@ -201,6 +201,8 @@ struct udf_options {
	mode_t umask;
	mode_t umask;
	gid_t gid;
	gid_t gid;
	uid_t uid;
	uid_t uid;
	mode_t fmode;
	mode_t dmode;
	struct nls_table *nls_map;
	struct nls_table *nls_map;
};
};


@@ -282,6 +284,10 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
		seq_printf(seq, ",gid=%u", sbi->s_gid);
		seq_printf(seq, ",gid=%u", sbi->s_gid);
	if (sbi->s_umask != 0)
	if (sbi->s_umask != 0)
		seq_printf(seq, ",umask=%o", sbi->s_umask);
		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))
	if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
		seq_printf(seq, ",session=%u", sbi->s_session);
		seq_printf(seq, ",session=%u", sbi->s_session);
	if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
	if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
@@ -317,6 +323,8 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
 *
 *
 *	gid=		Set the default group.
 *	gid=		Set the default group.
 *	umask=		Set the default umask.
 *	umask=		Set the default umask.
 *	mode=		Set the default file permissions.
 *	dmode=		Set the default directory permissions.
 *	uid=		Set the default user.
 *	uid=		Set the default user.
 *	bs=		Set the block size.
 *	bs=		Set the block size.
 *	unhide		Show otherwise hidden files.
 *	unhide		Show otherwise hidden files.
@@ -366,7 +374,8 @@ enum {
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
	Opt_rootdir, Opt_utf8, Opt_iocharset,
	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 = {
static const match_table_t tokens = {
@@ -395,6 +404,8 @@ static const match_table_t tokens = {
	{Opt_rootdir,	"rootdir=%u"},
	{Opt_rootdir,	"rootdir=%u"},
	{Opt_utf8,	"utf8"},
	{Opt_utf8,	"utf8"},
	{Opt_iocharset,	"iocharset=%s"},
	{Opt_iocharset,	"iocharset=%s"},
	{Opt_fmode,     "mode=%o"},
	{Opt_dmode,     "dmode=%o"},
	{Opt_err,	NULL}
	{Opt_err,	NULL}
};
};


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


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


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


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


	/* Set the block size for all transfers */
	/* Set the block size for all transfers */
+2 −0
Original line number Original line Diff line number Diff line
@@ -123,6 +123,8 @@ struct udf_sb_info {
	mode_t			s_umask;
	mode_t			s_umask;
	gid_t			s_gid;
	gid_t			s_gid;
	uid_t			s_uid;
	uid_t			s_uid;
	mode_t			s_fmode;
	mode_t			s_dmode;


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