File Index
Files and directories
Sign in
FILE

super.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/fs/super.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef _LINUX_FS_SUPER_H
  3#define _LINUX_FS_SUPER_H
  4
  5#include <linux/fs/super_types.h>
  6#include <linux/unicode.h>
  7
  8/*
  9 * These are internal functions, please use sb_start_{write,pagefault,intwrite}
 10 * instead.
 11 */
 12static inline void __sb_end_write(struct super_block *sb, int level)
 13{
 14	percpu_up_read(sb->s_writers.rw_sem + level - 1);
 15}
 16
 17static inline void __sb_start_write(struct super_block *sb, int level)
 18{
 19	percpu_down_read_freezable(sb->s_writers.rw_sem + level - 1, true);
 20}
 21
 22static inline bool __sb_start_write_trylock(struct super_block *sb, int level)
 23{
 24	return percpu_down_read_trylock(sb->s_writers.rw_sem + level - 1);
 25}
 26
 27#define __sb_writers_acquired(sb, lev) \
 28	percpu_rwsem_acquire(&(sb)->s_writers.rw_sem[(lev) - 1], 1, _THIS_IP_)
 29#define __sb_writers_release(sb, lev) \
 30	percpu_rwsem_release(&(sb)->s_writers.rw_sem[(lev) - 1], _THIS_IP_)
 31
 32/**
 33 * __sb_write_started - check if sb freeze level is held
 34 * @sb: the super we write to
 35 * @level: the freeze level
 36 *
 37 * * > 0 - sb freeze level is held
 38 * *   0 - sb freeze level is not held
 39 * * < 0 - !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN
 40 */
 41static inline int __sb_write_started(const struct super_block *sb, int level)
 42{
 43	return lockdep_is_held_type(sb->s_writers.rw_sem + level - 1, 1);
 44}
 45
 46/**
 47 * sb_write_started - check if SB_FREEZE_WRITE is held
 48 * @sb: the super we write to
 49 *
 50 * May be false positive with !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN.
 51 */
 52static inline bool sb_write_started(const struct super_block *sb)
 53{
 54	return __sb_write_started(sb, SB_FREEZE_WRITE);
 55}
 56
 57/**
 58 * sb_write_not_started - check if SB_FREEZE_WRITE is not held
 59 * @sb: the super we write to
 60 *
 61 * May be false positive with !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN.
 62 */
 63static inline bool sb_write_not_started(const struct super_block *sb)
 64{
 65	return __sb_write_started(sb, SB_FREEZE_WRITE) <= 0;
 66}
 67
 68/**
 69 * sb_end_write - drop write access to a superblock
 70 * @sb: the super we wrote to
 71 *
 72 * Decrement number of writers to the filesystem. Wake up possible waiters
 73 * wanting to freeze the filesystem.
 74 */
 75static inline void sb_end_write(struct super_block *sb)
 76{
 77	__sb_end_write(sb, SB_FREEZE_WRITE);
 78}
 79
 80/**
 81 * sb_end_pagefault - drop write access to a superblock from a page fault
 82 * @sb: the super we wrote to
 83 *
 84 * Decrement number of processes handling write page fault to the filesystem.
 85 * Wake up possible waiters wanting to freeze the filesystem.
 86 */
 87static inline void sb_end_pagefault(struct super_block *sb)
 88{
 89	__sb_end_write(sb, SB_FREEZE_PAGEFAULT);
 90}
 91
 92/**
 93 * sb_end_intwrite - drop write access to a superblock for internal fs purposes
 94 * @sb: the super we wrote to
 95 *
 96 * Decrement fs-internal number of writers to the filesystem.  Wake up possible
 97 * waiters wanting to freeze the filesystem.
 98 */
 99static inline void sb_end_intwrite(struct super_block *sb)
