diff options
| -rw-r--r-- | Documentation/filesystems/adfs.txt | 18 | ||||
| -rw-r--r-- | fs/adfs/adfs.h | 21 | ||||
| -rw-r--r-- | fs/adfs/dir_f.c | 23 | ||||
| -rw-r--r-- | fs/adfs/dir_fplus.c | 18 | ||||
| -rw-r--r-- | fs/adfs/inode.c | 22 | ||||
| -rw-r--r-- | fs/adfs/super.c | 23 |
6 files changed, 99 insertions, 26 deletions
diff --git a/Documentation/filesystems/adfs.txt b/Documentation/filesystems/adfs.txt index 9e8811f92b84..5949766353f7 100644 --- a/Documentation/filesystems/adfs.txt +++ b/Documentation/filesystems/adfs.txt | |||
| @@ -9,6 +9,9 @@ Mount options for ADFS | |||
| 9 | will be nnn. Default 0700. | 9 | will be nnn. Default 0700. |
| 10 | othmask=nnn The permission mask for ADFS 'other' permissions | 10 | othmask=nnn The permission mask for ADFS 'other' permissions |
| 11 | will be nnn. Default 0077. | 11 | will be nnn. Default 0077. |
| 12 | ftsuffix=n When ftsuffix=0, no file type suffix will be applied. | ||
| 13 | When ftsuffix=1, a hexadecimal suffix corresponding to | ||
| 14 | the RISC OS file type will be added. Default 0. | ||
| 12 | 15 | ||
| 13 | Mapping of ADFS permissions to Linux permissions | 16 | Mapping of ADFS permissions to Linux permissions |
| 14 | ------------------------------------------------ | 17 | ------------------------------------------------ |
| @@ -55,3 +58,18 @@ Mapping of ADFS permissions to Linux permissions | |||
| 55 | 58 | ||
| 56 | You can therefore tailor the permission translation to whatever you | 59 | You can therefore tailor the permission translation to whatever you |
| 57 | desire the permissions should be under Linux. | 60 | desire the permissions should be under Linux. |
| 61 | |||
| 62 | RISC OS file type suffix | ||
| 63 | ------------------------ | ||
| 64 | |||
| 65 | RISC OS file types are stored in bits 19..8 of the file load address. | ||
| 66 | |||
| 67 | To enable non-RISC OS systems to be used to store files without losing | ||
| 68 | file type information, a file naming convention was devised (initially | ||
| 69 | for use with NFS) such that a hexadecimal suffix of the form ,xyz | ||
| 70 | denoted the file type: e.g. BasicFile,ffb is a BASIC (0xffb) file. This | ||
| 71 | naming convention is now also used by RISC OS emulators such as RPCEmu. | ||
| 72 | |||
| 73 | Mounting an ADFS disc with option ftsuffix=1 will cause appropriate file | ||
| 74 | type suffixes to be appended to file names read from a directory. If the | ||
| 75 | ftsuffix option is zero or omitted, no file type suffixes will be added. | ||
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index 58588ddb178c..a8a58d864f96 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h | |||
| @@ -50,6 +50,7 @@ struct adfs_sb_info { | |||
| 50 | gid_t s_gid; /* owner gid */ | 50 | gid_t s_gid; /* owner gid */ |
| 51 | umode_t s_owner_mask; /* ADFS owner perm -> unix perm */ | 51 | umode_t s_owner_mask; /* ADFS owner perm -> unix perm */ |
| 52 | umode_t s_other_mask; /* ADFS other perm -> unix perm */ | 52 | umode_t s_other_mask; /* ADFS other perm -> unix perm */ |
| 53 | int s_ftsuffix; /* ,xyz hex filetype suffix option */ | ||
| 53 | 54 | ||
| 54 | __u32 s_ids_per_zone; /* max. no ids in one zone */ | 55 | __u32 s_ids_per_zone; /* max. no ids in one zone */ |
| 55 | __u32 s_idlen; /* length of ID in map */ | 56 | __u32 s_idlen; /* length of ID in map */ |
| @@ -93,7 +94,7 @@ struct adfs_dir { | |||
| 93 | /* | 94 | /* |
| 94 | * This is the overall maximum name length | 95 | * This is the overall maximum name length |
| 95 | */ | 96 | */ |
| 96 | #define ADFS_MAX_NAME_LEN 256 | 97 | #define ADFS_MAX_NAME_LEN (256 + 4) /* +4 for ,xyz hex filetype suffix */ |
| 97 | struct object_info { | 98 | struct object_info { |
| 98 | __u32 parent_id; /* parent object id */ | 99 | __u32 parent_id; /* parent object id */ |
| 99 | __u32 file_id; /* object id */ | 100 | __u32 file_id; /* object id */ |
| @@ -101,10 +102,26 @@ struct object_info { | |||
| 101 | __u32 execaddr; /* execution address */ | 102 | __u32 execaddr; /* execution address */ |
| 102 | __u32 size; /* size */ | 103 | __u32 size; /* size */ |
| 103 | __u8 attr; /* RISC OS attributes */ | 104 | __u8 attr; /* RISC OS attributes */ |
| 104 | unsigned char name_len; /* name length */ | 105 | unsigned int name_len; /* name length */ |
| 105 | char name[ADFS_MAX_NAME_LEN];/* file name */ | 106 | char name[ADFS_MAX_NAME_LEN];/* file name */ |
| 107 | |||
| 108 | /* RISC OS file type (12-bit: derived from loadaddr) */ | ||
| 109 | __u16 filetype; | ||
| 106 | }; | 110 | }; |
| 107 | 111 | ||
| 112 | /* RISC OS 12-bit filetype converts to ,xyz hex filename suffix */ | ||
| 113 | static inline int append_filetype_suffix(char *buf, __u16 filetype) | ||
| 114 | { | ||
| 115 | if (filetype == -1) | ||
| 116 | return 0; | ||
| 117 | |||
| 118 | *buf++ = ','; | ||
| 119 | *buf++ = hex_asc_lo(filetype >> 8); | ||
| 120 | *buf++ = hex_asc_lo(filetype >> 4); | ||
| 121 | *buf++ = hex_asc_lo(filetype >> 0); | ||
| 122 | return 4; | ||
| 123 | } | ||
| 124 | |||
| 108 | struct adfs_dir_ops { | 125 | struct adfs_dir_ops { |
| 109 | int (*read)(struct super_block *sb, unsigned int id, unsigned int sz, struct adfs_dir *dir); | 126 | int (*read)(struct super_block *sb, unsigned int id, unsigned int sz, struct adfs_dir *dir); |
| 110 | int (*setpos)(struct adfs_dir *dir, unsigned int fpos); | 127 | int (*setpos)(struct adfs_dir *dir, unsigned int fpos); |
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c index bafc71222e25..4bbe853ee50a 100644 --- a/fs/adfs/dir_f.c +++ b/fs/adfs/dir_f.c | |||
| @@ -52,7 +52,6 @@ static inline int adfs_readname(char *buf, char *ptr, int maxlen) | |||
| 52 | *buf++ = *ptr; | 52 | *buf++ = *ptr; |
| 53 | ptr++; | 53 | ptr++; |
| 54 | } | 54 | } |
| 55 | *buf = '\0'; | ||
| 56 | 55 | ||
| 57 | return buf - old_buf; | 56 | return buf - old_buf; |
| 58 | } | 57 | } |
| @@ -208,7 +207,8 @@ release_buffers: | |||
| 208 | * convert a disk-based directory entry to a Linux ADFS directory entry | 207 | * convert a disk-based directory entry to a Linux ADFS directory entry |
| 209 | */ | 208 | */ |
| 210 | static inline void | 209 | static inline void |
| 211 | adfs_dir2obj(struct object_info *obj, struct adfs_direntry *de) | 210 | adfs_dir2obj(struct adfs_dir *dir, struct object_info *obj, |
| 211 | struct adfs_direntry *de) | ||
| 212 | { | 212 | { |
| 213 | obj->name_len = adfs_readname(obj->name, de->dirobname, ADFS_F_NAME_LEN); | 213 | obj->name_len = adfs_readname(obj->name, de->dirobname, ADFS_F_NAME_LEN); |
| 214 | obj->file_id = adfs_readval(de->dirinddiscadd, 3); | 214 | obj->file_id = adfs_readval(de->dirinddiscadd, 3); |
| @@ -216,6 +216,23 @@ adfs_dir2obj(struct object_info *obj, struct adfs_direntry *de) | |||
| 216 | obj->execaddr = adfs_readval(de->direxec, 4); | 216 | obj->execaddr = adfs_readval(de->direxec, 4); |
| 217 | obj->size = adfs_readval(de->dirlen, 4); | 217 | obj->size = adfs_readval(de->dirlen, 4); |
| 218 | obj->attr = de->newdiratts; | 218 | obj->attr = de->newdiratts; |
| 219 | obj->filetype = -1; | ||
| 220 | |||
| 221 | /* | ||
| 222 | * object is a file and is filetyped and timestamped? | ||
| 223 | * RISC OS 12-bit filetype is stored in load_address[19:8] | ||
| 224 | */ | ||
| 225 | if ((0 == (obj->attr & ADFS_NDA_DIRECTORY)) && | ||
| 226 | (0xfff00000 == (0xfff00000 & obj->loadaddr))) { | ||
| 227 | obj->filetype = (__u16) ((0x000fff00 & obj->loadaddr) >> 8); | ||
| 228 | |||
| 229 | /* optionally append the ,xyz hex filetype suffix */ | ||
| 230 | if (ADFS_SB(dir->sb)->s_ftsuffix) | ||
| 231 | obj->name_len += | ||
| 232 | append_filetype_suffix( | ||
| 233 | &obj->name[obj->name_len], | ||
| 234 | obj->filetype); | ||
| 235 | } | ||
| 219 | } | 236 | } |
| 220 | 237 | ||
| 221 | /* | 238 | /* |
| @@ -260,7 +277,7 @@ __adfs_dir_get(struct adfs_dir *dir, int pos, struct object_info *obj) | |||
| 260 | if (!de.dirobname[0]) | 277 | if (!de.dirobname[0]) |
| 261 | return -ENOENT; | 278 | return -ENOENT; |
| 262 | 279 | ||
| 263 | adfs_dir2obj(obj, &de); | 280 | adfs_dir2obj(dir, obj, &de); |
| 264 | 281 | ||
| 265 | return 0; | 282 | return 0; |
| 266 | } | 283 | } |
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c index a7f41da8115b..d9e3bee4e653 100644 --- a/fs/adfs/dir_fplus.c +++ b/fs/adfs/dir_fplus.c | |||
| @@ -197,6 +197,24 @@ adfs_fplus_getnext(struct adfs_dir *dir, struct object_info *obj) | |||
| 197 | if (obj->name[i] == '/') | 197 | if (obj->name[i] == '/') |
| 198 | obj->name[i] = '.'; | 198 | obj->name[i] = '.'; |
| 199 | 199 | ||
| 200 | obj->filetype = -1; | ||
| 201 | |||
| 202 | /* | ||
| 203 | * object is a file and is filetyped and timestamped? | ||
| 204 | * RISC OS 12-bit filetype is stored in load_address[19:8] | ||
| 205 | */ | ||
| 206 | if ((0 == (obj->attr & ADFS_NDA_DIRECTORY)) && | ||
| 207 | (0xfff00000 == (0xfff00000 & obj->loadaddr))) { | ||
| 208 | obj->filetype = (__u16) ((0x000fff00 & obj->loadaddr) >> 8); | ||
| 209 | |||
| 210 | /* optionally append the ,xyz hex filetype suffix */ | ||
| 211 | if (ADFS_SB(dir->sb)->s_ftsuffix) | ||
| 212 | obj->name_len += | ||
| 213 | append_filetype_suffix( | ||
| 214 | &obj->name[obj->name_len], | ||
| 215 | obj->filetype); | ||
| 216 | } | ||
| 217 | |||
| 200 | dir->pos += 1; | 218 | dir->pos += 1; |
| 201 | ret = 0; | 219 | ret = 0; |
| 202 | out: | 220 | out: |
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 16d7ef2dffe1..92444e94f842 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
| @@ -78,26 +78,13 @@ static const struct address_space_operations adfs_aops = { | |||
| 78 | .bmap = _adfs_bmap | 78 | .bmap = _adfs_bmap |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | static inline unsigned int | ||
| 82 | adfs_filetype(struct inode *inode) | ||
| 83 | { | ||
| 84 | unsigned int type; | ||
| 85 | |||
| 86 | if (ADFS_I(inode)->stamped) | ||
| 87 | type = (ADFS_I(inode)->loadaddr >> 8) & 0xfff; | ||
| 88 | else | ||
| 89 | type = (unsigned int) -1; | ||
| 90 | |||
| 91 | return type; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | 81 | /* |
| 95 | * Convert ADFS attributes and filetype to Linux permission. | 82 | * Convert ADFS attributes and filetype to Linux permission. |
| 96 | */ | 83 | */ |
| 97 | static umode_t | 84 | static umode_t |
| 98 | adfs_atts2mode(struct super_block *sb, struct inode *inode) | 85 | adfs_atts2mode(struct super_block *sb, struct inode *inode) |
