VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
^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) };