Commit 9769f4eb authored by Jeremy White's avatar Jeremy White Committed by Linus Torvalds

[PATCH] isofs: show hidden files, add granularity for assoc/hidden files flags

The current isofs treatment of hidden files is flawed in two ways.  First,
it does not provide sufficient granularity; it hides both 'hidden' files
and 'associated' files (resource fork for Mac files).  Second, the default
behavior to completely strip hidden files, while an admirable
implementation of the spec, is a poor choice given the real world use of
hidden files as a poor mans copy protection scheme for MSDOS and Windows
based systems.  A longer description of this is available here:

   http://www.uwsg.iu.edu/hypermail/linux/kernel/0205.3/0267.html

This patch was originally built after a few private conversations with Alan
Cox; I shamefully failed to persist in seeing it go forward, I hope to make
amends now.

This patch introduces granularity by allowing explicit control for both
hidden and associated files.  It also reverses the default so that by
default, hidden files are treated as regular files on the iso9660 file
system.

This allow Wine to process Windows CDs, including those that are hybrid
Mac/Windows CDs properly and completely, without our having to go muck up
peoples fstabs as we do now.  (I have tested this with such a hybrid +
hidden CD and have verified that this patch works as claimed).
Signed-off-by: default avatarJeremy White <jwhite@codeweavers.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f2966632
......@@ -26,7 +26,11 @@ Mount options unique to the isofs filesystem.
mode=xxx Sets the permissions on files to xxx
nojoliet Ignore Joliet extensions if they are present.
norock Ignore Rock Ridge extensions if they are present.
unhide Show hidden files.
hide Completely strip hidden files from the file system.
showassoc Show files marked with the 'associated' bit
unhide Deprecated; showing hidden files is now default;
If given, it is a synonym for 'showassoc' which will
recreate previous unhide behavior
session=x Select number of session on multisession CD
sbsector=xxx Session begins from sector xxx
......
......@@ -193,13 +193,18 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
/* Handle everything else. Do name translation if there
is no Rock Ridge NM field. */
if (sbi->s_unhide == 'n') {
/* Do not report hidden or associated files */
if (de->flags[-sbi->s_high_sierra] & 5) {
/*
* Do not report hidden files if so instructed, or associated
* files unless instructed to do so
*/
if ((sbi->s_hide == 'y' &&
(de->flags[-sbi->s_high_sierra] & 1)) ||
(sbi->s_showassoc =='n' &&
(de->flags[-sbi->s_high_sierra] & 4))) {
filp->f_pos += de_len;
continue;
}
}
map = 1;
if (sbi->s_rock) {
......
......@@ -144,7 +144,8 @@ struct iso9660_options{
char rock;
char joliet;
char cruft;
char unhide;
char hide;
char showassoc;
char nocompress;
unsigned char check;
unsigned int blocksize;
......@@ -309,13 +310,15 @@ enum {
Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
Opt_nocompress,
Opt_nocompress, Opt_hide, Opt_showassoc,
};
static match_table_t tokens = {
{Opt_norock, "norock"},
{Opt_nojoliet, "nojoliet"},
{Opt_unhide, "unhide"},
{Opt_hide, "hide"},
{Opt_showassoc, "showassoc"},
{Opt_cruft, "cruft"},
{Opt_utf8, "utf8"},
{Opt_iocharset, "iocharset=%s"},
......@@ -356,7 +359,8 @@ static int parse_options(char *options, struct iso9660_options *popt)
popt->rock = 'y';
popt->joliet = 'y';
popt->cruft = 'n';
popt->unhide = 'n';
popt->hide = 'n';
popt->showassoc = 'n';
popt->check = 'u'; /* unset */
popt->nocompress = 0;
popt->blocksize = 1024;
......@@ -389,8 +393,12 @@ static int parse_options(char *options, struct iso9660_options *popt)
case Opt_nojoliet:
popt->joliet = 'n';
break;
case Opt_hide:
popt->hide = 'y';
break;
case Opt_unhide:
popt->unhide = 'y';
case Opt_showassoc:
popt->showassoc = 'y';
break;
case Opt_cruft:
popt->cruft = 'y';
......@@ -784,7 +792,8 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
sbi->s_rock = (opt.rock == 'y' ? 2 : 0);
sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/
sbi->s_cruft = opt.cruft;
sbi->s_unhide = opt.unhide;
sbi->s_hide = opt.hide;
sbi->s_showassoc = opt.showassoc;
sbi->s_uid = opt.uid;
sbi->s_gid = opt.gid;
sbi->s_utf8 = opt.utf8;
......
......@@ -47,6 +47,8 @@ struct isofs_sb_info {
unsigned char s_nosuid;
unsigned char s_nodev;
unsigned char s_nocompress;
unsigned char s_hide;
unsigned char s_showassoc;
mode_t s_mode;
gid_t s_gid;
......
......@@ -131,14 +131,16 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
}
/*
* Skip hidden or associated files unless unhide is set
* Skip hidden or associated files unless hide or showassoc,
* respectively, is set
*/
match = 0;
if (dlen > 0 &&
(!(de->flags[-sbi->s_high_sierra] & 5)
|| sbi->s_unhide == 'y'))
{
match = (isofs_cmp(dentry,dpnt,dlen) == 0);
(sbi->s_hide =='n' ||
(!(de->flags[-sbi->s_high_sierra] & 1))) &&
(sbi->s_showassoc =='y' ||
(!(de->flags[-sbi->s_high_sierra] & 4)))) {
match = (isofs_cmp(dentry, dpnt, dlen) == 0);
}
if (match) {
isofs_normalize_block_and_offset(de,
......@@ -146,11 +148,11 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
&offset_saved);
*block_rv = block_saved;
*offset_rv = offset_saved;
if (bh) brelse(bh);
brelse(bh);
return 1;
}
}
if (bh) brelse(bh);
brelse(bh);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment