VisionFive2 Linux kernel

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

More than 9999 Commits   32 Branches   54 Tags
b24413180f560 (Greg Kroah-Hartman   2017-11-01 15:07:57 +0100   1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   2) /*
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   3)  *  linux/fs/hfsplus/inode.c
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   4)  *
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   5)  * Copyright (C) 2001
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   6)  * Brad Boyer (flar@allandria.com)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   7)  * (C) 2003 Ardis Technologies <roman@ardistech.com>
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   8)  *
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700   9)  * Inode handling routines
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  10)  */
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  11) 
34a2d313c51f4 (Christoph Hellwig    2010-11-23 14:38:21 +0100  12) #include <linux/blkdev.h>
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  13) #include <linux/mm.h>
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  14) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  15) #include <linux/pagemap.h>
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  16) #include <linux/mpage.h>
e8edc6e03a5c8 (Alexey Dobriyan      2007-05-21 01:22:52 +0400  17) #include <linux/sched.h>
5b825c3af1d8a (Ingo Molnar          2017-02-02 17:54:15 +0100  18) #include <linux/cred.h>
e2e40f2c1ed43 (Christoph Hellwig    2015-02-22 08:58:50 -0800  19) #include <linux/uio.h>
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200  20) #include <linux/fileattr.h>
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  21) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  22) #include "hfsplus_fs.h"
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  23) #include "hfsplus_raw.h"
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800  24) #include "xattr.h"
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  25) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  26) static int hfsplus_readpage(struct file *file, struct page *page)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  27) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  28) 	return block_read_full_page(page, hfsplus_get_block);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  29) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  30) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  31) static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  32) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  33) 	return block_write_full_page(page, hfsplus_get_block, wbc);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  34) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  35) 
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  36) static void hfsplus_write_failed(struct address_space *mapping, loff_t to)
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  37) {
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  38) 	struct inode *inode = mapping->host;
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  39) 
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  40) 	if (to > inode->i_size) {
7caef26767c17 (Kirill A. Shutemov   2013-09-12 15:13:56 -0700  41) 		truncate_pagecache(inode, inode->i_size);
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  42) 		hfsplus_file_truncate(inode);
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  43) 	}
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  44) }
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  45) 
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700  46) static int hfsplus_write_begin(struct file *file, struct address_space *mapping,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700  47) 			loff_t pos, unsigned len, unsigned flags,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700  48) 			struct page **pagep, void **fsdata)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  49) {
282dc17884988 (Christoph Hellwig    2010-06-04 11:29:55 +0200  50) 	int ret;
282dc17884988 (Christoph Hellwig    2010-06-04 11:29:55 +0200  51) 
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700  52) 	*pagep = NULL;
282dc17884988 (Christoph Hellwig    2010-06-04 11:29:55 +0200  53) 	ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700  54) 				hfsplus_get_block,
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200  55) 				&HFSPLUS_I(mapping->host)->phys_size);
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  56) 	if (unlikely(ret))
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100  57) 		hfsplus_write_failed(mapping, pos + len);
282dc17884988 (Christoph Hellwig    2010-06-04 11:29:55 +0200  58) 
282dc17884988 (Christoph Hellwig    2010-06-04 11:29:55 +0200  59) 	return ret;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  60) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  61) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  62) static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  63) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  64) 	return generic_block_bmap(mapping, block, hfsplus_get_block);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  65) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  66) 
27496a8c67bef (Al Viro              2005-10-21 03:20:48 -0400  67) static int hfsplus_releasepage(struct page *page, gfp_t mask)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  68) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  69) 	struct inode *inode = page->mapping->host;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  70) 	struct super_block *sb = inode->i_sb;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  71) 	struct hfs_btree *tree;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  72) 	struct hfs_bnode *node;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  73) 	u32 nidx;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  74) 	int i, res = 1;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  75) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  76) 	switch (inode->i_ino) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  77) 	case HFSPLUS_EXT_CNID:
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200  78) 		tree = HFSPLUS_SB(sb)->ext_tree;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  79) 		break;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  80) 	case HFSPLUS_CAT_CNID:
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200  81) 		tree = HFSPLUS_SB(sb)->cat_tree;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  82) 		break;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  83) 	case HFSPLUS_ATTR_CNID:
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200  84) 		tree = HFSPLUS_SB(sb)->attr_tree;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  85) 		break;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  86) 	default:
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  87) 		BUG();
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  88) 		return 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  89) 	}
706322496b3a5 (Eric Sesterhenn      2008-05-12 14:02:21 -0700  90) 	if (!tree)
706322496b3a5 (Eric Sesterhenn      2008-05-12 14:02:21 -0700  91) 		return 0;
09cbfeaf1a5a6 (Kirill A. Shutemov   2016-04-01 15:29:47 +0300  92) 	if (tree->node_size >= PAGE_SIZE) {
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200  93) 		nidx = page->index >>
09cbfeaf1a5a6 (Kirill A. Shutemov   2016-04-01 15:29:47 +0300  94) 			(tree->node_size_shift - PAGE_SHIFT);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  95) 		spin_lock(&tree->hash_lock);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  96) 		node = hfs_bnode_findhash(tree, nidx);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  97) 		if (!node)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  98) 			;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700  99) 		else if (atomic_read(&node->refcnt))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 100) 			res = 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 101) 		if (res && node) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 102) 			hfs_bnode_unhash(node);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 103) 			hfs_bnode_free(node);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 104) 		}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 105) 		spin_unlock(&tree->hash_lock);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 106) 	} else {
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 107) 		nidx = page->index <<
09cbfeaf1a5a6 (Kirill A. Shutemov   2016-04-01 15:29:47 +0300 108) 			(PAGE_SHIFT - tree->node_size_shift);
09cbfeaf1a5a6 (Kirill A. Shutemov   2016-04-01 15:29:47 +0300 109) 		i = 1 << (PAGE_SHIFT - tree->node_size_shift);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 110) 		spin_lock(&tree->hash_lock);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 111) 		do {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 112) 			node = hfs_bnode_findhash(tree, nidx++);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 113) 			if (!node)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 114) 				continue;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 115) 			if (atomic_read(&node->refcnt)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 116) 				res = 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 117) 				break;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 118) 			}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 119) 			hfs_bnode_unhash(node);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 120) 			hfs_bnode_free(node);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 121) 		} while (--i && nidx < tree->node_count);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 122) 		spin_unlock(&tree->hash_lock);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 123) 	}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 124) 	return res ? try_to_free_buffers(page) : 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 125) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 126) 
c8b8e32d700fe (Christoph Hellwig    2016-04-07 08:51:58 -0700 127) static ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 128) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 129) 	struct file *file = iocb->ki_filp;
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100 130) 	struct address_space *mapping = file->f_mapping;
93c76a3d437ff (Al Viro              2015-12-04 23:45:44 -0500 131) 	struct inode *inode = mapping->host;
a6cbcd4a4a85e (Al Viro              2014-03-04 22:38:00 -0500 132) 	size_t count = iov_iter_count(iter);
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 133) 	ssize_t ret;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 134) 
c8b8e32d700fe (Christoph Hellwig    2016-04-07 08:51:58 -0700 135) 	ret = blockdev_direct_IO(iocb, inode, iter, hfsplus_get_block);
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 136) 
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 137) 	/*
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 138) 	 * In case of error extending write may have instantiated a few
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 139) 	 * blocks outside i_size. Trim these off again.
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 140) 	 */
6f67376318abe (Omar Sandoval        2015-03-16 04:33:52 -0700 141) 	if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 142) 		loff_t isize = i_size_read(inode);
c8b8e32d700fe (Christoph Hellwig    2016-04-07 08:51:58 -0700 143) 		loff_t end = iocb->ki_pos + count;
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 144) 
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 145) 		if (end > isize)
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100 146) 			hfsplus_write_failed(mapping, end);
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 147) 	}
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 148) 
eafdc7d190a94 (Christoph Hellwig    2010-06-04 11:29:53 +0200 149) 	return ret;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 150) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 151) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 152) static int hfsplus_writepages(struct address_space *mapping,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 153) 			      struct writeback_control *wbc)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 154) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 155) 	return mpage_writepages(mapping, wbc, hfsplus_get_block);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 156) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 157) 
f5e54d6e53a20 (Christoph Hellwig    2006-06-28 04:26:44 -0700 158) const struct address_space_operations hfsplus_btree_aops = {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 159) 	.readpage	= hfsplus_readpage,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 160) 	.writepage	= hfsplus_writepage,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700 161) 	.write_begin	= hfsplus_write_begin,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700 162) 	.write_end	= generic_write_end,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 163) 	.bmap		= hfsplus_bmap,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 164) 	.releasepage	= hfsplus_releasepage,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 165) };
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 166) 
f5e54d6e53a20 (Christoph Hellwig    2006-06-28 04:26:44 -0700 167) const struct address_space_operations hfsplus_aops = {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 168) 	.readpage	= hfsplus_readpage,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 169) 	.writepage	= hfsplus_writepage,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700 170) 	.write_begin	= hfsplus_write_begin,
7c0efc627738c (Nicholas Piggin      2007-10-16 01:25:09 -0700 171) 	.write_end	= generic_write_end,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 172) 	.bmap		= hfsplus_bmap,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 173) 	.direct_IO	= hfsplus_direct_IO,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 174) 	.writepages	= hfsplus_writepages,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 175) };
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 176) 
e16404ed0f3f3 (Al Viro              2009-02-20 05:55:13 +0000 177) const struct dentry_operations hfsplus_dentry_operations = {
d45bce8faf555 (Duane Griffin        2007-07-15 23:41:23 -0700 178) 	.d_hash       = hfsplus_hash_dentry,
d45bce8faf555 (Duane Griffin        2007-07-15 23:41:23 -0700 179) 	.d_compare    = hfsplus_compare_dentry,
d45bce8faf555 (Duane Griffin        2007-07-15 23:41:23 -0700 180) };
d45bce8faf555 (Duane Griffin        2007-07-15 23:41:23 -0700 181) 
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 182) static void hfsplus_get_perms(struct inode *inode,
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 183) 		struct hfsplus_perm *perms, int dir)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 184) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 185) 	struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 186) 	u16 mode;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 187) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 188) 	mode = be16_to_cpu(perms->mode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 189) 
16525e3f146fb (Eric W. Biederman    2012-02-07 16:27:17 -0800 190) 	i_uid_write(inode, be32_to_cpu(perms->owner));
16525e3f146fb (Eric W. Biederman    2012-02-07 16:27:17 -0800 191) 	if (!i_uid_read(inode) && !mode)
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 192) 		inode->i_uid = sbi->uid;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 193) 
16525e3f146fb (Eric W. Biederman    2012-02-07 16:27:17 -0800 194) 	i_gid_write(inode, be32_to_cpu(perms->group));
16525e3f146fb (Eric W. Biederman    2012-02-07 16:27:17 -0800 195) 	if (!i_gid_read(inode) && !mode)
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 196) 		inode->i_gid = sbi->gid;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 197) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 198) 	if (dir) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 199) 		mode = mode ? (mode & S_IALLUGO) : (S_IRWXUGO & ~(sbi->umask));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 200) 		mode |= S_IFDIR;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 201) 	} else if (!mode)
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 202) 		mode = S_IFREG | ((S_IRUGO|S_IWUGO) & ~(sbi->umask));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 203) 	inode->i_mode = mode;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 204) 
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 205) 	HFSPLUS_I(inode)->userflags = perms->userflags;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 206) 	if (perms->rootflags & HFSPLUS_FLG_IMMUTABLE)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 207) 		inode->i_flags |= S_IMMUTABLE;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 208) 	else
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 209) 		inode->i_flags &= ~S_IMMUTABLE;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 210) 	if (perms->rootflags & HFSPLUS_FLG_APPEND)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 211) 		inode->i_flags |= S_APPEND;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 212) 	else
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 213) 		inode->i_flags &= ~S_APPEND;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 214) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 215) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 216) static int hfsplus_file_open(struct inode *inode, struct file *file)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 217) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 218) 	if (HFSPLUS_IS_RSRC(inode))
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 219) 		inode = HFSPLUS_I(inode)->rsrc_inode;
6e7152944426b (Alan Cox             2008-10-18 20:28:01 -0700 220) 	if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
6e7152944426b (Alan Cox             2008-10-18 20:28:01 -0700 221) 		return -EOVERFLOW;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 222) 	atomic_inc(&HFSPLUS_I(inode)->opencnt);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 223) 	return 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 224) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 225) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 226) static int hfsplus_file_release(struct inode *inode, struct file *file)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 227) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 228) 	struct super_block *sb = inode->i_sb;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 229) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 230) 	if (HFSPLUS_IS_RSRC(inode))
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 231) 		inode = HFSPLUS_I(inode)->rsrc_inode;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 232) 	if (atomic_dec_and_test(&HFSPLUS_I(inode)->opencnt)) {
5955102c9984f (Al Viro              2016-01-22 15:40:57 -0500 233) 		inode_lock(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 234) 		hfsplus_file_truncate(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 235) 		if (inode->i_flags & S_DEAD) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 236) 			hfsplus_delete_cat(inode->i_ino,
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 237) 					   HFSPLUS_SB(sb)->hidden_dir, NULL);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 238) 			hfsplus_delete_inode(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 239) 		}
5955102c9984f (Al Viro              2016-01-22 15:40:57 -0500 240) 		inode_unlock(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 241) 	}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 242) 	return 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 243) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 244) 
549c7297717c3 (Christian Brauner    2021-01-21 14:19:43 +0100 245) static int hfsplus_setattr(struct user_namespace *mnt_userns,
549c7297717c3 (Christian Brauner    2021-01-21 14:19:43 +0100 246) 			   struct dentry *dentry, struct iattr *attr)
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 247) {
2b0143b5c986b (David Howells        2015-03-17 22:25:59 +0000 248) 	struct inode *inode = d_inode(dentry);
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 249) 	int error;
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 250) 
2f221d6f7b881 (Christian Brauner    2021-01-21 14:19:26 +0100 251) 	error = setattr_prepare(&init_user_ns, dentry, attr);
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 252) 	if (error)
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 253) 		return error;
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 254) 
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 255) 	if ((attr->ia_valid & ATTR_SIZE) &&
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 256) 	    attr->ia_size != i_size_read(inode)) {
562c72aa57c36 (Christoph Hellwig    2011-06-24 14:29:45 -0400 257) 		inode_dio_wait(inode);
059a704c43ea8 (Sergei Antonov       2015-04-16 12:47:15 -0700 258) 		if (attr->ia_size > inode->i_size) {
059a704c43ea8 (Sergei Antonov       2015-04-16 12:47:15 -0700 259) 			error = generic_cont_expand_simple(inode,
059a704c43ea8 (Sergei Antonov       2015-04-16 12:47:15 -0700 260) 							   attr->ia_size);
059a704c43ea8 (Sergei Antonov       2015-04-16 12:47:15 -0700 261) 			if (error)
059a704c43ea8 (Sergei Antonov       2015-04-16 12:47:15 -0700 262) 				return error;
059a704c43ea8 (Sergei Antonov       2015-04-16 12:47:15 -0700 263) 		}
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100 264) 		truncate_setsize(inode, attr->ia_size);
d506848567b52 (Marco Stornelli      2012-12-15 11:55:07 +0100 265) 		hfsplus_file_truncate(inode);
dc8844aada735 (Ernesto A. Fernández 2018-10-30 15:06:27 -0700 266) 		inode->i_mtime = inode->i_ctime = current_time(inode);
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 267) 	}
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 268) 
2f221d6f7b881 (Christian Brauner    2021-01-21 14:19:26 +0100 269) 	setattr_copy(&init_user_ns, inode, attr);
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 270) 	mark_inode_dirty(inode);
b4c1107cc9626 (Vyacheslav Dubeyko   2013-09-11 14:24:30 -0700 271) 
1025774ce411f (Christoph Hellwig    2010-06-04 11:30:02 +0200 272) 	return 0;
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 273) }
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 274) 
549c7297717c3 (Christian Brauner    2021-01-21 14:19:43 +0100 275) int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path,
549c7297717c3 (Christian Brauner    2021-01-21 14:19:43 +0100 276) 		    struct kstat *stat, u32 request_mask,
549c7297717c3 (Christian Brauner    2021-01-21 14:19:43 +0100 277) 		    unsigned int query_flags)
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 278) {
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 279) 	struct inode *inode = d_inode(path->dentry);
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 280) 	struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 281) 
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 282) 	if (inode->i_flags & S_APPEND)
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 283) 		stat->attributes |= STATX_ATTR_APPEND;
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 284) 	if (inode->i_flags & S_IMMUTABLE)
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 285) 		stat->attributes |= STATX_ATTR_IMMUTABLE;
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 286) 	if (hip->userflags & HFSPLUS_FLG_NODUMP)
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 287) 		stat->attributes |= STATX_ATTR_NODUMP;
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 288) 
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 289) 	stat->attributes_mask |= STATX_ATTR_APPEND | STATX_ATTR_IMMUTABLE |
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 290) 				 STATX_ATTR_NODUMP;
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 291) 
0d56a4518d5ea (Christian Brauner    2021-01-21 14:19:30 +0100 292) 	generic_fillattr(&init_user_ns, inode, stat);
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 293) 	return 0;
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 294) }
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 295) 
02c24a82187d5 (Josef Bacik          2011-07-16 20:44:56 -0400 296) int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
02c24a82187d5 (Josef Bacik          2011-07-16 20:44:56 -0400 297) 		       int datasync)
b5fc510c48f63 (Al Viro              2010-07-04 12:24:09 +0400 298) {
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 299) 	struct inode *inode = file->f_mapping->host;
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 300) 	struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 301) 	struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 302) 	int error = 0, error2;
b5fc510c48f63 (Al Viro              2010-07-04 12:24:09 +0400 303) 
3b49c9a1e984b (Jeff Layton          2017-07-07 15:20:52 -0400 304) 	error = file_write_and_wait_range(file, start, end);
02c24a82187d5 (Josef Bacik          2011-07-16 20:44:56 -0400 305) 	if (error)
02c24a82187d5 (Josef Bacik          2011-07-16 20:44:56 -0400 306) 		return error;
5955102c9984f (Al Viro              2016-01-22 15:40:57 -0500 307) 	inode_lock(inode);
02c24a82187d5 (Josef Bacik          2011-07-16 20:44:56 -0400 308) 
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 309) 	/*
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 310) 	 * Sync inode metadata into the catalog and extent trees.
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 311) 	 */
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 312) 	sync_inode_metadata(inode, 1);
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 313) 
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 314) 	/*
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 315) 	 * And explicitly write out the btrees.
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 316) 	 */
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 317) 	if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags))
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 318) 		error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping);
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 319) 
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 320) 	if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) {
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 321) 		error2 =
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 322) 			filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 323) 		if (!error)
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 324) 			error = error2;
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 325) 	}
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 326) 
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 327) 	if (test_and_clear_bit(HFSPLUS_I_ATTR_DIRTY, &hip->flags)) {
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 328) 		if (sbi->attr_tree) {
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 329) 			error2 =
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 330) 				filemap_write_and_wait(
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 331) 					    sbi->attr_tree->inode->i_mapping);
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 332) 			if (!error)
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 333) 				error = error2;
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 334) 		} else {
d614267329f2b (Joe Perches          2013-04-30 15:27:55 -0700 335) 			pr_err("sync non-existent attributes tree\n");
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 336) 		}
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 337) 	}
324ef39a8a4f6 (Vyacheslav Dubeyko   2013-02-27 17:03:04 -0800 338) 
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 339) 	if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) {
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 340) 		error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 341) 		if (!error)
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 342) 			error = error2;
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 343) 	}
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 344) 
34a2d313c51f4 (Christoph Hellwig    2010-11-23 14:38:21 +0100 345) 	if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
c6bf3f0e25f4c (Christoph Hellwig    2021-01-26 15:52:35 +0100 346) 		blkdev_issue_flush(inode->i_sb->s_bdev);
34a2d313c51f4 (Christoph Hellwig    2010-11-23 14:38:21 +0100 347) 
5955102c9984f (Al Viro              2016-01-22 15:40:57 -0500 348) 	inode_unlock(inode);
02c24a82187d5 (Josef Bacik          2011-07-16 20:44:56 -0400 349) 
281469766bdde (Christoph Hellwig    2010-11-23 14:38:06 +0100 350) 	return error;
b5fc510c48f63 (Al Viro              2010-07-04 12:24:09 +0400 351) }
b5fc510c48f63 (Al Viro              2010-07-04 12:24:09 +0400 352) 
92e1d5be91a0e (Arjan van de Ven     2007-02-12 00:55:39 -0800 353) static const struct inode_operations hfsplus_file_inode_operations = {
d39aae9ec447d (Christoph Hellwig    2010-06-04 11:29:59 +0200 354) 	.setattr	= hfsplus_setattr,
f93ca1ed9ba09 (Ernesto A. Fernández 2019-01-03 15:27:46 -0800 355) 	.getattr	= hfsplus_getattr,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 356) 	.listxattr	= hfsplus_listxattr,
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 357) 	.fileattr_get	= hfsplus_fileattr_get,
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 358) 	.fileattr_set	= hfsplus_fileattr_set,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 359) };
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 360) 
4b6f5d20b04dc (Arjan van de Ven     2006-03-28 01:56:42 -0800 361) static const struct file_operations hfsplus_file_operations = {
20b7643d8ee44 (Anton Salikhmetov    2010-12-16 18:08:40 +0200 362) 	.llseek		= generic_file_llseek,
aad4f8bb42af0 (Al Viro              2014-04-02 14:33:16 -0400 363) 	.read_iter	= generic_file_read_iter,
8174202b34c30 (Al Viro              2014-04-03 03:17:43 -0400 364) 	.write_iter	= generic_file_write_iter,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 365) 	.mmap		= generic_file_mmap,
5ffc4ef45b3b0 (Jens Axboe           2007-06-01 11:49:19 +0200 366) 	.splice_read	= generic_file_splice_read,
b5fc510c48f63 (Al Viro              2010-07-04 12:24:09 +0400 367) 	.fsync		= hfsplus_file_fsync,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 368) 	.open		= hfsplus_file_open,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 369) 	.release	= hfsplus_file_release,
7cc4bcc6f152d (Arnd Bergmann        2010-04-27 16:24:20 +0200 370) 	.unlocked_ioctl = hfsplus_ioctl,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 371) };
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 372) 
b0cd38c7f54c9 (Ernesto A. Fernandez 2018-02-06 15:49:02 -0800 373) struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
b0cd38c7f54c9 (Ernesto A. Fernandez 2018-02-06 15:49:02 -0800 374) 				umode_t mode)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 375) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 376) 	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 377) 	struct inode *inode = new_inode(sb);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 378) 	struct hfsplus_inode_info *hip;
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 379) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 380) 	if (!inode)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 381) 		return NULL;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 382) 
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 383) 	inode->i_ino = sbi->next_cnid++;
21cb47be6fb9e (Christian Brauner    2021-01-21 14:19:25 +0100 384) 	inode_init_owner(&init_user_ns, inode, dir, mode);
bfe8684869601 (Miklos Szeredi       2011-10-28 14:13:29 +0200 385) 	set_nlink(inode, 1);
02027d42c3f74 (Deepa Dinamani       2016-09-14 07:48:05 -0700 386) 	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 387) 
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 388) 	hip = HFSPLUS_I(inode);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 389) 	INIT_LIST_HEAD(&hip->open_dir_list);
323ee8fc544d4 (Al Viro              2016-05-12 20:02:09 -0400 390) 	spin_lock_init(&hip->open_dir_lock);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 391) 	mutex_init(&hip->extents_lock);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 392) 	atomic_set(&hip->opencnt, 0);
b33b7921db14a (Christoph Hellwig    2010-11-23 14:38:13 +0100 393) 	hip->extent_state = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 394) 	hip->flags = 0;
f3922382ce930 (Matthew Garrett      2012-03-13 12:10:34 -0400 395) 	hip->userflags = 0;
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 396) 	hip->subfolders = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 397) 	memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec));
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 398) 	memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 399) 	hip->alloc_blocks = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 400) 	hip->first_blocks = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 401) 	hip->cached_start = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 402) 	hip->cached_blocks = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 403) 	hip->phys_size = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 404) 	hip->fs_blocks = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 405) 	hip->rsrc_inode = NULL;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 406) 	if (S_ISDIR(inode->i_mode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 407) 		inode->i_size = 2;
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 408) 		sbi->folder_count++;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 409) 		inode->i_op = &hfsplus_dir_inode_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 410) 		inode->i_fop = &hfsplus_dir_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 411) 	} else if (S_ISREG(inode->i_mode)) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 412) 		sbi->file_count++;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 413) 		inode->i_op = &hfsplus_file_inode_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 414) 		inode->i_fop = &hfsplus_file_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 415) 		inode->i_mapping->a_ops = &hfsplus_aops;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 416) 		hip->clump_blocks = sbi->data_clump_blocks;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 417) 	} else if (S_ISLNK(inode->i_mode)) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 418) 		sbi->file_count++;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 419) 		inode->i_op = &page_symlink_inode_operations;
21fc61c73c390 (Al Viro              2015-11-17 01:07:57 -0500 420) 		inode_nohighmem(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 421) 		inode->i_mapping->a_ops = &hfsplus_aops;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 422) 		hip->clump_blocks = 1;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 423) 	} else
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 424) 		sbi->file_count++;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 425) 	insert_inode_hash(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 426) 	mark_inode_dirty(inode);
9e6c5829b07c9 (Artem Bityutskiy     2012-07-12 17:26:31 +0300 427) 	hfsplus_mark_mdb_dirty(sb);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 428) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 429) 	return inode;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 430) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 431) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 432) void hfsplus_delete_inode(struct inode *inode)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 433) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 434) 	struct super_block *sb = inode->i_sb;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 435) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 436) 	if (S_ISDIR(inode->i_mode)) {
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 437) 		HFSPLUS_SB(sb)->folder_count--;
9e6c5829b07c9 (Artem Bityutskiy     2012-07-12 17:26:31 +0300 438) 		hfsplus_mark_mdb_dirty(sb);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 439) 		return;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 440) 	}
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 441) 	HFSPLUS_SB(sb)->file_count--;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 442) 	if (S_ISREG(inode->i_mode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 443) 		if (!inode->i_nlink) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 444) 			inode->i_size = 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 445) 			hfsplus_file_truncate(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 446) 		}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 447) 	} else if (S_ISLNK(inode->i_mode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 448) 		inode->i_size = 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 449) 		hfsplus_file_truncate(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 450) 	}
9e6c5829b07c9 (Artem Bityutskiy     2012-07-12 17:26:31 +0300 451) 	hfsplus_mark_mdb_dirty(sb);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 452) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 453) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 454) void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 455) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 456) 	struct super_block *sb = inode->i_sb;
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 457) 	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 458) 	struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 459) 	u32 count;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 460) 	int i;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 461) 
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 462) 	memcpy(&hip->first_extents, &fork->extents, sizeof(hfsplus_extent_rec));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 463) 	for (count = 0, i = 0; i < 8; i++)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 464) 		count += be32_to_cpu(fork->extents[i].block_count);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 465) 	hip->first_blocks = count;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 466) 	memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 467) 	hip->cached_start = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 468) 	hip->cached_blocks = 0;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 469) 
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 470) 	hip->alloc_blocks = be32_to_cpu(fork->total_blocks);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 471) 	hip->phys_size = inode->i_size = be64_to_cpu(fork->total_size);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 472) 	hip->fs_blocks =
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 473) 		(inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 474) 	inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 475) 	hip->clump_blocks =
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 476) 		be32_to_cpu(fork->clump_size) >> sbi->alloc_blksz_shift;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 477) 	if (!hip->clump_blocks) {
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 478) 		hip->clump_blocks = HFSPLUS_IS_RSRC(inode) ?
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 479) 			sbi->rsrc_clump_blocks :
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 480) 			sbi->data_clump_blocks;
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 481) 	}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 482) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 483) 
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 484) void hfsplus_inode_write_fork(struct inode *inode,
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 485) 		struct hfsplus_fork_raw *fork)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 486) {
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 487) 	memcpy(&fork->extents, &HFSPLUS_I(inode)->first_extents,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 488) 	       sizeof(hfsplus_extent_rec));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 489) 	fork->total_size = cpu_to_be64(inode->i_size);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 490) 	fork->total_blocks = cpu_to_be32(HFSPLUS_I(inode)->alloc_blocks);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 491) }
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 492) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 493) int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 494) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 495) 	hfsplus_cat_entry entry;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 496) 	int res = 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 497) 	u16 type;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 498) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 499) 	type = hfs_bnode_read_u16(fd->bnode, fd->entryoffset);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 500) 
f6089ff87d309 (Christoph Hellwig    2010-10-14 09:54:28 -0400 501) 	HFSPLUS_I(inode)->linkid = 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 502) 	if (type == HFSPLUS_FOLDER) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 503) 		struct hfsplus_cat_folder *folder = &entry.folder;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 504) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 505) 		if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 506) 			/* panic? */;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 507) 		hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 508) 					sizeof(struct hfsplus_cat_folder));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 509) 		hfsplus_get_perms(inode, &folder->permissions, 1);
bfe8684869601 (Miklos Szeredi       2011-10-28 14:13:29 +0200 510) 		set_nlink(inode, 1);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 511) 		inode->i_size = 2 + be32_to_cpu(folder->valence);
4ddfc3dc60a24 (Arnd Bergmann        2018-06-20 09:47:26 +0200 512) 		inode->i_atime = hfsp_mt2ut(folder->access_date);
4ddfc3dc60a24 (Arnd Bergmann        2018-06-20 09:47:26 +0200 513) 		inode->i_mtime = hfsp_mt2ut(folder->content_mod_date);
4ddfc3dc60a24 (Arnd Bergmann        2018-06-20 09:47:26 +0200 514) 		inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 515) 		HFSPLUS_I(inode)->create_date = folder->create_date;
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 516) 		HFSPLUS_I(inode)->fs_blocks = 0;
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 517) 		if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) {
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 518) 			HFSPLUS_I(inode)->subfolders =
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 519) 				be32_to_cpu(folder->subfolders);
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 520) 		}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 521) 		inode->i_op = &hfsplus_dir_inode_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 522) 		inode->i_fop = &hfsplus_dir_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 523) 	} else if (type == HFSPLUS_FILE) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 524) 		struct hfsplus_cat_file *file = &entry.file;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 525) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 526) 		if (fd->entrylength < sizeof(struct hfsplus_cat_file))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 527) 			/* panic? */;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 528) 		hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 529) 					sizeof(struct hfsplus_cat_file));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 530) 
b33b7921db14a (Christoph Hellwig    2010-11-23 14:38:13 +0100 531) 		hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ?
b33b7921db14a (Christoph Hellwig    2010-11-23 14:38:13 +0100 532) 					&file->rsrc_fork : &file->data_fork);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 533) 		hfsplus_get_perms(inode, &file->permissions, 0);
bfe8684869601 (Miklos Szeredi       2011-10-28 14:13:29 +0200 534) 		set_nlink(inode, 1);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 535) 		if (S_ISREG(inode->i_mode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 536) 			if (file->permissions.dev)
bfe8684869601 (Miklos Szeredi       2011-10-28 14:13:29 +0200 537) 				set_nlink(inode,
bfe8684869601 (Miklos Szeredi       2011-10-28 14:13:29 +0200 538) 					  be32_to_cpu(file->permissions.dev));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 539) 			inode->i_op = &hfsplus_file_inode_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 540) 			inode->i_fop = &hfsplus_file_operations;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 541) 			inode->i_mapping->a_ops = &hfsplus_aops;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 542) 		} else if (S_ISLNK(inode->i_mode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 543) 			inode->i_op = &page_symlink_inode_operations;
21fc61c73c390 (Al Viro              2015-11-17 01:07:57 -0500 544) 			inode_nohighmem(inode);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 545) 			inode->i_mapping->a_ops = &hfsplus_aops;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 546) 		} else {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 547) 			init_special_inode(inode, inode->i_mode,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 548) 					   be32_to_cpu(file->permissions.dev));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 549) 		}
4ddfc3dc60a24 (Arnd Bergmann        2018-06-20 09:47:26 +0200 550) 		inode->i_atime = hfsp_mt2ut(file->access_date);
4ddfc3dc60a24 (Arnd Bergmann        2018-06-20 09:47:26 +0200 551) 		inode->i_mtime = hfsp_mt2ut(file->content_mod_date);
4ddfc3dc60a24 (Arnd Bergmann        2018-06-20 09:47:26 +0200 552) 		inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date);
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 553) 		HFSPLUS_I(inode)->create_date = file->create_date;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 554) 	} else {
d614267329f2b (Joe Perches          2013-04-30 15:27:55 -0700 555) 		pr_err("bad catalog entry used to create inode\n");
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 556) 		res = -EIO;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 557) 	}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 558) 	return res;
^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) int hfsplus_cat_write_inode(struct inode *inode)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 562) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 563) 	struct inode *main_inode = inode;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 564) 	struct hfs_find_data fd;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 565) 	hfsplus_cat_entry entry;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 566) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 567) 	if (HFSPLUS_IS_RSRC(inode))
6af502de224c3 (Christoph Hellwig    2010-10-01 05:43:31 +0200 568) 		main_inode = HFSPLUS_I(inode)->rsrc_inode;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 569) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 570) 	if (!main_inode->i_nlink)
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 571) 		return 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 572) 
dd73a01a30d72 (Christoph Hellwig    2010-10-01 05:42:59 +0200 573) 	if (hfs_find_init(HFSPLUS_SB(main_inode->i_sb)->cat_tree, &fd))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 574) 		/* panic? */
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 575) 		return -EIO;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 576) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 577) 	if (hfsplus_find_cat(main_inode->i_sb, main_inode->i_ino, &fd))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 578) 		/* panic? */
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 579) 		goto out;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 580) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 581) 	if (S_ISDIR(main_inode->i_mode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 582) 		struct hfsplus_cat_folder *folder = &entry.folder;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 583) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 584) 		if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 585) 			/* panic? */;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 586) 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 587) 					sizeof(struct hfsplus_cat_folder));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 588) 		/* simple node checks? */
90e616905a423 (Christoph Hellwig    2010-10-14 09:54:39 -0400 589) 		hfsplus_cat_set_perms(inode, &folder->permissions);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 590) 		folder->access_date = hfsp_ut2mt(inode->i_atime);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 591) 		folder->content_mod_date = hfsp_ut2mt(inode->i_mtime);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 592) 		folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 593) 		folder->valence = cpu_to_be32(inode->i_size - 2);
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 594) 		if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) {
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 595) 			folder->subfolders =
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 596) 				cpu_to_be32(HFSPLUS_I(inode)->subfolders);
d7d673a591701 (Sergei Antonov       2014-03-10 15:49:51 -0700 597) 		}
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 598) 		hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 599) 					 sizeof(struct hfsplus_cat_folder));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 600) 	} else if (HFSPLUS_IS_RSRC(inode)) {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 601) 		struct hfsplus_cat_file *file = &entry.file;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 602) 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 603) 			       sizeof(struct hfsplus_cat_file));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 604) 		hfsplus_inode_write_fork(inode, &file->rsrc_fork);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 605) 		hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 606) 				sizeof(struct hfsplus_cat_file));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 607) 	} else {
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 608) 		struct hfsplus_cat_file *file = &entry.file;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 609) 
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 610) 		if (fd.entrylength < sizeof(struct hfsplus_cat_file))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 611) 			/* panic? */;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 612) 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 613) 					sizeof(struct hfsplus_cat_file));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 614) 		hfsplus_inode_write_fork(inode, &file->data_fork);
90e616905a423 (Christoph Hellwig    2010-10-14 09:54:39 -0400 615) 		hfsplus_cat_set_perms(inode, &file->permissions);
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 616) 		if (HFSPLUS_FLG_IMMUTABLE &
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 617) 				(file->permissions.rootflags |
2753cc281c9a0 (Anton Salikhmetov    2010-12-16 18:08:38 +0200 618) 					file->permissions.userflags))
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 619) 			file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 620) 		else
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 621) 			file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 622) 		file->access_date = hfsp_ut2mt(inode->i_atime);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 623) 		file->content_mod_date = hfsp_ut2mt(inode->i_mtime);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 624) 		file->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 625) 		hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 626) 					 sizeof(struct hfsplus_cat_file));
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 627) 	}
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 628) 
e34947056076c (Christoph Hellwig    2010-11-23 14:38:15 +0100 629) 	set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 630) out:
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 631) 	hfs_find_exit(&fd);
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 632) 	return 0;
^1da177e4c3f4 (Linus Torvalds       2005-04-16 15:20:36 -0700 633) }
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 634) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 635) int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 636) {
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 637) 	struct inode *inode = d_inode(dentry);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 638) 	struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 639) 	unsigned int flags = 0;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 640) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 641) 	if (inode->i_flags & S_IMMUTABLE)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 642) 		flags |= FS_IMMUTABLE_FL;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 643) 	if (inode->i_flags & S_APPEND)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 644) 		flags |= FS_APPEND_FL;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 645) 	if (hip->userflags & HFSPLUS_FLG_NODUMP)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 646) 		flags |= FS_NODUMP_FL;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 647) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 648) 	fileattr_fill_flags(fa, flags);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 649) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 650) 	return 0;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 651) }
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 652) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 653) int hfsplus_fileattr_set(struct user_namespace *mnt_userns,
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 654) 			 struct dentry *dentry, struct fileattr *fa)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 655) {
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 656) 	struct inode *inode = d_inode(dentry);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 657) 	struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 658) 	unsigned int new_fl = 0;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 659) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 660) 	if (fileattr_has_fsx(fa))
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 661) 		return -EOPNOTSUPP;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 662) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 663) 	/* don't silently ignore unsupported ext2 flags */
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 664) 	if (fa->flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL))
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 665) 		return -EOPNOTSUPP;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 666) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 667) 	if (fa->flags & FS_IMMUTABLE_FL)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 668) 		new_fl |= S_IMMUTABLE;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 669) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 670) 	if (fa->flags & FS_APPEND_FL)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 671) 		new_fl |= S_APPEND;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 672) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 673) 	inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 674) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 675) 	if (fa->flags & FS_NODUMP_FL)
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 676) 		hip->userflags |= HFSPLUS_FLG_NODUMP;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 677) 	else
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 678) 		hip->userflags &= ~HFSPLUS_FLG_NODUMP;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 679) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 680) 	inode->i_ctime = current_time(inode);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 681) 	mark_inode_dirty(inode);
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 682) 
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 683) 	return 0;
9cbae74838e62 (Miklos Szeredi       2021-04-07 14:36:44 +0200 684) }