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