aboutsummaryrefslogtreecommitdiffstats
path: root/fs/isofs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/isofs/inode.c')
-rw-r--r--fs/isofs/inode.c118
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
143struct iso9660_options{ 143struct 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
318static const match_table_t tokens = { 321static 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
674root_found: 681root_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
1098static inline void test_and_set_uid(uid_t *p, uid_t value)
1099{
1100 if (value)
1101 *p = value;
1102}
1103
1104static inline void test_and_set_gid(gid_t *p, gid_t value)
1105{
1106 if (value)
1107 *p = value;
1108}
1109
1110static int isofs_read_level3_size(struct inode *inode) 1114static 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)) {