]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - fs/aufs/branch.h
UBUNTU: SAUCE: AUFS
[mirror_ubuntu-jammy-kernel.git] / fs / aufs / branch.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (C) 2005-2021 Junjiro R. Okajima
4 *
5 * This program, aufs is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /*
20 * branch filesystems and xino for them
21 */
22
23 #ifndef __AUFS_BRANCH_H__
24 #define __AUFS_BRANCH_H__
25
26 #ifdef __KERNEL__
27
28 #include <linux/mount.h>
29 #include "dirren.h"
30 #include "dynop.h"
31 #include "lcnt.h"
32 #include "rwsem.h"
33 #include "super.h"
34
35 /* ---------------------------------------------------------------------- */
36
37 /* a xino file */
38 struct au_xino {
39 struct file **xi_file;
40 unsigned int xi_nfile;
41
42 struct {
43 spinlock_t spin;
44 ino_t *array;
45 int total;
46 /* reserved for future use */
47 /* unsigned long *bitmap; */
48 wait_queue_head_t wqh;
49 } xi_nondir;
50
51 struct mutex xi_mtx; /* protects xi_file array */
52 struct hlist_bl_head xi_writing;
53
54 atomic_t xi_truncating;
55
56 struct kref xi_kref;
57 };
58
59 /* File-based Hierarchical Storage Management */
60 struct au_br_fhsm {
61 #ifdef CONFIG_AUFS_FHSM
62 struct mutex bf_lock;
63 unsigned long bf_jiffy;
64 struct aufs_stfs bf_stfs;
65 int bf_readable;
66 #endif
67 };
68
69 /* members for writable branch only */
70 enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
71 struct au_wbr {
72 struct au_rwsem wbr_wh_rwsem;
73 struct dentry *wbr_wh[AuBrWh_Last];
74 atomic_t wbr_wh_running;
75 #define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
76 #define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
77 #define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
78
79 /* mfs mode */
80 unsigned long long wbr_bytes;
81 };
82
83 /* ext2 has 3 types of operations at least, ext3 has 4 */
84 #define AuBrDynOp (AuDyLast * 4)
85
86 #ifdef CONFIG_AUFS_HFSNOTIFY
87 /* support for asynchronous destruction */
88 struct au_br_hfsnotify {
89 struct fsnotify_group *hfsn_group;
90 };
91 #endif
92
93 /* sysfs entries */
94 struct au_brsysfs {
95 char name[16];
96 struct attribute attr;
97 };
98
99 enum {
100 AuBrSysfs_BR,
101 AuBrSysfs_BRID,
102 AuBrSysfs_Last
103 };
104
105 /* protected by superblock rwsem */
106 struct au_branch {
107 struct au_xino *br_xino;
108
109 aufs_bindex_t br_id;
110
111 int br_perm;
112 struct path br_path;
113 spinlock_t br_dykey_lock;
114 struct au_dykey *br_dykey[AuBrDynOp];
115 au_lcnt_t br_nfiles; /* opened files */
116 au_lcnt_t br_count; /* in-use for other */
117
118 struct au_wbr *br_wbr;
119 struct au_br_fhsm *br_fhsm;
120
121 #ifdef CONFIG_AUFS_HFSNOTIFY
122 struct au_br_hfsnotify *br_hfsn;
123 #endif
124
125 #ifdef CONFIG_SYSFS
126 /* entries under sysfs per mount-point */
127 struct au_brsysfs br_sysfs[AuBrSysfs_Last];
128 #endif
129
130 #ifdef CONFIG_DEBUG_FS
131 struct dentry *br_dbgaufs; /* xino */
132 #endif
133
134 struct au_dr_br br_dirren;
135 };
136
137 /* ---------------------------------------------------------------------- */
138
139 static inline struct vfsmount *au_br_mnt(struct au_branch *br)
140 {
141 return br->br_path.mnt;
142 }
143
144 static inline struct dentry *au_br_dentry(struct au_branch *br)
145 {
146 return br->br_path.dentry;
147 }
148
149 static inline struct user_namespace *au_br_userns(struct au_branch *br)
150 {
151 return mnt_user_ns(br->br_path.mnt);
152 }
153
154 static inline struct super_block *au_br_sb(struct au_branch *br)
155 {
156 return au_br_mnt(br)->mnt_sb;
157 }
158
159 static inline int au_br_rdonly(struct au_branch *br)
160 {
161 return (sb_rdonly(au_br_sb(br))
162 || !au_br_writable(br->br_perm))
163 ? -EROFS : 0;
164 }
165
166 static inline int au_br_hnotifyable(int brperm __maybe_unused)
167 {
168 #ifdef CONFIG_AUFS_HNOTIFY
169 return !(brperm & AuBrPerm_RR);
170 #else
171 return 0;
172 #endif
173 }
174
175 static inline int au_br_test_oflag(int oflag, struct au_branch *br)
176 {
177 int err, exec_flag;
178
179 err = 0;
180 exec_flag = oflag & __FMODE_EXEC;
181 if (unlikely(exec_flag && path_noexec(&br->br_path)))
182 err = -EACCES;
183
184 return err;
185 }
186
187 static inline void au_xino_get(struct au_branch *br)
188 {
189 struct au_xino *xi;
190
191 xi = br->br_xino;
192 if (xi)
193 kref_get(&xi->xi_kref);
194 }
195
196 static inline int au_xino_count(struct au_branch *br)
197 {
198 int v;
199 struct au_xino *xi;
200
201 v = 0;
202 xi = br->br_xino;
203 if (xi)
204 v = kref_read(&xi->xi_kref);
205
206 return v;
207 }
208
209 /* ---------------------------------------------------------------------- */
210
211 /* branch.c */
212 struct au_sbinfo;
213 void au_br_free(struct au_sbinfo *sinfo);
214 int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
215 struct au_opt_add;
216 int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
217 struct au_opt_del;
218 int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
219 long au_ibusy_ioctl(struct file *file, unsigned long arg);
220 #ifdef CONFIG_COMPAT
221 long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
222 #endif
223 struct au_opt_mod;
224 int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
225 int *do_refresh);
226 struct aufs_stfs;
227 int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
228
229 /* xino.c */
230 static const loff_t au_loff_max = LLONG_MAX;
231
232 aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry);
233 struct file *au_xino_create(struct super_block *sb, char *fpath, int silent,
234 int wbrtop);
235 struct file *au_xino_create2(struct super_block *sb, struct path *base,
236 struct file *copy_src);
237 struct au_xi_new {
238 struct au_xino *xi; /* switch between xino and xigen */
239 int idx;
240 struct path *base;
241 struct file *copy_src;
242 };
243 struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew);
244
245 int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
246 ino_t *ino);
247 int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
248 ino_t ino);
249 ssize_t xino_fread(struct file *file, void *buf, size_t size, loff_t *pos);
250 ssize_t xino_fwrite(struct file *file, void *buf, size_t size, loff_t *pos);
251
252 int au_xib_trunc(struct super_block *sb);
253 int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin);
254
255 struct au_xino *au_xino_alloc(unsigned int nfile);
256 int au_xino_put(struct au_branch *br);
257 struct file *au_xino_file1(struct au_xino *xi);
258
259 struct au_opt_xino;
260 void au_xino_clr(struct super_block *sb);
261 int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount);
262 struct file *au_xino_def(struct super_block *sb);
263 int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino,
264 struct path *base);
265
266 ino_t au_xino_new_ino(struct super_block *sb);
267 void au_xino_delete_inode(struct inode *inode, const int unlinked);
268
269 void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
270 ino_t h_ino, int idx);
271 int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
272 int *idx);
273
274 int au_xino_path(struct seq_file *seq, struct file *file);
275
276 /* ---------------------------------------------------------------------- */
277
278 /* @idx is signed to accept -1 meaning the first file */
279 static inline struct file *au_xino_file(struct au_xino *xi, int idx)
280 {
281 struct file *file;
282
283 file = NULL;
284 if (!xi)
285 goto out;
286
287 if (idx >= 0) {
288 if (idx < xi->xi_nfile)
289 file = xi->xi_file[idx];
290 } else
291 file = au_xino_file1(xi);
292
293 out:
294 return file;
295 }
296
297 /* ---------------------------------------------------------------------- */
298
299 /* Superblock to branch */
300 static inline
301 aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
302 {
303 return au_sbr(sb, bindex)->br_id;
304 }
305
306 static inline
307 struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
308 {
309 return au_br_mnt(au_sbr(sb, bindex));
310 }
311
312 static inline
313 struct user_namespace *au_sbr_userns(struct super_block *sb, aufs_bindex_t bindex)
314 {
315 return au_br_userns(au_sbr(sb, bindex));
316 }
317
318 static inline
319 struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
320 {
321 return au_br_sb(au_sbr(sb, bindex));
322 }
323
324 static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
325 {
326 return au_sbr(sb, bindex)->br_perm;
327 }
328
329 static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
330 {
331 return au_br_whable(au_sbr_perm(sb, bindex));
332 }
333
334 /* ---------------------------------------------------------------------- */
335
336 #define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem)
337 #define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem)
338 #define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem)
339 #define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem)
340 /*
341 #define wbr_wh_read_trylock_nested(wbr) \
342 au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem)
343 #define wbr_wh_write_trylock_nested(wbr) \
344 au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem)
345 */
346
347 #define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem)
348 #define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem)
349 #define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem)
350
351 #define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem)
352 #define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem)
353 #define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem)
354
355 /* ---------------------------------------------------------------------- */
356
357 #ifdef CONFIG_AUFS_FHSM
358 static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
359 {
360 mutex_init(&brfhsm->bf_lock);
361 brfhsm->bf_jiffy = 0;
362 brfhsm->bf_readable = 0;
363 }
364
365 static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
366 {
367 mutex_destroy(&brfhsm->bf_lock);
368 }
369 #else
370 AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
371 AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
372 #endif
373
374 #endif /* __KERNEL__ */
375 #endif /* __AUFS_BRANCH_H__ */