100{
101	__sb_end_write(sb, SB_FREEZE_FS);
102}
103
104/**
105 * sb_start_write - get write access to a superblock
106 * @sb: the super we write to
107 *
108 * When a process wants to write data or metadata to a file system (i.e. dirty
109 * a page or an inode), it should embed the operation in a sb_start_write() -
110 * sb_end_write() pair to get exclusion against file system freezing. This
111 * function increments number of writers preventing freezing. If the file
112 * system is already frozen, the function waits until the file system is
113 * thawed.
114 *
115 * Since freeze protection behaves as a lock, users have to preserve
116 * ordering of freeze protection and other filesystem locks. Generally,
117 * freeze protection should be the outermost lock. In particular, we have:
118 *
119 * sb_start_write
120 *   -> i_rwsem			(write path, truncate, directory ops, ...)
121 *   -> s_umount		(freeze_super, thaw_super)
122 */
123static inline void sb_start_write(struct super_block *sb)
124{
125	__sb_start_write(sb, SB_FREEZE_WRITE);
126}
127
128DEFINE_GUARD(super_write,
129	     struct super_block *,
130	     sb_start_write(_T),
131	     sb_end_write(_T))
132
133static inline bool sb_start_write_trylock(struct super_block *sb)
134{
135	return __sb_start_write_trylock(sb, SB_FREEZE_WRITE);
136}
137
138/**
139 * sb_start_pagefault - get write access to a superblock from a page fault
140 * @sb: the super we write to
141 *
142 * When a process starts handling write page fault, it should embed the
143 * operation into sb_start_pagefault() - sb_end_pagefault() pair to get
144 * exclusion against file system freezing. This is needed since the page fault
145 * is going to dirty a page. This function increments number of running page
146 * faults preventing freezing. If the file system is already frozen, the
147 * function waits until the file system is thawed.
148 *
149 * Since page fault freeze protection behaves as a lock, users have to preserve
150 * ordering of freeze protection and other filesystem locks. It is advised to
151 * put sb_start_pagefault() close to mmap_lock in lock ordering. Page fault
152 * handling code implies lock dependency:
153 *
154 * mmap_lock
155 *   -> sb_start_pagefault
156 */
157static inline void sb_start_pagefault(struct super_block *sb)
158{
159	__sb_start_write(sb, SB_FREEZE_PAGEFAULT);
160}
161
162/**
163 * sb_start_intwrite - get write access to a superblock for internal fs purposes
164 * @sb: the super we write to
165 *
166 * This is the third level of protection against filesystem freezing. It is
167 * free for use by a filesystem. The only requirement is that it must rank
168 * below sb_start_pagefault.
169 *
170 * For example filesystem can call sb_start_intwrite() when starting a
171 * transaction which somewhat eases handling of freezing for internal sources
172 * of filesystem changes (internal fs threads, discarding preallocation on file
173 * close, etc.).
174 */
175static inline void sb_start_intwrite(struct super_block *sb)
176{
177	__sb_start_write(sb, SB_FREEZE_FS);
178}
179
180static inline bool sb_start_intwrite_trylock(struct super_block *sb)
181{
182	return __sb_start_write_trylock(sb, SB_FREEZE_FS);
183}
184
185static inline bool sb_rdonly(const struct super_block *sb)
186{
187	return sb->s_flags & SB_RDONLY;
188}
189
190static inline bool sb_is_blkdev_sb(struct super_block *sb)
191{
192	return IS_ENABLED(CONFIG_BLOCK) && sb == blockdev_superblock;
193}
194
195#if IS_ENABLED(CONFIG_UNICODE)
196static inline struct unicode_map *sb_encoding(const struct super_block *sb)
197{
198	return sb->s_encoding;
199}
200
201/* Compare if two super blocks have the same encoding and flags */
202static inline bool sb_same_encoding(const struct super_block *sb1,
203				    const struct super_block *sb2)
204{
205	if (sb1->s_encoding == sb2->s_encoding)
206		return true;
207
208	return (sb1->s_encoding && sb2->s_encoding &&
209		(sb1->s_encoding->version == sb2->s_encoding->version) &&
210		(sb1->s_encoding_flags == sb2->s_encoding_flags));
211}
212#else
213static inline struct unicode_map *sb_encoding(const struct super_block *sb)
214{
215	return NULL;
216}
217
218static inline bool sb_same_encoding(const struct super_block *sb1,
219				    const struct super_block *sb2)
220{
221	return true;
222}
223#endif
224
225static inline bool sb_has_encoding(const struct super_block *sb)
226{
227	return !!sb_encoding(sb);
228}
229
230int sb_set_blocksize(struct super_block *sb, int size);
231int __must_check sb_min_blocksize(struct super_block *sb, int size);
232
233int freeze_super(struct super_block *super, enum freeze_holder who,
234		 const void *freeze_owner);
235int thaw_super(struct super_block *super, enum freeze_holder who,
236	       const void *freeze_owner);
237
238#endif /* _LINUX_FS_SUPER_H */
~/ Read-only file preview.