1 /*
2 * linux/fs/hfs/inode.c
3 *
4 * Copyright (C) 1995-1997 Paul H. Hargrove
5 * This file may be distributed under the terms of the GNU Public License.
6 *
7 * This file contains inode-related functions which do not depend on
8 * which scheme is being used to represent forks.
9 *
10 * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
11 *
12 * "XXX" in a comment is a note to myself to consider changing something.
13 *
14 * In function preconditions the term "valid" applied to a pointer to
15 * a structure means that the pointer is non-NULL and the structure it
16 * points to has all fields initialized to consistent values.
17 */
18
19 #include "hfs.h"
20 #include <linux/hfs_fs_sb.h>
21 #include <linux/hfs_fs_i.h>
22 #include <linux/hfs_fs.h>
23 #include <linux/smp_lock.h>
24
25 /*================ Variable-like macros ================*/
26
27 #define HFS_VALID_MODE_BITS (S_IFREG | S_IFDIR | S_IRWXUGO)
28
29 /*================ File-local functions ================*/
30
31 /*
32 * init_file_inode()
33 *
34 * Given an HFS catalog entry initialize an inode for a file.
35 */
36 static void init_file_inode(struct inode *inode, hfs_u8 fork)
37 {
38 struct hfs_fork *fk;
39 struct hfs_cat_entry *entry = HFS_I(inode)->entry;
40
41 if (!IS_NOEXEC(inode) && (fork == HFS_FK_DATA)) {
42 inode->i_mode = S_IRWXUGO | S_IFREG;
43 } else {
44 inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
45 }
46
47 if (fork == HFS_FK_DATA) {
48 #if 0 /* XXX: disable crlf translations for now */
49 hfs_u32 type = hfs_get_nl(entry->info.file.finfo.fdType);
50
51 HFS_I(inode)->convert =
52 ((HFS_SB(inode->i_sb)->s_conv == 't') ||
53 ((HFS_SB(inode->i_sb)->s_conv == 'a') &&
54 ((type == htonl(0x54455854)) || /* "TEXT" */
55 (type == htonl(0x7474726f))))); /* "ttro" */
56 #else
57 HFS_I(inode)->convert = 0;
58 #endif
59 fk = &entry->u.file.data_fork;
60 } else {
61 fk = &entry->u.file.rsrc_fork;
62 HFS_I(inode)->convert = 0;
63 }
64 HFS_I(inode)->fork = fk;
65 inode->i_size = fk->lsize;
66 inode->i_blocks = fk->psize;
67 inode->i_nlink = 1;
68 }
69
70 /*================ Global functions ================*/
71
72 /*
73 * hfs_put_inode()
74 *
75 * This is the put_inode() entry in the super_operations for HFS
76 * filesystems. The purpose is to perform any filesystem-dependent
77 * cleanup necessary when the use-count of an inode falls to zero.
78 */
79 void hfs_put_inode(struct inode * inode)
80 {
81 struct hfs_cat_entry *entry = HFS_I(inode)->entry;
82
83 lock_kernel();
84 hfs_cat_put(entry);
85 if (atomic_read(&inode->i_count) == 1) {
86 struct hfs_hdr_layout *tmp = HFS_I(inode)->layout;
87
88 if (tmp) {
89 HFS_I(inode)->layout = NULL;
90 HFS_DELETE(tmp);
91 }
92 }
93 unlock_kernel();
94 }
95
96 /*
97 * hfs_notify_change()
98 *
99 * Based very closely on fs/msdos/inode.c by Werner Almesberger
100 *
101 * This is the notify_change() field in the super_operations structure
102 * for HFS file systems. The purpose is to take that changes made to
103 * an inode and apply then in a filesystem-dependent manner. In this
104 * case the process has a few of tasks to do:
105 * 1) prevent changes to the i_uid and i_gid fields.
106 * 2) map file permissions to the closest allowable permissions
107 * 3) Since multiple Linux files can share the same on-disk inode under
108 * HFS (for instance the data and resource forks of a file) a change
109 * to permissions must be applied to all other in-core inodes which
110 * correspond to the same HFS file.
111 */
112 enum {HFS_NORM, HFS_HDR, HFS_CAP};
113
114 static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int kind)
115 {
116 struct inode *inode = dentry->d_inode;
117 struct hfs_cat_entry *entry = HFS_I(inode)->entry;
118 struct dentry **de = entry->sys_entry;
119 struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
120 int error, i;
121
122 error = inode_change_ok(inode, attr); /* basic permission checks */
123 if (error) {
124 /* Let netatalk's afpd think chmod() always succeeds */
125 if (hsb->s_afpd &&
126 (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {
127 return 0;
128 } else {
129 return error;
130 }
131 }
132
133 /* no uig/gid changes and limit which mode bits can be set */
134 if (((attr->ia_valid & ATTR_UID) &&
135 (attr->ia_uid != hsb->s_uid)) ||
136 ((attr->ia_valid & ATTR_GID) &&
137 (attr->ia_gid != hsb->s_gid)) ||
138 ((attr->ia_valid & ATTR_MODE) &&
139 (((entry->type == HFS_CDR_DIR) &&
140 (attr->ia_mode != inode->i_mode))||
141 (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
142 return hsb->s_quiet ? 0 : error;
143 }
144
145 if (entry->type == HFS_CDR_DIR) {
146 attr->ia_valid &= ~ATTR_MODE;
147 } else if (attr->ia_valid & ATTR_MODE) {
148 /* Only the 'w' bits can ever change and only all together. */
149 if (attr->ia_mode & S_IWUSR) {
150 attr->ia_mode = inode->i_mode | S_IWUGO;
151 } else {
152 attr->ia_mode = inode->i_mode & ~S_IWUGO;
153 }
154 attr->ia_mode &= ~hsb->s_umask;
155 }
156 /*
157 * Normal files handle size change in normal way.
158 * Oddballs are served here.
159 */
160 if (attr->ia_valid & ATTR_SIZE) {
161 if (kind == HFS_CAP) {
162 inode->i_size = attr->ia_size;
163 if (inode->i_size > HFS_FORK_MAX)
164 inode->i_size = HFS_FORK_MAX;
165 mark_inode_dirty(inode);
166 attr->ia_valid &= ~ATTR_SIZE;
167 } else if (kind == HFS_HDR) {
168 hdr_truncate(inode, attr->ia_size);
169 attr->ia_valid &= ~ATTR_SIZE;
170 }
171 }
172 inode_setattr(inode, attr);
173
174 /* We wouldn't want to mess with the sizes of the other fork */
175 attr->ia_valid &= ~ATTR_SIZE;
176
177 /* We must change all in-core inodes corresponding to this file. */
178 for (i = 0; i < 4; ++i) {
179 if (de[i] && (de[i] != dentry)) {
180 inode_setattr(de[i]->d_inode, attr);
181 }
182 }
183
184 /* Change the catalog entry if needed */
185 if (attr->ia_valid & ATTR_MTIME) {
186 entry->modify_date = hfs_u_to_mtime(inode->i_mtime);
187 hfs_cat_mark_dirty(entry);
188 }
189 if (attr->ia_valid & ATTR_MODE) {
190 hfs_u8 new_flags;
191
192 if (inode->i_mode & S_IWUSR) {
193 new_flags = entry->u.file.flags & ~HFS_FIL_LOCK;
194 } else {
195 new_flags = entry->u.file.flags | HFS_FIL_LOCK;
196 }
197
198 if (new_flags != entry->u.file.flags) {
199 entry->u.file.flags = new_flags;
200 hfs_cat_mark_dirty(entry);
201 }
202 }
203 /* size changes handled in hfs_extent_adj() */
204
205 return 0;
206 }
207
208 int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
209 {
210 return __hfs_notify_change(dentry, attr, HFS_NORM);
211 }
212
213 int hfs_notify_change_cap(struct dentry *dentry, struct iattr * attr)
214 {
215 return __hfs_notify_change(dentry, attr, HFS_CAP);
216 }
217
218 int hfs_notify_change_hdr(struct dentry *dentry, struct iattr * attr)
219 {
220 return __hfs_notify_change(dentry, attr, HFS_HDR);
221 }
222
223 static int hfs_writepage(struct page *page)
224 {
225 return block_write_full_page(page,hfs_get_block);
226 }
227 static int hfs_readpage(struct file *file, struct page *page)
228 {
229 return block_read_full_page(page,hfs_get_block);
230 }
231 static int hfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
232 {
233 return cont_prepare_write(page,from,to,hfs_get_block,
234 &page->mapping->host->u.hfs_i.mmu_private);
235 }
236 static int hfs_bmap(struct address_space *mapping, long block)
237 {
238 return generic_block_bmap(mapping,block,hfs_get_block);
239 }
240 struct address_space_operations hfs_aops = {
241 readpage: hfs_readpage,
242 writepage: hfs_writepage,
243 sync_page: block_sync_page,
244 prepare_write: hfs_prepare_write,
245 commit_write: generic_commit_write,
246 bmap: hfs_bmap
247 };
248
249 /*
250 * __hfs_iget()
251 *
252 * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in
253 * the catalog B-tree and the 'type' of the desired file return the
254 * inode for that file/directory or NULL. Note that 'type' indicates
255 * whether we want the actual file or directory, or the corresponding
256 * metadata (AppleDouble header file or CAP metadata file).
257 *
258 * In an ideal world we could call iget() and would not need this
259 * function. However, since there is no way to even know the inode
260 * number until we've found the file/directory in the catalog B-tree
261 * that simply won't happen.
262 *
263 * The main idea here is to look in the catalog B-tree to get the
264 * vital info about the file or directory (including the file id which
265 * becomes the inode number) and then to call iget() and return the
266 * inode if it is complete. If it is not then we use the catalog
267 * entry to fill in the missing info, by calling the appropriate
268 * 'fillin' function. Note that these fillin functions are
269 * essentially hfs_*_read_inode() functions, but since there is no way
270 * to pass the catalog entry through iget() to such a read_inode()
271 * function, we have to call them after iget() returns an incomplete
272 * inode to us. This is pretty much the same problem faced in the NFS
273 * code, and pretty much the same solution. The SMB filesystem deals
274 * with this in a different way: by using the address of the
275 * kmalloc()'d space which holds the data as the inode number.
276 *
277 * XXX: Both this function and NFS's corresponding nfs_fhget() would
278 * benefit from a way to pass an additional (void *) through iget() to
279 * the VFS read_inode() function.
280 *
281 * this will hfs_cat_put() the entry if it fails.
282 */
283 struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,
284 struct dentry *dentry)
285 {
286 struct dentry **sys_entry;
287 struct super_block *sb;
288 struct inode *inode;
289
290 if (!entry) {
291 return NULL;
292 }
293
294 /* If there are several processes all calling __iget() for
295 the same inode then they will all get the same one back.
296 The first one to return from __iget() will notice that the
297 i_mode field of the inode is blank and KNOW that it is
298 the first to return. Therefore, it will set the appropriate
299 'sys_entry' field in the entry and initialize the inode.
300 All the initialization must be done without sleeping,
301 or else other processes could end up using a partially
302 initialized inode. */
303
304 sb = entry->mdb->sys_mdb;
305 sys_entry = &entry->sys_entry[HFS_ITYPE_TO_INT(type)];
306
307 if (!(inode = iget(sb, ntohl(entry->cnid) | type))) {
308 hfs_cat_put(entry);
309 return NULL;
310 }
311
312 if (inode->i_dev != sb->s_dev) {
313 iput(inode); /* automatically does an hfs_cat_put */
314 inode = NULL;
315 } else if (!inode->i_mode || (*sys_entry == NULL)) {
316 /* Initialize the inode */
317 struct hfs_sb_info *hsb = HFS_SB(sb);
318
319 inode->i_rdev = 0;
320 inode->i_ctime = inode->i_atime = inode->i_mtime =
321 hfs_m_to_utime(entry->modify_date);
322 inode->i_blksize = HFS_SECTOR_SIZE;
323 inode->i_uid = hsb->s_uid;
324 inode->i_gid = hsb->s_gid;
325
326 memset(HFS_I(inode), 0, sizeof(struct hfs_inode_info));
327 HFS_I(inode)->magic = HFS_INO_MAGIC;
328 HFS_I(inode)->entry = entry;
329 HFS_I(inode)->tz_secondswest = hfs_to_utc(0);
330
331 hsb->s_ifill(inode, type, hsb->s_version);
332 if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) &&
333 (entry->u.file.flags & HFS_FIL_LOCK)) {
334 inode->i_mode &= ~S_IWUGO;
335 }
336 inode->i_mode &= ~hsb->s_umask;
337
338 if (!inode->i_mode) {
339 iput(inode); /* does an hfs_cat_put */
340 inode = NULL;
341 } else
342 *sys_entry = dentry; /* cache dentry */
343
344 }
345
346 return inode;
347 }
348
349 /*================ Scheme-specific functions ================*/
350
351 /*
352 * hfs_cap_ifill()
353 *
354 * This function serves the same purpose as a read_inode() function does
355 * in other filesystems. It is called by __hfs_iget() to fill in
356 * the missing fields of an uninitialized inode under the CAP scheme.
357 */
358 void hfs_cap_ifill(struct inode * inode, ino_t type, const int version)
359 {
360 struct hfs_cat_entry *entry = HFS_I(inode)->entry;
361
362 HFS_I(inode)->d_drop_op = hfs_cap_drop_dentry;
363 if (type == HFS_CAP_FNDR) {
364 inode->i_size = sizeof(struct hfs_cap_info);
365 inode->i_blocks = 0;
366 inode->i_nlink = 1;
367 inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
368 inode->i_op = &hfs_cap_info_inode_operations;
369 inode->i_fop = &hfs_cap_info_operations;
370 } else if (entry->type == HFS_CDR_FIL) {
371 init_file_inode(inode, (type == HFS_CAP_DATA) ?
372 HFS_FK_DATA : HFS_FK_RSRC);
373 inode->i_op = &hfs_file_inode_operations;
374 inode->i_fop = &hfs_file_operations;
375 inode->i_mapping->a_ops = &hfs_aops;
376 inode->u.hfs_i.mmu_private = inode->i_size;
377 } else { /* Directory */
378 struct hfs_dir *hdir = &entry->u.dir;
379
380 inode->i_blocks = 0;
381 inode->i_size = hdir->files + hdir->dirs + 5;
382 HFS_I(inode)->dir_size = 1;
383 if (type == HFS_CAP_NDIR) {
384 inode->i_mode = S_IRWXUGO | S_IFDIR;
385 inode->i_nlink = hdir->dirs + 4;
386 inode->i_op = &hfs_cap_ndir_inode_operations;
387 inode->i_fop = &hfs_cap_dir_operations;
388 HFS_I(inode)->file_type = HFS_CAP_NORM;
389 } else if (type == HFS_CAP_FDIR) {
390 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
391 inode->i_nlink = 2;
392 inode->i_op = &hfs_cap_fdir_inode_operations;
393 inode->i_fop = &hfs_cap_dir_operations;
394 HFS_I(inode)->file_type = HFS_CAP_FNDR;
395 } else if (type == HFS_CAP_RDIR) {
396 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
397 inode->i_nlink = 2;
398 inode->i_op = &hfs_cap_rdir_inode_operations;
399 inode->i_fop = &hfs_cap_dir_operations;
400 HFS_I(inode)->file_type = HFS_CAP_RSRC;
401 }
402 }
403 }
404
405 /*
406 * hfs_dbl_ifill()
407 *
408 * This function serves the same purpose as a read_inode() function does
409 * in other filesystems. It is called by __hfs_iget() to fill in
410 * the missing fields of an uninitialized inode under the AppleDouble
411 * scheme.
412 */
413 void hfs_dbl_ifill(struct inode * inode, ino_t type, const int version)
414 {
415 struct hfs_cat_entry *entry = HFS_I(inode)->entry;
416
417 HFS_I(inode)->d_drop_op = hfs_dbl_drop_dentry;
418 if (type == HFS_DBL_HDR) {
419 if (entry->type == HFS_CDR_FIL) {
420 init_file_inode(inode, HFS_FK_RSRC);
421 inode->i_size += HFS_DBL_HDR_LEN;
422 HFS_I(inode)->default_layout = &hfs_dbl_fil_hdr_layout;
423 } else {
424 inode->i_size = HFS_DBL_HDR_LEN;
425 inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
426 inode->i_nlink = 1;
427 HFS_I(inode)->default_layout = &hfs_dbl_dir_hdr_layout;
428 }
429 inode->i_op = &hfs_hdr_inode_operations;
430 inode->i_fop = &hfs_hdr_operations;
431 } else if (entry->type == HFS_CDR_FIL) {
432 init_file_inode(inode, HFS_FK_DATA);
433 inode->i_op = &hfs_file_inode_operations;
434 inode->i_fop = &hfs_file_operations;
435 inode->i_mapping->a_ops = &hfs_aops;
436 inode->u.hfs_i.mmu_private = inode->i_size;
437 } else { /* Directory */
438 struct hfs_dir *hdir = &entry->u.dir;
439
440 inode->i_blocks = 0;
441 inode->i_nlink = hdir->dirs + 2;
442 inode->i_size = 3 + 2 * (hdir->dirs + hdir->files);
443 inode->i_mode = S_IRWXUGO | S_IFDIR;
444 inode->i_op = &hfs_dbl_dir_inode_operations;
445 inode->i_fop = &hfs_dbl_dir_operations;
446 HFS_I(inode)->file_type = HFS_DBL_NORM;
447 HFS_I(inode)->dir_size = 2;
448 }
449 }
450
451 /*
452 * hfs_nat_ifill()
453 *
454 * This function serves the same purpose as a read_inode() function does
455 * in other filesystems. It is called by __hfs_iget() to fill in
456 * the missing fields of an uninitialized inode under the Netatalk
457 * scheme.
458 */
459 void hfs_nat_ifill(struct inode * inode, ino_t type, const int version)
460 {
461 struct hfs_cat_entry *entry = HFS_I(inode)->entry;
462
463 HFS_I(inode)->d_drop_op = hfs_nat_drop_dentry;
464 if (type == HFS_NAT_HDR) {
465 if (entry->type == HFS_CDR_FIL) {
466 init_file_inode(inode, HFS_FK_RSRC);
467 inode->i_size += HFS_NAT_HDR_LEN;
468 } else {
469 inode->i_size = HFS_NAT_HDR_LEN;
470 inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
471 inode->i_nlink = 1;
472 }
473 inode->i_op = &hfs_hdr_inode_operations;
474 inode->i_fop = &hfs_hdr_operations;
475 HFS_I(inode)->default_layout = (version == 2) ?
476 &hfs_nat2_hdr_layout : &hfs_nat_hdr_layout;
477 } else if (entry->type == HFS_CDR_FIL) {
478 init_file_inode(inode, HFS_FK_DATA);
479 inode->i_op = &hfs_file_inode_operations;
480 inode->i_fop = &hfs_file_operations;
481 inode->i_mapping->a_ops = &hfs_aops;
482 inode->u.hfs_i.mmu_private = inode->i_size;
483 } else { /* Directory */
484 struct hfs_dir *hdir = &entry->u.dir;
485
486 inode->i_blocks = 0;
487 inode->i_size = hdir->files + hdir->dirs + 4;
488 inode->i_mode = S_IRWXUGO | S_IFDIR;
489 HFS_I(inode)->dir_size = 1;
490 if (type == HFS_NAT_NDIR) {
491 inode->i_nlink = hdir->dirs + 3;
492 inode->i_op = &hfs_nat_ndir_inode_operations;
493 HFS_I(inode)->file_type = HFS_NAT_NORM;
494 } else if (type == HFS_NAT_HDIR) {
495 inode->i_nlink = 2;
496 inode->i_op = &hfs_nat_hdir_inode_operations;
497 HFS_I(inode)->file_type = HFS_NAT_HDR;
498 }
499 inode->i_fop = &hfs_nat_dir_operations;
500 }
501 }
502
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.