2 * linux/fs/adfs/inode.c
4 * Copyright (C) 1997 Russell King
7 #include <linux/errno.h>
9 #include <linux/adfs_fs.h>
10 #include <linux/sched.h>
11 #include <linux/stat.h>
12 #include <linux/string.h>
13 #include <linux/locks.h>
18 * bit 30 - 16 FragID of parent object
20 * bit 14 - 0 FragID of object Offset into parent FragID
23 * Inode = Frag ID of parent (14) + Frag Offset (8) + (index into directory + 1)(8)
25 #define inode_frag(ino) ((ino) >> 8)
26 #define inode_idx(ino) ((ino) & 0xff)
27 #define inode_dirindex(idx) (((idx) & 0xff) * 26 - 21)
29 #define frag_id(x) (((x) >> 8) & 0x7fff)
30 #define off(x) (((x) & 0xff) ? (((x) & 0xff) - 1) << sb->u.adfs_sb.s_dr->log2sharesize : 0)
32 static inline int adfs_inode_validate_no (struct super_block
*sb
, unsigned int inode_no
)
34 unsigned long max_frag_id
;
36 max_frag_id
= sb
->u
.adfs_sb
.s_map_size
* sb
->u
.adfs_sb
.s_ids_per_zone
;
38 return (inode_no
& 0x800000ff) ||
39 (frag_id (inode_frag (inode_no
)) > max_frag_id
) ||
40 (frag_id (inode_frag (inode_no
)) < 2);
43 int adfs_inode_validate (struct inode
*inode
)
45 struct super_block
*sb
= inode
->i_sb
;
47 return adfs_inode_validate_no (sb
, inode
->i_ino
& 0xffffff00) ||
48 adfs_inode_validate_no (sb
, inode
->u
.adfs_i
.file_id
<< 8);
51 unsigned long adfs_inode_generate (unsigned long parent_id
, int diridx
)
57 diridx
= (diridx
+ 21) / 26;
59 return (parent_id
<< 8) | diridx
;
62 unsigned long adfs_inode_objid (struct inode
*inode
)
64 if (adfs_inode_validate (inode
)) {
65 adfs_error (inode
->i_sb
, "adfs_inode_objid",
66 "bad inode number: %lu (%X,%X)",
67 inode
->i_ino
, inode
->i_ino
, inode
->u
.adfs_i
.file_id
);
71 return inode
->u
.adfs_i
.file_id
;
74 int adfs_bmap (struct inode
*inode
, int block
)
76 struct super_block
*sb
= inode
->i_sb
;
79 if (adfs_inode_validate (inode
)) {
80 adfs_error (sb
, "adfs_bmap",
81 "bad inode number: %lu (%X,%X)",
82 inode
->i_ino
, inode
->i_ino
, inode
->u
.adfs_i
.file_id
);
87 adfs_error(sb
, "adfs_bmap", "block(%d) < 0", block
);
91 if (block
> inode
->i_blocks
)
94 block
+= off(inode
->u
.adfs_i
.file_id
);
96 if (frag_id(inode
->u
.adfs_i
.file_id
) == ADFS_ROOT_FRAG
)
97 blk
= sb
->u
.adfs_sb
.s_map_block
+ block
;
99 blk
= adfs_map_lookup (sb
, frag_id(inode
->u
.adfs_i
.file_id
), block
);
103 unsigned int adfs_parent_bmap (struct inode
*inode
, int block
)
105 struct super_block
*sb
= inode
->i_sb
;
106 unsigned int blk
, fragment
;
108 if (adfs_inode_validate_no (sb
, inode
->i_ino
& 0xffffff00)) {
109 adfs_error (sb
, "adfs_parent_bmap",
110 "bad inode number: %lu (%X,%X)",
111 inode
->i_ino
, inode
->i_ino
, inode
->u
.adfs_i
.file_id
);
115 fragment
= inode_frag (inode
->i_ino
);
116 if (frag_id (fragment
) == ADFS_ROOT_FRAG
)
117 blk
= sb
->u
.adfs_sb
.s_map_block
+ off(fragment
) + block
;
119 blk
= adfs_map_lookup (sb
, frag_id (fragment
), off(fragment
) + block
);
123 static int adfs_atts2mode(struct super_block
*sb
, unsigned char mode
, unsigned int filetype
)
127 if (filetype
== 0xfc0 /* LinkFS */) {
128 omode
= S_IFLNK
|S_IRUSR
|S_IWUSR
|S_IXUSR
|
129 S_IRGRP
|S_IWGRP
|S_IXGRP
|
130 S_IROTH
|S_IWOTH
|S_IXOTH
;
132 if (mode
& ADFS_NDA_DIRECTORY
) {
133 omode
|= S_IRUGO
& sb
->u
.adfs_sb
.s_owner_mask
;
134 omode
|= S_IFDIR
|S_IXUSR
|S_IXGRP
|S_IXOTH
;
138 if (mode
& ADFS_NDA_OWNER_READ
) {
139 omode
|= S_IRUGO
& sb
->u
.adfs_sb
.s_owner_mask
;
140 if (filetype
== 0xfe6 /* UnixExec */)
141 omode
|= S_IXUGO
& sb
->u
.adfs_sb
.s_owner_mask
;
144 if (mode
& ADFS_NDA_OWNER_WRITE
)
145 omode
|= S_IWUGO
& sb
->u
.adfs_sb
.s_owner_mask
;
147 if (mode
& ADFS_NDA_PUBLIC_READ
) {
148 omode
|= S_IRUGO
& sb
->u
.adfs_sb
.s_other_mask
;
149 if (filetype
== 0xfe6 /* UnixExec */)
150 omode
|= S_IXUGO
& sb
->u
.adfs_sb
.s_other_mask
;
153 if (mode
& ADFS_NDA_PUBLIC_WRITE
)
154 omode
|= S_IWUGO
& sb
->u
.adfs_sb
.s_other_mask
;
159 void adfs_read_inode (struct inode
*inode
)
161 struct super_block
*sb
;
162 struct buffer_head
*bh
[4];
163 struct adfs_idir_entry ide
;
167 inode
->i_uid
= sb
->u
.adfs_sb
.s_uid
;
168 inode
->i_gid
= sb
->u
.adfs_sb
.s_gid
;
169 inode
->i_version
= ++event
;
171 if (adfs_inode_validate_no (sb
, inode
->i_ino
& 0xffffff00)) {
172 adfs_error (sb
, "adfs_read_inode",
173 "bad inode number: %lu", inode
->i_ino
);
177 if (frag_id(inode_frag (inode
->i_ino
)) == ADFS_ROOT_FRAG
&&
178 inode_idx (inode
->i_ino
) == 0) {
180 inode
->i_mode
= S_IRWXUGO
| S_IFDIR
;
182 inode
->i_size
= ADFS_NEWDIR_SIZE
;
183 inode
->i_blksize
= PAGE_SIZE
;
184 inode
->i_blocks
= inode
->i_size
/ sb
->s_blocksize
;
188 inode
->u
.adfs_i
.file_id
= inode_frag (inode
->i_ino
);
190 if (!(buffers
= adfs_dir_read_parent (inode
, bh
)))
193 if (adfs_dir_check (inode
, bh
, buffers
, NULL
)) {
194 adfs_dir_free (bh
, buffers
);
198 if (!adfs_dir_find_entry (sb
, bh
, buffers
, inode_dirindex (inode
->i_ino
), &ide
)) {
199 adfs_dir_free (bh
, buffers
);
202 adfs_dir_free (bh
, buffers
);
203 inode
->i_mode
= adfs_atts2mode(sb
, ide
.mode
, ide
.filetype
);
205 inode
->i_size
= ide
.size
;
206 inode
->i_blksize
= PAGE_SIZE
;
207 inode
->i_blocks
= (inode
->i_size
+ sb
->s_blocksize
- 1) >> sb
->s_blocksize_bits
;
210 inode
->i_ctime
= ide
.mtime
;
211 inode
->u
.adfs_i
.file_id
= ide
.file_id
;
214 if (S_ISDIR(inode
->i_mode
))
215 inode
->i_op
= &adfs_dir_inode_operations
;
216 else if (S_ISREG(inode
->i_mode
))
217 inode
->i_op
= &adfs_file_inode_operations
;
221 make_bad_inode(inode
);