diff options
Diffstat (limited to 'fs/isofs/inode.c')
-rw-r--r-- | fs/isofs/inode.c | 118 |
1 files changed, 71 insertions, 47 deletions
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 068b34b5a107..58a7963e168a 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -141,13 +141,17 @@ static const struct dentry_operations isofs_dentry_ops[] = { | |||
141 | }; | 141 | }; |
142 | 142 | ||
143 | struct iso9660_options{ | 143 | struct iso9660_options{ |
144 | char map; | 144 | unsigned int rock:1; |
145 | char rock; | 145 | unsigned int cruft:1; |
146 | unsigned int hide:1; | ||
147 | unsigned int showassoc:1; | ||
148 | unsigned int nocompress:1; | ||
149 | unsigned int overriderockperm:1; | ||
150 | unsigned int uid_set:1; | ||
151 | unsigned int gid_set:1; | ||
152 | unsigned int utf8:1; | ||
153 | unsigned char map; | ||
146 | char joliet; | 154 | char joliet; |
147 | char cruft; | ||
148 | char hide; | ||
149 | char showassoc; | ||
150 | char nocompress; | ||
151 | unsigned char check; | 155 | unsigned char check; |
152 | unsigned int blocksize; | 156 | unsigned int blocksize; |
153 | mode_t fmode; | 157 | mode_t fmode; |
@@ -155,7 +159,6 @@ struct iso9660_options{ | |||
155 | gid_t gid; | 159 | gid_t gid; |
156 | uid_t uid; | 160 | uid_t uid; |
157 | char *iocharset; | 161 | char *iocharset; |
158 | unsigned char utf8; | ||
159 | /* LVE */ | 162 | /* LVE */ |
160 | s32 session; | 163 | s32 session; |
161 | s32 sbsector; | 164 | s32 sbsector; |
@@ -312,7 +315,7 @@ enum { | |||
312 | Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, | 315 | Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, |
313 | Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, | 316 | Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, |
314 | Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, | 317 | Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, |
315 | Opt_nocompress, Opt_hide, Opt_showassoc, Opt_dmode, | 318 | Opt_nocompress, Opt_hide, Opt_showassoc, Opt_dmode, Opt_overriderockperm, |
316 | }; | 319 | }; |
317 | 320 | ||
318 | static const match_table_t tokens = { | 321 | static const match_table_t tokens = { |
@@ -340,6 +343,7 @@ static const match_table_t tokens = { | |||
340 | {Opt_gid, "gid=%u"}, | 343 | {Opt_gid, "gid=%u"}, |
341 | {Opt_mode, "mode=%u"}, | 344 | {Opt_mode, "mode=%u"}, |
342 | {Opt_dmode, "dmode=%u"}, | 345 | {Opt_dmode, "dmode=%u"}, |
346 | {Opt_overriderockperm, "overriderockperm"}, | ||
343 | {Opt_block, "block=%u"}, | 347 | {Opt_block, "block=%u"}, |
344 | {Opt_ignore, "conv=binary"}, | 348 | {Opt_ignore, "conv=binary"}, |
345 | {Opt_ignore, "conv=b"}, | 349 | {Opt_ignore, "conv=b"}, |
@@ -359,24 +363,22 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
359 | int option; | 363 | int option; |
360 | 364 | ||
361 | popt->map = 'n'; | 365 | popt->map = 'n'; |
362 | popt->rock = 'y'; | 366 | popt->rock = 1; |
363 | popt->joliet = 'y'; | 367 | popt->joliet = 1; |
364 | popt->cruft = 'n'; | 368 | popt->cruft = 0; |
365 | popt->hide = 'n'; | 369 | popt->hide = 0; |
366 | popt->showassoc = 'n'; | 370 | popt->showassoc = 0; |
367 | popt->check = 'u'; /* unset */ | 371 | popt->check = 'u'; /* unset */ |
368 | popt->nocompress = 0; | 372 | popt->nocompress = 0; |
369 | popt->blocksize = 1024; | 373 | popt->blocksize = 1024; |
370 | popt->fmode = popt->dmode = S_IRUGO | S_IXUGO; /* | 374 | popt->fmode = popt->dmode = ISOFS_INVALID_MODE; |
371 | * r-x for all. The disc could | 375 | popt->uid_set = 0; |
372 | * be shared with DOS machines so | 376 | popt->gid_set = 0; |
373 | * virtually anything could be | ||
374 | * a valid executable. | ||
375 | */ | ||
376 | popt->gid = 0; | 377 | popt->gid = 0; |
377 | popt->uid = 0; | 378 | popt->uid = 0; |
378 | popt->iocharset = NULL; | 379 | popt->iocharset = NULL; |
379 | popt->utf8 = 0; | 380 | popt->utf8 = 0; |
381 | popt->overriderockperm = 0; | ||
380 | popt->session=-1; | 382 | popt->session=-1; |
381 | popt->sbsector=-1; | 383 | popt->sbsector=-1; |
382 | if (!options) | 384 | if (!options) |
@@ -393,20 +395,20 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
393 | token = match_token(p, tokens, args); | 395 | token = match_token(p, tokens, args); |
394 | switch (token) { | 396 | switch (token) { |
395 | case Opt_norock: | 397 | case Opt_norock: |
396 | popt->rock = 'n'; | 398 | popt->rock = 0; |
397 | break; | 399 | break; |
398 | case Opt_nojoliet: | 400 | case Opt_nojoliet: |
399 | popt->joliet = 'n'; | 401 | popt->joliet = 0; |
400 | break; | 402 | break; |
401 | case Opt_hide: | 403 | case Opt_hide: |
402 | popt->hide = 'y'; | 404 | popt->hide = 1; |
403 | break; | 405 | break; |
404 | case Opt_unhide: | 406 | case Opt_unhide: |
405 | case Opt_showassoc: | 407 | case Opt_showassoc: |
406 | popt->showassoc = 'y'; | 408 | popt->showassoc = 1; |
407 | break; | 409 | break; |
408 | case Opt_cruft: | 410 | case Opt_cruft: |
409 | popt->cruft = 'y'; | 411 | popt->cruft = 1; |
410 | break; | 412 | break; |
411 | case Opt_utf8: | 413 | case Opt_utf8: |
412 | popt->utf8 = 1; | 414 | popt->utf8 = 1; |
@@ -450,11 +452,13 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
450 | if (match_int(&args[0], &option)) | 452 | if (match_int(&args[0], &option)) |
451 | return 0; | 453 | return 0; |
452 | popt->uid = option; | 454 | popt->uid = option; |
455 | popt->uid_set = 1; | ||
453 | break; | 456 | break; |
454 | case Opt_gid: | 457 | case Opt_gid: |
455 | if (match_int(&args[0], &option)) | 458 | if (match_int(&args[0], &option)) |
456 | return 0; | 459 | return 0; |
457 | popt->gid = option; | 460 | popt->gid = option; |
461 | popt->gid_set = 1; | ||
458 | break; | 462 | break; |
459 | case Opt_mode: | 463 | case Opt_mode: |
460 | if (match_int(&args[0], &option)) | 464 | if (match_int(&args[0], &option)) |
@@ -466,6 +470,9 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
466 | return 0; | 470 | return 0; |
467 | popt->dmode = option; | 471 | popt->dmode = option; |
468 | break; | 472 | break; |
473 | case Opt_overriderockperm: | ||
474 | popt->overriderockperm = 1; | ||
475 | break; | ||
469 | case Opt_block: | 476 | case Opt_block: |
470 | if (match_int(&args[0], &option)) | 477 | if (match_int(&args[0], &option)) |
471 | return 0; | 478 | return 0; |
@@ -650,7 +657,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
650 | goto out_freebh; | 657 | goto out_freebh; |
651 | 658 | ||
652 | sbi->s_high_sierra = 1; | 659 | sbi->s_high_sierra = 1; |
653 | opt.rock = 'n'; | 660 | opt.rock = 0; |
654 | h_pri = (struct hs_primary_descriptor *)vdp; | 661 | h_pri = (struct hs_primary_descriptor *)vdp; |
655 | goto root_found; | 662 | goto root_found; |
656 | } | 663 | } |
@@ -673,7 +680,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
673 | 680 | ||
674 | root_found: | 681 | root_found: |
675 | 682 | ||
676 | if (joliet_level && (pri == NULL || opt.rock == 'n')) { | 683 | if (joliet_level && (pri == NULL || !opt.rock)) { |
677 | /* This is the case of Joliet with the norock mount flag. | 684 | /* This is the case of Joliet with the norock mount flag. |
678 | * A disc with both Joliet and Rock Ridge is handled later | 685 | * A disc with both Joliet and Rock Ridge is handled later |
679 | */ | 686 | */ |
@@ -802,22 +809,31 @@ root_found: | |||
802 | s->s_op = &isofs_sops; | 809 | s->s_op = &isofs_sops; |
803 | s->s_export_op = &isofs_export_ops; | 810 | s->s_export_op = &isofs_export_ops; |
804 | sbi->s_mapping = opt.map; | 811 | sbi->s_mapping = opt.map; |
805 | sbi->s_rock = (opt.rock == 'y' ? 2 : 0); | 812 | sbi->s_rock = (opt.rock ? 2 : 0); |
806 | sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ | 813 | sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ |
807 | sbi->s_cruft = opt.cruft; | 814 | sbi->s_cruft = opt.cruft; |
808 | sbi->s_hide = opt.hide; | 815 | sbi->s_hide = opt.hide; |
809 | sbi->s_showassoc = opt.showassoc; | 816 | sbi->s_showassoc = opt.showassoc; |
810 | sbi->s_uid = opt.uid; | 817 | sbi->s_uid = opt.uid; |
811 | sbi->s_gid = opt.gid; | 818 | sbi->s_gid = opt.gid; |
819 | sbi->s_uid_set = opt.uid_set; | ||
820 | sbi->s_gid_set = opt.gid_set; | ||
812 | sbi->s_utf8 = opt.utf8; | 821 | sbi->s_utf8 = opt.utf8; |
813 | sbi->s_nocompress = opt.nocompress; | 822 | sbi->s_nocompress = opt.nocompress; |
823 | sbi->s_overriderockperm = opt.overriderockperm; | ||
814 | /* | 824 | /* |
815 | * It would be incredibly stupid to allow people to mark every file | 825 | * It would be incredibly stupid to allow people to mark every file |
816 | * on the disk as suid, so we merely allow them to set the default | 826 | * on the disk as suid, so we merely allow them to set the default |
817 | * permissions. | 827 | * permissions. |
818 | */ | 828 | */ |
819 | sbi->s_fmode = opt.fmode & 0777; | 829 | if (opt.fmode != ISOFS_INVALID_MODE) |
820 | sbi->s_dmode = opt.dmode & 0777; | 830 | sbi->s_fmode = opt.fmode & 0777; |
831 | else | ||
832 | sbi->s_fmode = ISOFS_INVALID_MODE; | ||
833 | if (opt.dmode != ISOFS_INVALID_MODE) | ||
834 | sbi->s_dmode = opt.dmode & 0777; | ||
835 | else | ||
836 | sbi->s_dmode = ISOFS_INVALID_MODE; | ||
821 | 837 | ||
822 | /* | 838 | /* |
823 | * Read the root inode, which _may_ result in changing | 839 | * Read the root inode, which _may_ result in changing |
@@ -1095,18 +1111,6 @@ static const struct address_space_operations isofs_aops = { | |||
1095 | .bmap = _isofs_bmap | 1111 | .bmap = _isofs_bmap |
1096 | }; | 1112 | }; |
1097 | 1113 | ||
1098 | static inline void test_and_set_uid(uid_t *p, uid_t value) | ||
1099 | { | ||
1100 | if (value) | ||
1101 | *p = value; | ||
1102 | } | ||
1103 | |||
1104 | static inline void test_and_set_gid(gid_t *p, gid_t value) | ||
1105 | { | ||
1106 | if (value) | ||
1107 | *p = value; | ||
1108 | } | ||
1109 | |||
1110 | static int isofs_read_level3_size(struct inode *inode) | 1114 | static int isofs_read_level3_size(struct inode *inode) |
1111 | { | 1115 | { |
1112 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); | 1116 | unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); |
@@ -1261,7 +1265,10 @@ static int isofs_read_inode(struct inode *inode) | |||
1261 | ei->i_file_format = isofs_file_normal; | 1265 | ei->i_file_format = isofs_file_normal; |
1262 | 1266 | ||
1263 | if (de->flags[-high_sierra] & 2) { | 1267 | if (de->flags[-high_sierra] & 2) { |
1264 | inode->i_mode = sbi->s_dmode | S_IFDIR; | 1268 | if (sbi->s_dmode != ISOFS_INVALID_MODE) |
1269 | inode->i_mode = S_IFDIR | sbi->s_dmode; | ||
1270 | else | ||
1271 | inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; | ||
1265 | inode->i_nlink = 1; /* | 1272 | inode->i_nlink = 1; /* |
1266 | * Set to 1. We know there are 2, but | 1273 | * Set to 1. We know there are 2, but |
1267 | * the find utility tries to optimize | 1274 | * the find utility tries to optimize |
@@ -1270,8 +1277,16 @@ static int isofs_read_inode(struct inode *inode) | |||
1270 | * do it the hard way. | 1277 | * do it the hard way. |
1271 | */ | 1278 | */ |
1272 | } else { | 1279 | } else { |
1273 | /* Everybody gets to read the file. */ | 1280 | if (sbi->s_fmode != ISOFS_INVALID_MODE) { |
1274 | inode->i_mode = sbi->s_fmode | S_IFREG; | 1281 | inode->i_mode = S_IFREG | sbi->s_fmode; |
1282 | } else { | ||
1283 | /* | ||
1284 | * Set default permissions: r-x for all. The disc | ||
1285 | * could be shared with DOS machines so virtually | ||
1286 | * anything could be a valid executable. | ||
1287 | */ | ||
1288 | inode->i_mode = S_IFREG | S_IRUGO | S_IXUGO; | ||
1289 | } | ||
1275 | inode->i_nlink = 1; | 1290 | inode->i_nlink = 1; |
1276 | } | 1291 | } |
1277 | inode->i_uid = sbi->s_uid; | 1292 | inode->i_uid = sbi->s_uid; |
@@ -1300,7 +1315,7 @@ static int isofs_read_inode(struct inode *inode) | |||
1300 | * this CDROM was mounted with the cruft option. | 1315 | * this CDROM was mounted with the cruft option. |
1301 | */ | 1316 | */ |
1302 | 1317 | ||
1303 | if (sbi->s_cruft == 'y') | 1318 | if (sbi->s_cruft) |
1304 | inode->i_size &= 0x00ffffff; | 1319 | inode->i_size &= 0x00ffffff; |
1305 | 1320 | ||
1306 | if (de->interleave[0]) { | 1321 | if (de->interleave[0]) { |
@@ -1346,9 +1361,18 @@ static int isofs_read_inode(struct inode *inode) | |||
1346 | if (!high_sierra) { | 1361 | if (!high_sierra) { |
1347 | parse_rock_ridge_inode(de, inode); | 1362 | parse_rock_ridge_inode(de, inode); |
1348 | /* if we want uid/gid set, override the rock ridge setting */ | 1363 | /* if we want uid/gid set, override the rock ridge setting */ |
1349 | test_and_set_uid(&inode->i_uid, sbi->s_uid); | 1364 | if (sbi->s_uid_set) |
1350 | test_and_set_gid(&inode->i_gid, sbi->s_gid); | 1365 | inode->i_uid = sbi->s_uid; |
1366 | if (sbi->s_gid_set) | ||
1367 | inode->i_gid = sbi->s_gid; | ||
1351 | } | 1368 | } |
1369 | /* Now set final access rights if overriding rock ridge setting */ | ||
1370 | if (S_ISDIR(inode->i_mode) && sbi->s_overriderockperm && | ||
1371 | sbi->s_dmode != ISOFS_INVALID_MODE) | ||
1372 | inode->i_mode = S_IFDIR | sbi->s_dmode; | ||
1373 | if (S_ISREG(inode->i_mode) && sbi->s_overriderockperm && | ||
1374 | sbi->s_fmode != ISOFS_INVALID_MODE) | ||
1375 | inode->i_mode = S_IFREG | sbi->s_fmode; | ||
1352 | 1376 | ||
1353 | /* Install the inode operations vector */ | 1377 | /* Install the inode operations vector */ |
1354 | if (S_ISREG(inode->i_mode)) { | 1378 | if (S_ISREG(inode->i_mode)) { |