diff options
-rw-r--r-- | Documentation/filesystems/udf.txt | 2 | ||||
-rw-r--r-- | fs/udf/inode.c | 11 | ||||
-rw-r--r-- | fs/udf/super.c | 31 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 2 |
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 | ||
372 | static const match_table_t tokens = { | 381 | static 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; |