xref: /linux/fs/bcachefs/fs.h (revision 42b16d3ac371a2fac9b6f08fd75f23f34ba3955a)
11c6fdbd8SKent Overstreet /* SPDX-License-Identifier: GPL-2.0 */
21c6fdbd8SKent Overstreet #ifndef _BCACHEFS_FS_H
31c6fdbd8SKent Overstreet #define _BCACHEFS_FS_H
41c6fdbd8SKent Overstreet 
52ea90048SKent Overstreet #include "inode.h"
61c6fdbd8SKent Overstreet #include "opts.h"
71c6fdbd8SKent Overstreet #include "str_hash.h"
81c6fdbd8SKent Overstreet #include "quota_types.h"
9a7ecd30cSKent Overstreet #include "two_state_shared_lock.h"
101c6fdbd8SKent Overstreet 
111c6fdbd8SKent Overstreet #include <linux/seqlock.h>
121c6fdbd8SKent Overstreet #include <linux/stat.h>
131c6fdbd8SKent Overstreet 
141c6fdbd8SKent Overstreet struct bch_inode_info {
151c6fdbd8SKent Overstreet 	struct inode		v;
169edbcc72SKent Overstreet 	struct rhash_head	hash;
1733c74e41SKent Overstreet 	subvol_inum		ei_inum;
181c6fdbd8SKent Overstreet 
191c6fdbd8SKent Overstreet 	struct list_head	ei_vfs_inode_list;
201c6fdbd8SKent Overstreet 	unsigned long		ei_flags;
211c6fdbd8SKent Overstreet 
22a7ecd30cSKent Overstreet 	struct mutex		ei_update_lock;
231c6fdbd8SKent Overstreet 	u64			ei_quota_reserved;
241c6fdbd8SKent Overstreet 	unsigned long		ei_last_dirtied;
251c6fdbd8SKent Overstreet 	two_state_lock_t	ei_pagecache_lock;
261c6fdbd8SKent Overstreet 
27284ae18cSKent Overstreet 	struct mutex		ei_quota_lock;
28284ae18cSKent Overstreet 	struct bch_qid		ei_qid;
29a8b3a677SKent Overstreet 
30a8b3a677SKent Overstreet 	/*
31a8b3a677SKent Overstreet 	 * When we've been doing nocow writes we'll need to issue flushes to the
32a8b3a677SKent Overstreet 	 * underlying block devices
33a8b3a677SKent Overstreet 	 *
34a8b3a677SKent Overstreet 	 * XXX: a device may have had a flush issued by some other codepath. It
35a8b3a677SKent Overstreet 	 * would be better to keep for each device a sequence number that's
36a8b3a677SKent Overstreet 	 * incremented when we isusue a cache flush, and track here the sequence
37a8b3a677SKent Overstreet 	 * number that needs flushing.
38a8b3a677SKent Overstreet 	 */
39a8b3a677SKent Overstreet 	struct bch_devs_mask	ei_devs_need_flush;
401c6fdbd8SKent Overstreet 
411c6fdbd8SKent Overstreet 	/* copy of inode in btree: */
421c6fdbd8SKent Overstreet 	struct bch_inode_unpacked ei_inode;
431c6fdbd8SKent Overstreet };
44a7ecd30cSKent Overstreet 
45a7ecd30cSKent Overstreet #define bch2_pagecache_add_put(i)	bch2_two_state_unlock(&i->ei_pagecache_lock, 0)
46a7ecd30cSKent Overstreet #define bch2_pagecache_add_tryget(i)	bch2_two_state_trylock(&i->ei_pagecache_lock, 0)
47a7ecd30cSKent Overstreet #define bch2_pagecache_add_get(i)	bch2_two_state_lock(&i->ei_pagecache_lock, 0)
48a7ecd30cSKent Overstreet 
49a7ecd30cSKent Overstreet #define bch2_pagecache_block_put(i)	bch2_two_state_unlock(&i->ei_pagecache_lock, 1)
50a7ecd30cSKent Overstreet #define bch2_pagecache_block_get(i)	bch2_two_state_lock(&i->ei_pagecache_lock, 1)
51284ae18cSKent Overstreet 
inode_inum(struct bch_inode_info * inode)52284ae18cSKent Overstreet static inline subvol_inum inode_inum(struct bch_inode_info *inode)
53284ae18cSKent Overstreet {
54284ae18cSKent Overstreet 	return inode->ei_inum;
55284ae18cSKent Overstreet }
56284ae18cSKent Overstreet 
57284ae18cSKent Overstreet struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum);
58284ae18cSKent Overstreet 
59*16005147SKent Overstreet /*
60*16005147SKent Overstreet  * Set if we've gotten a btree error for this inode, and thus the vfs inode and
6133c74e41SKent Overstreet  * btree inode may be inconsistent:
6233c74e41SKent Overstreet  */
6333c74e41SKent Overstreet #define EI_INODE_ERROR			0
6433c74e41SKent Overstreet 
6533c74e41SKent Overstreet /*
6633c74e41SKent Overstreet  * Set in the inode is in a snapshot subvolume - we don't do quota accounting in
679ca4853bSKent Overstreet  * those:
689ca4853bSKent Overstreet  */
699ca4853bSKent Overstreet #define EI_INODE_SNAPSHOT		1
709ca4853bSKent Overstreet #define EI_INODE_HASHED			2
719ca4853bSKent Overstreet 
729ca4853bSKent Overstreet #define to_bch_ei(_inode)					\
731c6fdbd8SKent Overstreet 	container_of_or_null(_inode, struct bch_inode_info, v)
741c6fdbd8SKent Overstreet 
ptrcmp(void * l,void * r)751c6fdbd8SKent Overstreet static inline int ptrcmp(void *l, void *r)
768095708fSKent Overstreet {
778095708fSKent Overstreet 	return cmp_int(l, r);
783ea2b1e1SKent Overstreet }
798095708fSKent Overstreet 
808095708fSKent Overstreet enum bch_inode_lock_op {
81168f4c5fSKent Overstreet 	INODE_PAGECACHE_BLOCK	= (1U << 0),
82ecf8a74dSKent Overstreet 	INODE_UPDATE_LOCK	= (1U << 1),
83ecf8a74dSKent Overstreet };
84168f4c5fSKent Overstreet 
85168f4c5fSKent Overstreet #define bch2_lock_inodes(_locks, ...)					\
86168f4c5fSKent Overstreet do {									\
878095708fSKent Overstreet 	struct bch_inode_info *a[] = { NULL, __VA_ARGS__ };		\
888095708fSKent Overstreet 	unsigned i;							\
898095708fSKent Overstreet 									\
908095708fSKent Overstreet 	bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp);			\
918095708fSKent Overstreet 									\
928095708fSKent Overstreet 	for (i = 1; i < ARRAY_SIZE(a); i++)				\
93168f4c5fSKent Overstreet 		if (a[i] != a[i - 1]) {					\
948095708fSKent Overstreet 			if ((_locks) & INODE_PAGECACHE_BLOCK)		\
9576426098SKent Overstreet 				bch2_pagecache_block_get(a[i]);\
96a7ecd30cSKent Overstreet 			if ((_locks) & INODE_UPDATE_LOCK)			\
9776426098SKent Overstreet 				mutex_lock_nested(&a[i]->ei_update_lock, i);\
988095708fSKent Overstreet 		}							\
998095708fSKent Overstreet } while (0)
1008095708fSKent Overstreet 
1018095708fSKent Overstreet #define bch2_unlock_inodes(_locks, ...)					\
102168f4c5fSKent Overstreet do {									\
103168f4c5fSKent Overstreet 	struct bch_inode_info *a[] = { NULL, __VA_ARGS__ };		\
104168f4c5fSKent Overstreet 	unsigned i;							\
105168f4c5fSKent Overstreet 									\
106168f4c5fSKent Overstreet 	bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp);			\
107168f4c5fSKent Overstreet 									\
108168f4c5fSKent Overstreet 	for (i = 1; i < ARRAY_SIZE(a); i++)				\
109168f4c5fSKent Overstreet 		if (a[i] != a[i - 1]) {					\
110168f4c5fSKent Overstreet 			if ((_locks) & INODE_PAGECACHE_BLOCK)		\
11176426098SKent Overstreet 				bch2_pagecache_block_put(a[i]);\
112a7ecd30cSKent Overstreet 			if ((_locks) & INODE_UPDATE_LOCK)			\
11376426098SKent Overstreet 				mutex_unlock(&a[i]->ei_update_lock);	\
114168f4c5fSKent Overstreet 		}							\
115168f4c5fSKent Overstreet } while (0)
116168f4c5fSKent Overstreet 
file_bch_inode(struct file * file)1178095708fSKent Overstreet static inline struct bch_inode_info *file_bch_inode(struct file *file)
1181c6fdbd8SKent Overstreet {
1191c6fdbd8SKent Overstreet 	return to_bch_ei(file_inode(file));
1201c6fdbd8SKent Overstreet }
1211c6fdbd8SKent Overstreet 
inode_attr_changing(struct bch_inode_info * dir,struct bch_inode_info * inode,enum inode_opt_id id)1221c6fdbd8SKent Overstreet static inline bool inode_attr_changing(struct bch_inode_info *dir,
12396012e14SKent Overstreet 				struct bch_inode_info *inode,
12496012e14SKent Overstreet 				enum inode_opt_id id)
12596012e14SKent Overstreet {
12696012e14SKent Overstreet 	return !(inode->ei_inode.bi_fields_set & (1 << id)) &&
12796012e14SKent Overstreet 		bch2_inode_opt_get(&dir->ei_inode, id) !=
12896012e14SKent Overstreet 		bch2_inode_opt_get(&inode->ei_inode, id);
12996012e14SKent Overstreet }
13096012e14SKent Overstreet 
inode_attrs_changing(struct bch_inode_info * dir,struct bch_inode_info * inode)13196012e14SKent Overstreet static inline bool inode_attrs_changing(struct bch_inode_info *dir,
13296012e14SKent Overstreet 				 struct bch_inode_info *inode)
13396012e14SKent Overstreet {
13496012e14SKent Overstreet 	unsigned id;
13596012e14SKent Overstreet 
13696012e14SKent Overstreet 	for (id = 0; id < Inode_opt_nr; id++)
13796012e14SKent Overstreet 		if (inode_attr_changing(dir, inode, id))
13896012e14SKent Overstreet 			return true;
13996012e14SKent Overstreet 
14096012e14SKent Overstreet 	return false;
14196012e14SKent Overstreet }
14296012e14SKent Overstreet 
14396012e14SKent Overstreet struct bch_inode_unpacked;
1441c6fdbd8SKent Overstreet 
1451c6fdbd8SKent Overstreet #ifndef NO_BCACHEFS_FS
1461c6fdbd8SKent Overstreet 
1471c6fdbd8SKent Overstreet struct bch_inode_info *
1486fed42bbSKent Overstreet __bch2_create(struct mnt_idmap *, struct bch_inode_info *,
1496fed42bbSKent Overstreet 	      struct dentry *, umode_t, dev_t, subvol_inum, unsigned);
15042d23732SKent Overstreet 
1516fed42bbSKent Overstreet int bch2_fs_quota_transfer(struct bch_fs *,
1520f5254aaSKent Overstreet 			   struct bch_inode_info *,
1530f5254aaSKent Overstreet 			   struct bch_qid,
1540f5254aaSKent Overstreet 			   unsigned,
1550f5254aaSKent Overstreet 			   enum quota_acct_mode);
1560f5254aaSKent Overstreet 
bch2_set_projid(struct bch_fs * c,struct bch_inode_info * inode,u32 projid)1570f5254aaSKent Overstreet static inline int bch2_set_projid(struct bch_fs *c,
1582fab25cdSKent Overstreet 				  struct bch_inode_info *inode,
1592fab25cdSKent Overstreet 				  u32 projid)
1602fab25cdSKent Overstreet {
1612fab25cdSKent Overstreet 	struct bch_qid qid = inode->ei_qid;
1622fab25cdSKent Overstreet 
1632fab25cdSKent Overstreet 	qid.q[QTYP_PRJ] = projid;
1642fab25cdSKent Overstreet 
1652fab25cdSKent Overstreet 	return bch2_fs_quota_transfer(c, inode, qid,
1662fab25cdSKent Overstreet 				      1 << QTYP_PRJ,
1672fab25cdSKent Overstreet 				      KEY_TYPE_QUOTA_PREALLOC);
1682fab25cdSKent Overstreet }
1692fab25cdSKent Overstreet 
1702fab25cdSKent Overstreet struct inode *bch2_vfs_inode_get(struct bch_fs *, subvol_inum);
171284ae18cSKent Overstreet 
1728095708fSKent Overstreet /* returns 0 if we want to do the update, or error is passed up */
1731c6fdbd8SKent Overstreet typedef int (*inode_set_fn)(struct btree_trans *,
174791236b8SJoshua Ashton 			    struct bch_inode_info *,
175791236b8SJoshua Ashton 			    struct bch_inode_unpacked *, void *);
1761c6fdbd8SKent Overstreet 
1771c6fdbd8SKent Overstreet void bch2_inode_update_after_write(struct btree_trans *,
17832b26e8cSKent Overstreet 				   struct bch_inode_info *,
1791c6fdbd8SKent Overstreet 				   struct bch_inode_unpacked *,
1801c6fdbd8SKent Overstreet 				   unsigned);
1811c6fdbd8SKent Overstreet int __must_check bch2_write_inode(struct bch_fs *, struct bch_inode_info *,
1822ea90048SKent Overstreet 				  inode_set_fn, void *, unsigned);
1831c6fdbd8SKent Overstreet 
1841c6fdbd8SKent Overstreet int bch2_setattr_nonsize(struct mnt_idmap *,
18568a507a2SKent Overstreet 			 struct bch_inode_info *,
18668a507a2SKent Overstreet 			 struct iattr *);
18768a507a2SKent Overstreet int __bch2_unlink(struct inode *, struct dentry *, bool);
1882027875bSKent Overstreet 
18968a507a2SKent Overstreet void bch2_evict_subvolume_inodes(struct bch_fs *, snapshot_id_list *);
19091d961baSKent Overstreet 
19141f9b7d3SKent Overstreet void bch2_fs_vfs_exit(struct bch_fs *);
1921c6fdbd8SKent Overstreet int bch2_fs_vfs_init(struct bch_fs *);
1931c6fdbd8SKent Overstreet 
1941c6fdbd8SKent Overstreet void bch2_vfs_exit(void);
1951c6fdbd8SKent Overstreet int bch2_vfs_init(void);
1961c6fdbd8SKent Overstreet 
197793a06d9SKent Overstreet #else
19807f293c8SKent Overstreet 
199*16005147SKent Overstreet #define bch2_inode_update_after_write(_trans, _inode, _inode_u, _fields)	({ do {} while (0); })
200*16005147SKent Overstreet 
__bch2_inode_hash_find(struct bch_fs * c,subvol_inum inum)201*16005147SKent Overstreet static inline struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
202*16005147SKent Overstreet {
203*16005147SKent Overstreet 	return NULL;
20441f9b7d3SKent Overstreet }
20591d961baSKent Overstreet 
bch2_evict_subvolume_inodes(struct bch_fs * c,snapshot_id_list * s)2061c6fdbd8SKent Overstreet static inline void bch2_evict_subvolume_inodes(struct bch_fs *c,
2071c6fdbd8SKent Overstreet 					       snapshot_id_list *s) {}
2081c6fdbd8SKent Overstreet 
bch2_fs_vfs_exit(struct bch_fs * c)2091c6fdbd8SKent Overstreet static inline void bch2_fs_vfs_exit(struct bch_fs *c) {}
bch2_fs_vfs_init(struct bch_fs * c)2101c6fdbd8SKent Overstreet static inline int bch2_fs_vfs_init(struct bch_fs *c) { return 0; }
2111c6fdbd8SKent Overstreet 
bch2_vfs_exit(void)212 static inline void bch2_vfs_exit(void) {}
bch2_vfs_init(void)213 static inline int bch2_vfs_init(void) { return 0; }
214 
215 #endif /* NO_BCACHEFS_FS */
216 
217 #endif /* _BCACHEFS_FS_H */
218