1 /*
2 * linux/fs/hfs/inode.c
3 *
4 * Copyright (C) 1995-1997 Paul H. Hargrove
5 * (C) 2003 Ardis Technologies <roman@ardistech.com>
6 * This file may be distributed under the terms of the GNU General Public License.
7 *
8 * This file contains inode-related functions which do not depend on
9 * which scheme is being used to represent forks.
10 *
11 * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
12 */
13
14 #include <linux/pagemap.h>
15 #include <linux/mpage.h>
16 #include <linux/sched.h>
17 #include <linux/cred.h>
18 #include <linux/uio.h>
19 #include <linux/xattr.h>
20 #include <linux/blkdev.h>
21
22 #include "hfs_fs.h"
23 #include "btree.h"
24
25 static const struct file_operations hfs_file_operations;
26 static const struct inode_operations hfs_file_inode_operations;
27
28 /*================ Variable-like macros ================*/
29
30 #define HFS_VALID_MODE_BITS (S_IFREG | S_IFDIR | S_IRWXUGO)
31
hfs_read_folio(struct file * file,struct folio * folio)32 static int hfs_read_folio(struct file *file, struct folio *folio)
33 {
34 return block_read_full_folio(folio, hfs_get_block);
35 }
36
hfs_write_failed(struct address_space * mapping,loff_t to)37 static void hfs_write_failed(struct address_space *mapping, loff_t to)
38 {
39 struct inode *inode = mapping->host;
40
41 if (to > inode->i_size) {
42 truncate_pagecache(inode, inode->i_size);
43 hfs_file_truncate(inode);
44 }
45 }
46
hfs_write_begin(const struct kiocb * iocb,struct address_space * mapping,loff_t pos,unsigned len,struct folio ** foliop,void ** fsdata)47 int hfs_write_begin(const struct kiocb *iocb, struct address_space *mapping,
48 loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
49 {
50 int ret;
51
52 ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
53 hfs_get_block,
54 &HFS_I(mapping->host)->phys_size);
55 if (unlikely(ret))
56 hfs_write_failed(mapping, pos + len);
57
58 return ret;
59 }
60
hfs_bmap(struct address_space * mapping,sector_t block)61 static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
62 {
63 return generic_block_bmap(mapping, block, hfs_get_block);
64 }
65
hfs_release_folio(struct folio * folio,gfp_t mask)66 static bool hfs_release_folio(struct folio *folio, gfp_t mask)
67 {
68 struct inode *inode = folio->mapping->host;
69 struct super_block *sb = inode->i_sb;
70 struct hfs_btree *tree;
71 struct hfs_bnode *node;
72 u32 nidx;
73 int i;
74 bool res = true;
75
76 switch (inode->i_ino) {
77 case HFS_EXT_CNID:
78 tree = HFS_SB(sb)->ext_tree;
79 break;
80 case HFS_CAT_CNID:
81 tree = HFS_SB(sb)->cat_tree;
82 break;
83 default:
84 BUG();
85 return false;
86 }
87
88 if (!tree)
89 return false;
90
91 if (tree->node_size >= PAGE_SIZE) {
92 nidx = folio->index >> (tree->node_size_shift - PAGE_SHIFT);
93 spin_lock(&tree->hash_lock);
94 node = hfs_bnode_findhash(tree, nidx);
95 if (!node)
96 ;
97 else if (atomic_read(&node->refcnt))
98 res = false;
99 if (res && node) {
100 hfs_bnode_unhash(node);
101 hfs_bnode_free(node);
102 }
103 spin_unlock(&tree->hash_lock);
104 } else {
105 nidx = folio->index << (PAGE_SHIFT - tree->node_size_shift);
106 i = 1 << (PAGE_SHIFT - tree->node_size_shift);
107 spin_lock(&tree->hash_lock);
108 do {
109 node = hfs_bnode_findhash(tree, nidx++);
110 if (!node)
111 continue;
112 if (atomic_read(&node->refcnt)) {
113 res = false;
114 break;
115 }
116 hfs_bnode_unhash(node);
117 hfs_bnode_free(node);
118 } while (--i && nidx < tree->node_count);
119 spin_unlock(&tree->hash_lock);
120 }
121 return res ? try_to_free_buffers(folio) : false;
122 }
123
hfs_direct_IO(struct kiocb * iocb,struct iov_iter * iter)124 static ssize_t hfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
125 {
126 struct file *file = iocb->ki_filp;
127 struct address_space *mapping = file->f_mapping;
128 struct inode *inode = mapping->host;
129 size_t count = iov_iter_count(iter);
130 ssize_t ret;
131
132 ret = blockdev_direct_IO(iocb, inode, iter, hfs_get_block);
133
134 /*
135 * In case of error extending write may have instantiated a few
136 * blocks outside i_size. Trim these off again.
137 */
138 if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
139 loff_t isize = i_size_read(inode);
140 loff_t end = iocb->ki_pos + count;
141
142 if (end > isize)
143 hfs_write_failed(mapping, end);
144 }
145
146 return ret;
147 }
148
hfs_writepages(struct address_space * mapping,struct writeback_control * wbc)149 static int hfs_writepages(struct address_space *mapping,
150 struct writeback_control *wbc)
151 {
152 return mpage_writepages(mapping, wbc, hfs_get_block);
153 }
154
155 const struct address_space_operations hfs_btree_aops = {
156 .dirty_folio = block_dirty_folio,
157 .invalidate_folio = block_invalidate_folio,
158 .read_folio = hfs_read_folio,
159 .writepages = hfs_writepages,
160 .write_begin = hfs_write_begin,
161 .write_end = generic_write_end,
162 .migrate_folio = buffer_migrate_folio,
163 .bmap = hfs_bmap,
164 .release_folio = hfs_release_folio,
165 };
166
167 const struct address_space_operations hfs_aops = {
168 .dirty_folio = block_dirty_folio,
169 .invalidate_folio = block_invalidate_folio,
170 .read_folio = hfs_read_folio,
171 .write_begin = hfs_write_begin,
172 .write_end = generic_write_end,
173 .bmap = hfs_bmap,
174 .direct_IO = hfs_direct_IO,
175 .writepages = hfs_writepages,
176 .migrate_folio = buffer_migrate_folio,
177 };
178
179 /*
180 * hfs_new_inode
181 */
hfs_new_inode(struct inode * dir,const struct qstr * name,umode_t mode)182 struct inode *hfs_new_inode(struct inode *dir, const struct qstr *name, umode_t mode)
183 {
184 struct super_block *sb = dir->i_sb;
185 struct inode *inode = new_inode(sb);
186 s64 next_id;
187 s64 file_count;
188 s64 folder_count;
189
190 if (!inode)
191 return NULL;
192
193 mutex_init(&HFS_I(inode)->extents_lock);
194 INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
195 spin_lock_init(&HFS_I(inode)->open_dir_lock);
196 hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
197 next_id = atomic64_inc_return(&HFS_SB(sb)->next_id);
198 BUG_ON(next_id > U32_MAX);
199 inode->i_ino = (u32)next_id;
200 inode->i_mode = mode;
201 inode->i_uid = current_fsuid();
202 inode->i_gid = current_fsgid();
203 set_nlink(inode, 1);
204 simple_inode_init_ts(inode);
205 HFS_I(inode)->flags = 0;
206 HFS_I(inode)->rsrc_inode = NULL;
207 HFS_I(inode)->fs_blocks = 0;
208 HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60;
209 if (S_ISDIR(mode)) {
210 inode->i_size = 2;
211 folder_count = atomic64_inc_return(&HFS_SB(sb)->folder_count);
212 BUG_ON(folder_count > U32_MAX);
213 if (dir->i_ino == HFS_ROOT_CNID)
214 HFS_SB(sb)->root_dirs++;
215 inode->i_op = &hfs_dir_inode_operations;
216 inode->i_fop = &hfs_dir_operations;
217 inode->i_mode |= S_IRWXUGO;
218 inode->i_mode &= ~HFS_SB(inode->i_sb)->s_dir_umask;
219 } else if (S_ISREG(mode)) {
220 HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks;
221 file_count = atomic64_inc_return(&HFS_SB(sb)->file_count);
222 BUG_ON(file_count > U32_MAX);
223 if (dir->i_ino == HFS_ROOT_CNID)
224 HFS_SB(sb)->root_files++;
225 inode->i_op = &hfs_file_inode_operations;
226 inode->i_fop = &hfs_file_operations;
227 inode->i_mapping->a_ops = &hfs_aops;
228 inode->i_mode |= S_IRUGO|S_IXUGO;
229 if (mode & S_IWUSR)
230 inode->i_mode |= S_IWUGO;
231 inode->i_mode &= ~HFS_SB(inode->i_sb)->s_file_umask;
232 HFS_I(inode)->phys_size = 0;
233 HFS_I(inode)->alloc_blocks = 0;
234 HFS_I(inode)->first_blocks = 0;
235 HFS_I(inode)->cached_start = 0;
236 HFS_I(inode)->cached_blocks = 0;
237 memset(HFS_I(inode)->first_extents, 0, sizeof(hfs_extent_rec));
238 memset(HFS_I(inode)->cached_extents, 0, sizeof(hfs_extent_rec));
239 }
240 insert_inode_hash(inode);
241 mark_inode_dirty(inode);
242 set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
243 hfs_mark_mdb_dirty(sb);
244
245 return inode;
246 }
247
hfs_delete_inode(struct inode * inode)248 void hfs_delete_inode(struct inode *inode)
249 {
250 struct super_block *sb = inode->i_sb;
251
252 hfs_dbg("ino %lu\n", inode->i_ino);
253 if (S_ISDIR(inode->i_mode)) {
254 BUG_ON(atomic64_read(&HFS_SB(sb)->folder_count) > U32_MAX);
255 atomic64_dec(&HFS_SB(sb)->folder_count);
256 if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID))
257 HFS_SB(sb)->root_dirs--;
258 set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
259 hfs_mark_mdb_dirty(sb);
260 return;
261 }
262
263 BUG_ON(atomic64_read(&HFS_SB(sb)->file_count) > U32_MAX);
264 atomic64_dec(&HFS_SB(sb)->file_count);
265 if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID))
266 HFS_SB(sb)->root_files--;
267 if (S_ISREG(inode->i_mode)) {
268 if (!inode->i_nlink) {
269 inode->i_size = 0;
270 hfs_file_truncate(inode);
271 }
272 }
273 set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);
274 hfs_mark_mdb_dirty(sb);
275 }
276
hfs_inode_read_fork(struct inode * inode,struct hfs_extent * ext,__be32 __log_size,__be32 phys_size,u32 clump_size)277 void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,
278 __be32 __log_size, __be32 phys_size, u32 clump_size)
279 {
280 struct super_block *sb = inode->i_sb;
281 u32 log_size = be32_to_cpu(__log_size);
282 u16 count;
283 int i;
284
285 memcpy(HFS_I(inode)->first_extents, ext, sizeof(hfs_extent_rec));
286 for (count = 0, i = 0; i < 3; i++)
287 count += be16_to_cpu(ext[i].count);
288 HFS_I(inode)->first_blocks = count;
289 HFS_I(inode)->cached_start = 0;
290 HFS_I(inode)->cached_blocks = 0;
291
292 inode->i_size = HFS_I(inode)->phys_size = log_size;
293 HFS_I(inode)->fs_blocks = (log_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
294 inode_set_bytes(inode, HFS_I(inode)->fs_blocks << sb->s_blocksize_bits);
295 HFS_I(inode)->alloc_blocks = be32_to_cpu(phys_size) /
296 HFS_SB(sb)->alloc_blksz;
297 HFS_I(inode)->clump_blocks = clump_size / HFS_SB(sb)->alloc_blksz;
298 if (!HFS_I(inode)->clump_blocks)
299 HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks;
300 }
301
302 struct hfs_iget_data {
303 struct hfs_cat_key *key;
304 hfs_cat_rec *rec;
305 };
306
hfs_test_inode(struct inode * inode,void * data)307 static int hfs_test_inode(struct inode *inode, void *data)
308 {
309 struct hfs_iget_data *idata = data;
310 hfs_cat_rec *rec;
311
312 rec = idata->rec;
313 switch (rec->type) {
314 case HFS_CDR_DIR:
315 return inode->i_ino == be32_to_cpu(rec->dir.DirID);
316 case HFS_CDR_FIL:
317 return inode->i_ino == be32_to_cpu(rec->file.FlNum);
318 default:
319 BUG();
320 return 1;
321 }
322 }
323
324 /*
325 * hfs_read_inode
326 */
hfs_read_inode(struct inode * inode,void * data)327 static int hfs_read_inode(struct inode *inode, void *data)
328 {
329 struct hfs_iget_data *idata = data;
330 struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
331 hfs_cat_rec *rec;
332
333 HFS_I(inode)->flags = 0;
334 HFS_I(inode)->rsrc_inode = NULL;
335 mutex_init(&HFS_I(inode)->extents_lock);
336 INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
337 spin_lock_init(&HFS_I(inode)->open_dir_lock);
338
339 /* Initialize the inode */
340 inode->i_uid = hsb->s_uid;
341 inode->i_gid = hsb->s_gid;
342 set_nlink(inode, 1);
343
344 if (idata->key)
345 HFS_I(inode)->cat_key = *idata->key;
346 else
347 HFS_I(inode)->flags |= HFS_FLG_RSRC;
348 HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60;
349
350 rec = idata->rec;
351 switch (rec->type) {
352 case HFS_CDR_FIL:
353 if (!HFS_IS_RSRC(inode)) {
354 hfs_inode_read_fork(inode, rec->file.ExtRec, rec->file.LgLen,
355 rec->file.PyLen, be16_to_cpu(rec->file.ClpSize));
356 } else {
357 hfs_inode_read_fork(inode, rec->file.RExtRec, rec->file.RLgLen,
358 rec->file.RPyLen, be16_to_cpu(rec->file.ClpSize));
359 }
360
361 inode->i_ino = be32_to_cpu(rec->file.FlNum);
362 inode->i_mode = S_IRUGO | S_IXUGO;
363 if (!(rec->file.Flags & HFS_FIL_LOCK))
364 inode->i_mode |= S_IWUGO;
365 inode->i_mode &= ~hsb->s_file_umask;
366 inode->i_mode |= S_IFREG;
367 inode_set_mtime_to_ts(inode,
368 inode_set_atime_to_ts(inode, inode_set_ctime_to_ts(inode, hfs_m_to_utime(rec->file.MdDat))));
369 inode->i_op = &hfs_file_inode_operations;
370 inode->i_fop = &hfs_file_operations;
371 inode->i_mapping->a_ops = &hfs_aops;
372 break;
373 case HFS_CDR_DIR:
374 inode->i_ino = be32_to_cpu(rec->dir.DirID);
375 inode->i_size = be16_to_cpu(rec->dir.Val) + 2;
376 HFS_I(inode)->fs_blocks = 0;
377 inode->i_mode = S_IFDIR | (S_IRWXUGO & ~hsb->s_dir_umask);
378 inode_set_mtime_to_ts(inode,
379 inode_set_atime_to_ts(inode, inode_set_ctime_to_ts(inode, hfs_m_to_utime(rec->dir.MdDat))));
380 inode->i_op = &hfs_dir_inode_operations;
381 inode->i_fop = &hfs_dir_operations;
382 break;
383 default:
384 make_bad_inode(inode);
385 }
386 return 0;
387 }
388
389 /*
390 * __hfs_iget()
391 *
392 * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in
393 * the catalog B-tree and the 'type' of the desired file return the
394 * inode for that file/directory or NULL. Note that 'type' indicates
395 * whether we want the actual file or directory, or the corresponding
396 * metadata (AppleDouble header file or CAP metadata file).
397 */
hfs_iget(struct super_block * sb,struct hfs_cat_key * key,hfs_cat_rec * rec)398 struct inode *hfs_iget(struct super_block *sb, struct hfs_cat_key *key, hfs_cat_rec *rec)
399 {
400 struct hfs_iget_data data = { key, rec };
401 struct inode *inode;
402 u32 cnid;
403
404 switch (rec->type) {
405 case HFS_CDR_DIR:
406 cnid = be32_to_cpu(rec->dir.DirID);
407 break;
408 case HFS_CDR_FIL:
409 cnid = be32_to_cpu(rec->file.FlNum);
410 break;
411 default:
412 return NULL;
413 }
414 inode = iget5_locked(sb, cnid, hfs_test_inode, hfs_read_inode, &data);
415 if (inode && (inode->i_state & I_NEW))
416 unlock_new_inode(inode);
417 return inode;
418 }
419
hfs_inode_write_fork(struct inode * inode,struct hfs_extent * ext,__be32 * log_size,__be32 * phys_size)420 void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext,
421 __be32 *log_size, __be32 *phys_size)
422 {
423 memcpy(ext, HFS_I(inode)->first_extents, sizeof(hfs_extent_rec));
424
425 if (log_size)
426 *log_size = cpu_to_be32(inode->i_size);
427 if (phys_size)
428 *phys_size = cpu_to_be32(HFS_I(inode)->alloc_blocks *
429 HFS_SB(inode->i_sb)->alloc_blksz);
430 }
431
hfs_write_inode(struct inode * inode,struct writeback_control * wbc)432 int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
433 {
434 struct inode *main_inode = inode;
435 struct hfs_find_data fd;
436 hfs_cat_rec rec;
437 int res;
438
439 hfs_dbg("ino %lu\n", inode->i_ino);
440 res = hfs_ext_write_extent(inode);
441 if (res)
442 return res;
443
444 if (inode->i_ino < HFS_FIRSTUSER_CNID) {
445 switch (inode->i_ino) {
446 case HFS_ROOT_CNID:
447 break;
448 case HFS_EXT_CNID:
449 hfs_btree_write(HFS_SB(inode->i_sb)->ext_tree);
450 return 0;
451 case HFS_CAT_CNID:
452 hfs_btree_write(HFS_SB(inode->i_sb)->cat_tree);
453 return 0;
454 default:
455 BUG();
456 return -EIO;
457 }
458 }
459
460 if (HFS_IS_RSRC(inode))
461 main_inode = HFS_I(inode)->rsrc_inode;
462
463 if (!main_inode->i_nlink)
464 return 0;
465
466 if (hfs_find_init(HFS_SB(main_inode->i_sb)->cat_tree, &fd))
467 /* panic? */
468 return -EIO;
469
470 res = -EIO;
471 if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
472 goto out;
473 fd.search_key->cat = HFS_I(main_inode)->cat_key;
474 if (hfs_brec_find(&fd))
475 goto out;
476
477 if (S_ISDIR(main_inode->i_mode)) {
478 if (fd.entrylength < sizeof(struct hfs_cat_dir))
479 goto out;
480 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
481 sizeof(struct hfs_cat_dir));
482 if (rec.type != HFS_CDR_DIR ||
483 be32_to_cpu(rec.dir.DirID) != inode->i_ino) {
484 }
485
486 rec.dir.MdDat = hfs_u_to_mtime(inode_get_mtime(inode));
487 rec.dir.Val = cpu_to_be16(inode->i_size - 2);
488
489 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
490 sizeof(struct hfs_cat_dir));
491 } else if (HFS_IS_RSRC(inode)) {
492 if (fd.entrylength < sizeof(struct hfs_cat_file))
493 goto out;
494 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
495 sizeof(struct hfs_cat_file));
496 hfs_inode_write_fork(inode, rec.file.RExtRec,
497 &rec.file.RLgLen, &rec.file.RPyLen);
498 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
499 sizeof(struct hfs_cat_file));
500 } else {
501 if (fd.entrylength < sizeof(struct hfs_cat_file))
502 goto out;
503 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
504 sizeof(struct hfs_cat_file));
505 if (rec.type != HFS_CDR_FIL ||
506 be32_to_cpu(rec.file.FlNum) != inode->i_ino) {
507 }
508
509 if (inode->i_mode & S_IWUSR)
510 rec.file.Flags &= ~HFS_FIL_LOCK;
511 else
512 rec.file.Flags |= HFS_FIL_LOCK;
513 hfs_inode_write_fork(inode, rec.file.ExtRec, &rec.file.LgLen, &rec.file.PyLen);
514 rec.file.MdDat = hfs_u_to_mtime(inode_get_mtime(inode));
515
516 hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
517 sizeof(struct hfs_cat_file));
518 }
519 res = 0;
520 out:
521 hfs_find_exit(&fd);
522 return res;
523 }
524
hfs_file_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)525 static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
526 unsigned int flags)
527 {
528 struct inode *inode = NULL;
529 hfs_cat_rec rec;
530 struct hfs_find_data fd;
531 int res;
532
533 if (HFS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc"))
534 goto out;
535
536 inode = HFS_I(dir)->rsrc_inode;
537 if (inode)
538 goto out;
539
540 inode = new_inode(dir->i_sb);
541 if (!inode)
542 return ERR_PTR(-ENOMEM);
543
544 res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
545 if (res) {
546 iput(inode);
547 return ERR_PTR(res);
548 }
549 fd.search_key->cat = HFS_I(dir)->cat_key;
550 res = hfs_brec_read(&fd, &rec, sizeof(rec));
551 if (!res) {
552 struct hfs_iget_data idata = { NULL, &rec };
553 hfs_read_inode(inode, &idata);
554 }
555 hfs_find_exit(&fd);
556 if (res) {
557 iput(inode);
558 return ERR_PTR(res);
559 }
560 HFS_I(inode)->rsrc_inode = dir;
561 HFS_I(dir)->rsrc_inode = inode;
562 igrab(dir);
563 inode_fake_hash(inode);
564 mark_inode_dirty(inode);
565 dont_mount(dentry);
566 out:
567 return d_splice_alias(inode, dentry);
568 }
569
hfs_evict_inode(struct inode * inode)570 void hfs_evict_inode(struct inode *inode)
571 {
572 truncate_inode_pages_final(&inode->i_data);
573 clear_inode(inode);
574 if (HFS_IS_RSRC(inode) && HFS_I(inode)->rsrc_inode) {
575 HFS_I(HFS_I(inode)->rsrc_inode)->rsrc_inode = NULL;
576 iput(HFS_I(inode)->rsrc_inode);
577 }
578 }
579
hfs_file_open(struct inode * inode,struct file * file)580 static int hfs_file_open(struct inode *inode, struct file *file)
581 {
582 if (HFS_IS_RSRC(inode))
583 inode = HFS_I(inode)->rsrc_inode;
584 atomic_inc(&HFS_I(inode)->opencnt);
585 return 0;
586 }
587
hfs_file_release(struct inode * inode,struct file * file)588 static int hfs_file_release(struct inode *inode, struct file *file)
589 {
590 //struct super_block *sb = inode->i_sb;
591
592 if (HFS_IS_RSRC(inode))
593 inode = HFS_I(inode)->rsrc_inode;
594 if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
595 inode_lock(inode);
596 hfs_file_truncate(inode);
597 //if (inode->i_flags & S_DEAD) {
598 // hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
599 // hfs_delete_inode(inode);
600 //}
601 inode_unlock(inode);
602 }
603 return 0;
604 }
605
606 /*
607 * hfs_notify_change()
608 *
609 * Based very closely on fs/msdos/inode.c by Werner Almesberger
610 *
611 * This is the notify_change() field in the super_operations structure
612 * for HFS file systems. The purpose is to take that changes made to
613 * an inode and apply then in a filesystem-dependent manner. In this
614 * case the process has a few of tasks to do:
615 * 1) prevent changes to the i_uid and i_gid fields.
616 * 2) map file permissions to the closest allowable permissions
617 * 3) Since multiple Linux files can share the same on-disk inode under
618 * HFS (for instance the data and resource forks of a file) a change
619 * to permissions must be applied to all other in-core inodes which
620 * correspond to the same HFS file.
621 */
622
hfs_inode_setattr(struct mnt_idmap * idmap,struct dentry * dentry,struct iattr * attr)623 int hfs_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
624 struct iattr *attr)
625 {
626 struct inode *inode = d_inode(dentry);
627 struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
628 int error;
629
630 error = setattr_prepare(&nop_mnt_idmap, dentry,
631 attr); /* basic permission checks */
632 if (error)
633 return error;
634
635 /* no uig/gid changes and limit which mode bits can be set */
636 if (((attr->ia_valid & ATTR_UID) &&
637 (!uid_eq(attr->ia_uid, hsb->s_uid))) ||
638 ((attr->ia_valid & ATTR_GID) &&
639 (!gid_eq(attr->ia_gid, hsb->s_gid))) ||
640 ((attr->ia_valid & ATTR_MODE) &&
641 ((S_ISDIR(inode->i_mode) &&
642 (attr->ia_mode != inode->i_mode)) ||
643 (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
644 return hsb->s_quiet ? 0 : error;
645 }
646
647 if (attr->ia_valid & ATTR_MODE) {
648 /* Only the 'w' bits can ever change and only all together. */
649 if (attr->ia_mode & S_IWUSR)
650 attr->ia_mode = inode->i_mode | S_IWUGO;
651 else
652 attr->ia_mode = inode->i_mode & ~S_IWUGO;
653 attr->ia_mode &= S_ISDIR(inode->i_mode) ? ~hsb->s_dir_umask: ~hsb->s_file_umask;
654 }
655
656 if ((attr->ia_valid & ATTR_SIZE) &&
657 attr->ia_size != i_size_read(inode)) {
658 inode_dio_wait(inode);
659
660 error = inode_newsize_ok(inode, attr->ia_size);
661 if (error)
662 return error;
663
664 truncate_setsize(inode, attr->ia_size);
665 hfs_file_truncate(inode);
666 simple_inode_init_ts(inode);
667 }
668
669 setattr_copy(&nop_mnt_idmap, inode, attr);
670 mark_inode_dirty(inode);
671 return 0;
672 }
673
hfs_file_fsync(struct file * filp,loff_t start,loff_t end,int datasync)674 static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,
675 int datasync)
676 {
677 struct inode *inode = filp->f_mapping->host;
678 struct super_block * sb;
679 int ret, err;
680
681 ret = file_write_and_wait_range(filp, start, end);
682 if (ret)
683 return ret;
684 inode_lock(inode);
685
686 /* sync the inode to buffers */
687 ret = write_inode_now(inode, 0);
688
689 /* sync the superblock to buffers */
690 sb = inode->i_sb;
691 flush_delayed_work(&HFS_SB(sb)->mdb_work);
692 /* .. finally sync the buffers to disk */
693 err = sync_blockdev(sb->s_bdev);
694 if (!ret)
695 ret = err;
696 inode_unlock(inode);
697 return ret;
698 }
699
700 static const struct file_operations hfs_file_operations = {
701 .llseek = generic_file_llseek,
702 .read_iter = generic_file_read_iter,
703 .write_iter = generic_file_write_iter,
704 .mmap_prepare = generic_file_mmap_prepare,
705 .splice_read = filemap_splice_read,
706 .splice_write = iter_file_splice_write,
707 .fsync = hfs_file_fsync,
708 .open = hfs_file_open,
709 .release = hfs_file_release,
710 };
711
712 static const struct inode_operations hfs_file_inode_operations = {
713 .lookup = hfs_file_lookup,
714 .setattr = hfs_inode_setattr,
715 .listxattr = generic_listxattr,
716 };
717