aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/udf.txt2
-rw-r--r--fs/udf/inode.c11
-rw-r--r--fs/udf/super.c31
-rw-r--r--fs/udf/udf_sb.h2
4 files changed, 43 insertions, 3 deletions
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index fde829a756e6..902b95d0ee51 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -24,6 +24,8 @@ The following mount options are supported:
24 24
25 gid= Set the default group. 25 gid= Set the default group.
26 umask= Set the default umask. 26 umask= Set the default umask.
27 mode= Set the default file permissions.
28 dmode= Set the default directory permissions.
27 uid= Set the default user. 29 uid= Set the default user.
28 bs= Set the block size. 30 bs= Set the block size.
29 unhide Show otherwise hidden files. 31 unhide Show otherwise hidden files.
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 3c98c305d37d..1456d238f8f8 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1222,8 +1222,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1222 inode->i_size = le64_to_cpu(fe->informationLength); 1222 inode->i_size = le64_to_cpu(fe->informationLength);
1223 iinfo->i_lenExtents = inode->i_size; 1223 iinfo->i_lenExtents = inode->i_size;
1224 1224
1225 inode->i_mode = udf_convert_permissions(fe); 1225 if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
1226 inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask; 1226 sbi->s_fmode != -1)
1227 inode->i_mode = sbi->s_fmode;
1228 else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY &&
1229 sbi->s_dmode != -1)
1230 inode->i_mode = sbi->s_dmode;
1231 else
1232 inode->i_mode = udf_convert_permissions(fe);
1233 inode->i_mode &= ~sbi->s_umask;
1227 1234
1228 if (iinfo->i_efe == 0) { 1235 if (iinfo->i_efe == 0) {
1229 inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << 1236 inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 8364b1719158..98d5455f77c7 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -201,6 +201,8 @@ struct udf_options {
201 mode_t umask; 201 mode_t umask;
202 gid_t gid; 202 gid_t gid;
203 uid_t uid; 203 uid_t uid;
204 mode_t fmode;
205 mode_t dmode;
204 struct nls_table *nls_map; 206 struct nls_table *nls_map;
205}; 207};
206 208
@@ -282,6 +284,10 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
282 seq_printf(seq, ",gid=%u", sbi->s_gid); 284 seq_printf(seq, ",gid=%u", sbi->s_gid);
283 if (sbi->s_umask != 0) 285 if (sbi->s_umask != 0)
284 seq_printf(seq, ",umask=%o", sbi->s_umask); 286 seq_printf(seq, ",umask=%o", sbi->s_umask);
287 if (sbi->s_fmode != -1)
288 seq_printf(seq, ",mode=%o", sbi->s_fmode);
289 if (sbi->s_dmode != -1)
290 seq_printf(seq, ",dmode=%o", sbi->s_dmode);
285 if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET)) 291 if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
286 seq_printf(seq, ",session=%u", sbi->s_session); 292 seq_printf(seq, ",session=%u", sbi->s_session);
287 if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET)) 293 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)
317 * 323 *
318 * gid= Set the default group. 324 * gid= Set the default group.
319 * umask= Set the default umask. 325 * umask= Set the default umask.
326 * mode= Set the default file permissions.
327 * dmode= Set the default directory permissions.
320 * uid= Set the default user. 328 * uid= Set the default user.
321 * bs= Set the block size. 329 * bs= Set the block size.
322 * unhide Show otherwise hidden files. 330 * unhide Show otherwise hidden files.
@@ -366,7 +374,8 @@ enum {
366 Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, 374 Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
367 Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, 375 Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
368 Opt_rootdir, Opt_utf8, Opt_iocharset, 376 Opt_rootdir, Opt_utf8, Opt_iocharset,
369 Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore 377 Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
378 Opt_fmode, Opt_dmode
370}; 379};
371 380
372static const match_table_t tokens = { 381static const match_table_t tokens = {
@@ -395,6 +404,8 @@ static const match_table_t tokens = {
395 {Opt_rootdir, "rootdir=%u"}, 404 {Opt_rootdir, "rootdir=%u"},
396 {Opt_utf8, "utf8"}, 405 {Opt_utf8, "utf8"},
397 {Opt_iocharset, "iocharset=%s"}, 406 {Opt_iocharset, "iocharset=%s"},
407 {Opt_fmode, "mode=%o"},
408 {Opt_dmode, "dmode=%o"},
398 {Opt_err, NULL} 409 {Opt_err, NULL}
399}; 410};
400 411
@@ -531,6 +542,16 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
531 case Opt_gforget: 542 case Opt_gforget:
532 uopt->flags |= (1 << UDF_FLAG_GID_FORGET); 543 uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
533 break; 544 break;
545 case Opt_fmode:
546 if (match_octal(args, &option))
547 return 0;
548 uopt->fmode = option & 0777;
549 break;
550 case Opt_dmode:
551 if (match_octal(args, &option))
552 return 0;
553 uopt->dmode = option & 0777;
554 break;
534 default: 555 default:
535 printk(KERN_ERR "udf: bad mount option \"%s\" " 556 printk(KERN_ERR "udf: bad mount option \"%s\" "
536 "or missing value\n", p); 557 "or missing value\n", p);
@@ -560,6 +581,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
560 uopt.uid = sbi->s_uid; 581 uopt.uid = sbi->s_uid;
561 uopt.gid = sbi->s_gid; 582 uopt.gid = sbi->s_gid;
562 uopt.umask = sbi->s_umask; 583 uopt.umask = sbi->s_umask;
584 uopt.fmode = sbi->s_fmode;
585 uopt.dmode = sbi->s_dmode;
563 586
564 if (!udf_parse_options(options, &uopt, true)) 587 if (!udf_parse_options(options, &uopt, true))
565 return -EINVAL; 588 return -EINVAL;
@@ -568,6 +591,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
568 sbi->s_uid = uopt.uid; 591 sbi->s_uid = uopt.uid;
569 sbi->s_gid = uopt.gid; 592 sbi->s_gid = uopt.gid;
570 sbi->s_umask = uopt.umask; 593 sbi->s_umask = uopt.umask;
594 sbi->s_fmode = uopt.fmode;
595 sbi->s_dmode = uopt.dmode;
571 596
572 if (sbi->s_lvid_bh) { 597 if (sbi->s_lvid_bh) {
573 int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); 598 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)
1869 uopt.uid = -1; 1894 uopt.uid = -1;
1870 uopt.gid = -1; 1895 uopt.gid = -1;
1871 uopt.umask = 0; 1896 uopt.umask = 0;
1897 uopt.fmode = -1;
1898 uopt.dmode = -1;
1872 1899
1873 sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL); 1900 sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
1874 if (!sbi) 1901 if (!sbi)
@@ -1906,6 +1933,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1906 sbi->s_uid = uopt.uid; 1933 sbi->s_uid = uopt.uid;
1907 sbi->s_gid = uopt.gid; 1934 sbi->s_gid = uopt.gid;
1908 sbi->s_umask = uopt.umask; 1935 sbi->s_umask = uopt.umask;
1936 sbi->s_fmode = uopt.fmode;
1937 sbi->s_dmode = uopt.dmode;
1909 sbi->s_nls_map = uopt.nls_map; 1938 sbi->s_nls_map = uopt.nls_map;
1910 1939
1911 /* Set the block size for all transfers */ 1940 /* Set the block size for all transfers */
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 1c1c514a9725..5d32c609fceb 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -123,6 +123,8 @@ struct udf_sb_info {
123 mode_t s_umask; 123 mode_t s_umask;
124 gid_t s_gid; 124 gid_t s_gid;
125 uid_t s_uid; 125 uid_t s_uid;
126 mode_t s_fmode;
127 mode_t s_dmode;
126 128
127 /* Root Info */ 129 /* Root Info */
128 struct timespec s_record_time; 130 struct timespec s_record_time;