]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/fs.h
Update bcachefs sources to b91a514413 bcachefs: Don't try to delete stripes when RO
[bcachefs-tools-debian] / libbcachefs / fs.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_FS_H
3 #define _BCACHEFS_FS_H
4
5 #include "inode.h"
6 #include "opts.h"
7 #include "str_hash.h"
8 #include "quota_types.h"
9
10 #include <linux/seqlock.h>
11 #include <linux/stat.h>
12
13 struct bch_inode_info {
14         struct inode            v;
15
16         struct mutex            ei_update_lock;
17         struct deferred_update  *ei_inode_update;
18         u64                     ei_journal_seq;
19         u64                     ei_quota_reserved;
20         unsigned long           ei_last_dirtied;
21
22         struct mutex            ei_quota_lock;
23         struct bch_qid          ei_qid;
24
25         struct bch_hash_info    ei_str_hash;
26
27         /* copy of inode in btree: */
28         struct bch_inode_unpacked ei_inode;
29 };
30
31 #define to_bch_ei(_inode)                                       \
32         container_of_or_null(_inode, struct bch_inode_info, v)
33
34 static inline int ptrcmp(void *l, void *r)
35 {
36         return cmp_int(l, r);
37 }
38
39 enum bch_inode_lock_op {
40         INODE_LOCK              = (1U << 0),
41         INODE_UPDATE_LOCK       = (1U << 1),
42 };
43
44 #define bch2_lock_inodes(_locks, ...)                                   \
45 do {                                                                    \
46         struct bch_inode_info *a[] = { NULL, __VA_ARGS__ };             \
47         unsigned i;                                                     \
48                                                                         \
49         bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp);                  \
50                                                                         \
51         for (i = 1; i < ARRAY_SIZE(a); i++)                             \
52                 if (a[i] != a[i - 1]) {                                 \
53                         if (_locks & INODE_LOCK)                        \
54                                 down_write_nested(&a[i]->v.i_rwsem, i); \
55                         if (_locks & INODE_UPDATE_LOCK)                 \
56                                 mutex_lock_nested(&a[i]->ei_update_lock, i);\
57                 }                                                       \
58 } while (0)
59
60 #define bch2_unlock_inodes(_locks, ...)                                 \
61 do {                                                                    \
62         struct bch_inode_info *a[] = { NULL, __VA_ARGS__ };             \
63         unsigned i;                                                     \
64                                                                         \
65         bubble_sort(&a[1], ARRAY_SIZE(a) - 1, ptrcmp);                  \
66                                                                         \
67         for (i = 1; i < ARRAY_SIZE(a); i++)                             \
68                 if (a[i] != a[i - 1]) {                                 \
69                         if (_locks & INODE_LOCK)                        \
70                                 up_write(&a[i]->v.i_rwsem);             \
71                         if (_locks & INODE_UPDATE_LOCK)                 \
72                                 mutex_unlock(&a[i]->ei_update_lock);    \
73                 }                                                       \
74 } while (0)
75
76 static inline struct bch_inode_info *file_bch_inode(struct file *file)
77 {
78         return to_bch_ei(file_inode(file));
79 }
80
81 static inline u8 mode_to_type(umode_t mode)
82 {
83         return (mode >> 12) & 15;
84 }
85
86 static inline unsigned nlink_bias(umode_t mode)
87 {
88         return S_ISDIR(mode) ? 2 : 1;
89 }
90
91 static inline bool inode_attr_changing(struct bch_inode_info *dir,
92                                 struct bch_inode_info *inode,
93                                 enum inode_opt_id id)
94 {
95         return !(inode->ei_inode.bi_fields_set & (1 << id)) &&
96                 bch2_inode_opt_get(&dir->ei_inode, id) !=
97                 bch2_inode_opt_get(&inode->ei_inode, id);
98 }
99
100 static inline bool inode_attrs_changing(struct bch_inode_info *dir,
101                                  struct bch_inode_info *inode)
102 {
103         unsigned id;
104
105         for (id = 0; id < Inode_opt_nr; id++)
106                 if (inode_attr_changing(dir, inode, id))
107                         return true;
108
109         return false;
110 }
111
112 struct bch_inode_unpacked;
113
114 #ifndef NO_BCACHEFS_FS
115
116 int bch2_fs_quota_transfer(struct bch_fs *,
117                            struct bch_inode_info *,
118                            struct bch_qid,
119                            unsigned,
120                            enum quota_acct_mode);
121
122 static inline int bch2_set_projid(struct bch_fs *c,
123                                   struct bch_inode_info *inode,
124                                   u32 projid)
125 {
126         struct bch_qid qid = inode->ei_qid;
127
128         qid.q[QTYP_PRJ] = projid;
129
130         return bch2_fs_quota_transfer(c, inode, qid,
131                                       1 << QTYP_PRJ,
132                                       KEY_TYPE_QUOTA_PREALLOC);
133 }
134
135 struct inode *bch2_vfs_inode_get(struct bch_fs *, u64);
136
137 /* returns 0 if we want to do the update, or error is passed up */
138 typedef int (*inode_set_fn)(struct bch_inode_info *,
139                             struct bch_inode_unpacked *, void *);
140
141 void bch2_inode_update_after_write(struct bch_fs *,
142                                    struct bch_inode_info *,
143                                    struct bch_inode_unpacked *,
144                                    unsigned);
145 int __must_check bch2_write_inode_trans(struct btree_trans *,
146                                 struct bch_inode_info *,
147                                 struct bch_inode_unpacked *,
148                                 inode_set_fn, void *);
149 int __must_check bch2_write_inode(struct bch_fs *, struct bch_inode_info *,
150                                   inode_set_fn, void *, unsigned);
151
152 int bch2_reinherit_attrs_fn(struct bch_inode_info *,
153                             struct bch_inode_unpacked *,
154                             void *);
155
156 void bch2_vfs_exit(void);
157 int bch2_vfs_init(void);
158
159 #else
160
161 static inline void bch2_vfs_exit(void) {}
162 static inline int bch2_vfs_init(void) { return 0; }
163
164 #endif /* NO_BCACHEFS_FS */
165
166 #endif /* _BCACHEFS_FS_H */