← Documents Documentation/filesystems/vfs.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

Overview of the Linux Virtual File System

Linux VFS 객체와 operation table, page cache·dcache·mount 계약을 다룬 전문 번역입니다.

Source pathDocumentation/filesystems/vfs.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

vfs.rst:1-1551

VFS는 pathname을 dcache의 dentry로, dentry를 inode로, 열린 inode를 struct file로 연결해 서로 다른 파일 시스템을 동일 system call interface 뒤에 배치한다. mount에서는 file_system_type과 superblock, data I/O에서는 address_space, pathname cache에서는 dentry_operations가 각 구현 경계를 만든다.

callback 구현의 핵심은 호출 시점뿐 아니라 lock·RCU·reference 계약이다. RCU walk에서 block할 수 없으면 -ECHILD로 ref-walk 재호출을 요청하고, page·folio 수명과 writeback error cursor, directory의 단일 dentry 규칙을 지켜야 한다.

mount option은 parse만 하면 끝나지 않는다. 비기본 활성 설정을 show_options로 출력해 /proc/mounts만으로 mount를 재현할 수 있어야 한다.

VFS callback 계층
system call·pathnamedcache와 dentry_operationsinode와 inode_operationsstruct file과 file_operationsaddress_space_operations와 page cachesuper_operations와 mounted filesystemstorage 또는 device driver

userspace 요청이 object별 operation table을 거쳐 구현으로 전달된다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 =========================================
4 Overview of the Linux Virtual File System
5 =========================================
6
7 Original author: Richard Gooch <[email protected]>
8
9 - Copyright (C) 1999 Richard Gooch
10 - Copyright (C) 2005 Pekka Enberg
11
12
13 Introduction
14 ============
15
16 The Virtual File System (also known as the Virtual Filesystem Switch) is
17 the software layer in the kernel that provides the filesystem interface
18 to userspace programs. It also provides an abstraction within the
19 kernel which allows different filesystem implementations to coexist.
20
21 VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so on
22 are called from a process context. Filesystem locking is described in
23 the document Documentation/filesystems/locking.rst.
24
25
26 Directory Entry Cache (dcache)
27 ------------------------------
28
29 The VFS implements the open(2), stat(2), chmod(2), and similar system
30 calls. The pathname argument that is passed to them is used by the VFS
31 to search through the directory entry cache (also known as the dentry
32 cache or dcache). This provides a very fast look-up mechanism to
33 translate a pathname (filename) into a specific dentry. Dentries live
34 in RAM and are never saved to disc: they exist only for performance.
35
36 The dentry cache is meant to be a view into your entire filespace. As
37 most computers cannot fit all dentries in the RAM at the same time, some
38 bits of the cache are missing. In order to resolve your pathname into a
39 dentry, the VFS may have to resort to creating dentries along the way,
40 and then loading the inode. This is done by looking up the inode.
41
42
43 The Inode Object
44 ----------------
45
46 An individual dentry usually has a pointer to an inode. Inodes are
47 filesystem objects such as regular files, directories, FIFOs and other
48 beasts. They live either on the disc (for block device filesystems) or
49 in the memory (for pseudo filesystems). Inodes that live on the disc
50 are copied into the memory when required and changes to the inode are
51 written back to disc. A single inode can be pointed to by multiple
52 dentries (hard links, for example, do this).
53
54 To look up an inode requires that the VFS calls the lookup() method of
55 the parent directory inode. This method is installed by the specific
56 filesystem implementation that the inode lives in. Once the VFS has the
57 required dentry (and hence the inode), we can do all those boring things
58 like open(2) the file, or stat(2) it to peek at the inode data. The
59 stat(2) operation is fairly simple: once the VFS has the dentry, it
60 peeks at the inode data and passes some of it back to userspace.
61
62
63 The File Object
64 ---------------
65
66 Opening a file requires another operation: allocation of a file
67 structure (this is the kernel-side implementation of file descriptors).
68 The freshly allocated file structure is initialized with a pointer to
69 the dentry and a set of file operation member functions. These are
70 taken from the inode data. The open() file method is then called so the
71 specific filesystem implementation can do its work. You can see that
72 this is another switch performed by the VFS. The file structure is
73 placed into the file descriptor table for the process.
74
75 Reading, writing and closing files (and other assorted VFS operations)
76 is done by using the userspace file descriptor to grab the appropriate
77 file structure, and then calling the required file structure method to
78 do whatever is required. For as long as the file is open, it keeps the
79 dentry in use, which in turn means that the VFS inode is still in use.
80
81
82 Registering and Mounting a Filesystem
83 =====================================
84
85 To register and unregister a filesystem, use the following API
86 functions:
87
88 .. code-block:: c
89
90 #include <linux/fs.h>
91
92 extern int register_filesystem(struct file_system_type *);
93 extern int unregister_filesystem(struct file_system_type *);
94
95 The passed struct file_system_type describes your filesystem. When a
96 request is made to mount a filesystem onto a directory in your
97 namespace, the VFS will call the appropriate mount() method for the
98 specific filesystem. New vfsmount referring to the tree returned by
99 ->mount() will be attached to the mountpoint, so that when pathname
100 resolution reaches the mountpoint it will jump into the root of that
101 vfsmount.
102
103 You can see all filesystems that are registered to the kernel in the
104 file /proc/filesystems.
105
106
107 struct file_system_type
108 -----------------------
109
110 This describes the filesystem. The following
111 members are defined:
112
113 .. code-block:: c
114
115 struct file_system_type {
116 const char *name;
117 int fs_flags;
118 int (*init_fs_context)(struct fs_context *);
119 const struct fs_parameter_spec *parameters;
120 struct dentry *(*mount) (struct file_system_type *, int,
121 const char *, void *);
122 void (*kill_sb) (struct super_block *);
123 struct module *owner;
124 struct file_system_type * next;
125 struct hlist_head fs_supers;
126
127 struct lock_class_key s_lock_key;
128 struct lock_class_key s_umount_key;
129 struct lock_class_key s_vfs_rename_key;
130 struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];
131
132 struct lock_class_key i_lock_key;
133 struct lock_class_key i_mutex_key;
134 struct lock_class_key invalidate_lock_key;
135 struct lock_class_key i_mutex_dir_key;
136 };
137
138 ``name``
139 the name of the filesystem type, such as "ext2", "iso9660",
140 "msdos" and so on
141
142 ``fs_flags``
143 various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)
144
145 ``init_fs_context``
146 Initializes 'struct fs_context' ->ops and ->fs_private fields with
147 filesystem-specific data.
148
149 ``parameters``
150 Pointer to the array of filesystem parameters descriptors
151 'struct fs_parameter_spec'.
152 More info in Documentation/filesystems/mount_api.rst.
153
154 ``mount``
155 the method to call when a new instance of this filesystem should
156 be mounted
157
158 ``kill_sb``
159 the method to call when an instance of this filesystem should be
160 shut down
161
162
163 ``owner``
164 for internal VFS use: you should initialize this to THIS_MODULE
165 in most cases.
166
167 ``next``
168 for internal VFS use: you should initialize this to NULL
169
170 ``fs_supers``
171 for internal VFS use: hlist of filesystem instances (superblocks)
172
173 s_lock_key, s_umount_key, s_vfs_rename_key, s_writers_key,
174 i_lock_key, i_mutex_key, invalidate_lock_key, i_mutex_dir_key: lockdep-specific
175
176 The mount() method has the following arguments:
177
178 ``struct file_system_type *fs_type``
179 describes the filesystem, partly initialized by the specific
180 filesystem code
181
182 ``int flags``
183 mount flags
184
185 ``const char *dev_name``
186 the device name we are mounting.
187
188 ``void *data``
189 arbitrary mount options, usually comes as an ASCII string (see
190 "Mount Options" section)
191
192 The mount() method must return the root dentry of the tree requested by
193 caller. An active reference to its superblock must be grabbed and the
194 superblock must be locked. On failure it should return ERR_PTR(error).
195
196 The arguments match those of mount(2) and their interpretation depends
197 on filesystem type. E.g. for block filesystems, dev_name is interpreted
198 as block device name, that device is opened and if it contains a
199 suitable filesystem image the method creates and initializes struct
200 super_block accordingly, returning its root dentry to caller.
201
202 ->mount() may choose to return a subtree of existing filesystem - it
203 doesn't have to create a new one. The main result from the caller's
204 point of view is a reference to dentry at the root of (sub)tree to be
205 attached; creation of new superblock is a common side effect.
206
207 The most interesting member of the superblock structure that the mount()
208 method fills in is the "s_op" field. This is a pointer to a "struct
209 super_operations" which describes the next level of the filesystem
210 implementation.
211
212 For more information on mounting (and the new mount API), see
213 Documentation/filesystems/mount_api.rst.
214
215 The Superblock Object
216 =====================
217
218 A superblock object represents a mounted filesystem.
219
220
221 struct super_operations
222 -----------------------
223
224 This describes how the VFS can manipulate the superblock of your
225 filesystem. The following members are defined:
226
227 .. code-block:: c
228
229 struct super_operations {
230 struct inode *(*alloc_inode)(struct super_block *sb);
231 void (*destroy_inode)(struct inode *);
232 void (*free_inode)(struct inode *);
233
234 void (*dirty_inode) (struct inode *, int flags);
235 int (*write_inode) (struct inode *, struct writeback_control *wbc);
236 int (*drop_inode) (struct inode *);
237 void (*evict_inode) (struct inode *);
238 void (*put_super) (struct super_block *);
239 int (*sync_fs)(struct super_block *sb, int wait);
240 int (*freeze_super) (struct super_block *sb,
241 enum freeze_holder who);
242 int (*freeze_fs) (struct super_block *);
243 int (*thaw_super) (struct super_block *sb,
244 enum freeze_wholder who);
245 int (*unfreeze_fs) (struct super_block *);
246 int (*statfs) (struct dentry *, struct kstatfs *);
247 int (*remount_fs) (struct super_block *, int *, char *);
248 void (*umount_begin) (struct super_block *);
249
250 int (*show_options)(struct seq_file *, struct dentry *);
251 int (*show_devname)(struct seq_file *, struct dentry *);
252 int (*show_path)(struct seq_file *, struct dentry *);
253 int (*show_stats)(struct seq_file *, struct dentry *);
254
255 ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
256 ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
257 struct dquot **(*get_dquots)(struct inode *);
258
259 long (*nr_cached_objects)(struct super_block *,
260 struct shrink_control *);
261 long (*free_cached_objects)(struct super_block *,
262 struct shrink_control *);
263 };
264
265 All methods are called without any locks being held, unless otherwise
266 noted. This means that most methods can block safely. All methods are
267 only called from a process context (i.e. not from an interrupt handler
268 or bottom half).
269
270 ``alloc_inode``
271 this method is called by alloc_inode() to allocate memory for
272 struct inode and initialize it. If this function is not
273 defined, a simple 'struct inode' is allocated. Normally
274 alloc_inode will be used to allocate a larger structure which
275 contains a 'struct inode' embedded within it.
276
277 ``destroy_inode``
278 this method is called by destroy_inode() to release resources
279 allocated for struct inode. It is only required if
280 ->alloc_inode was defined and simply undoes anything done by
281 ->alloc_inode.
282
283 ``free_inode``
284 this method is called from RCU callback. If you use call_rcu()
285 in ->destroy_inode to free 'struct inode' memory, then it's
286 better to release memory in this method.
287
288 ``dirty_inode``
289 this method is called by the VFS when an inode is marked dirty.
290 This is specifically for the inode itself being marked dirty,
291 not its data. If the update needs to be persisted by fdatasync(),
292 then I_DIRTY_DATASYNC will be set in the flags argument.
293 I_DIRTY_TIME will be set in the flags in case lazytime is enabled
294 and struct inode has times updated since the last ->dirty_inode
295 call.
296
297 ``write_inode``
298 this method is called when the VFS needs to write an inode to
299 disc. The second parameter indicates whether the write should
300 be synchronous or not, not all filesystems check this flag.
301
302 ``drop_inode``
303 called when the last access to the inode is dropped, with the
304 inode->i_lock spinlock held.
305
306 This method should be either NULL (normal UNIX filesystem
307 semantics) or "inode_just_drop" (for filesystems that do
308 not want to cache inodes - causing "delete_inode" to always be
309 called regardless of the value of i_nlink)
310
311 The "inode_just_drop()" behavior is equivalent to the old
312 practice of using "force_delete" in the put_inode() case, but
313 does not have the races that the "force_delete()" approach had.
314
315 ``evict_inode``
316 called when the VFS wants to evict an inode. Caller does
317 *not* evict the pagecache or inode-associated metadata buffers;
318 the method has to use truncate_inode_pages_final() to get rid
319 of those. Caller makes sure async writeback cannot be running for
320 the inode while (or after) ->evict_inode() is called. Optional.
321
322 ``put_super``
323 called when the VFS wishes to free the superblock
324 (i.e. unmount). This is called with the superblock lock held
325
326 ``sync_fs``
327 called when VFS is writing out all dirty data associated with a
328 superblock. The second parameter indicates whether the method
329 should wait until the write out has been completed. Optional.
330
331 ``freeze_super``
332 Called instead of ->freeze_fs callback if provided.
333 Main difference is that ->freeze_super is called without taking
334 down_write(&sb->s_umount). If filesystem implements it and wants
335 ->freeze_fs to be called too, then it has to call ->freeze_fs
336 explicitly from this callback. Optional.
337
338 ``freeze_fs``
339 called when VFS is locking a filesystem and forcing it into a
340 consistent state. This method is currently used by the Logical
341 Volume Manager (LVM) and ioctl(FIFREEZE). Optional.
342
343 ``thaw_super``
344 called when VFS is unlocking a filesystem and making it writable
345 again after ->freeze_super. Optional.
346
347 ``unfreeze_fs``
348 called when VFS is unlocking a filesystem and making it writable
349 again after ->freeze_fs. Optional.
350
351 ``statfs``
352 called when the VFS needs to get filesystem statistics.
353
354 ``remount_fs``
355 called when the filesystem is remounted. This is called with
356 the kernel lock held
357
358 ``umount_begin``
359 called when the VFS is unmounting a filesystem.
360
361 ``show_options``
362 called by the VFS to show mount options for /proc/<pid>/mounts
363 and /proc/<pid>/mountinfo.
364 (see "Mount Options" section)
365
366 ``show_devname``
367 Optional. Called by the VFS to show device name for
368 /proc/<pid>/{mounts,mountinfo,mountstats}. If not provided then
369 '(struct mount).mnt_devname' will be used.
370
371 ``show_path``
372 Optional. Called by the VFS (for /proc/<pid>/mountinfo) to show
373 the mount root dentry path relative to the filesystem root.
374
375 ``show_stats``
376 Optional. Called by the VFS (for /proc/<pid>/mountstats) to show
377 filesystem-specific mount statistics.
378
379 ``quota_read``
380 called by the VFS to read from filesystem quota file.
381
382 ``quota_write``
383 called by the VFS to write to filesystem quota file.
384
385 ``get_dquots``
386 called by quota to get 'struct dquot' array for a particular inode.
387 Optional.
388
389 ``nr_cached_objects``
390 called by the sb cache shrinking function for the filesystem to
391 return the number of freeable cached objects it contains.
392 Optional.
393
394 ``free_cache_objects``
395 called by the sb cache shrinking function for the filesystem to
396 scan the number of objects indicated to try to free them.
397 Optional, but any filesystem implementing this method needs to
398 also implement ->nr_cached_objects for it to be called
399 correctly.
400
401 We can't do anything with any errors that the filesystem might
402 encountered, hence the void return type. This will never be
403 called if the VM is trying to reclaim under GFP_NOFS conditions,
404 hence this method does not need to handle that situation itself.
405
406 Implementations must include conditional reschedule calls inside
407 any scanning loop that is done. This allows the VFS to
408 determine appropriate scan batch sizes without having to worry
409 about whether implementations will cause holdoff problems due to
410 large scan batch sizes.
411
412 Whoever sets up the inode is responsible for filling in the "i_op"
413 field. This is a pointer to a "struct inode_operations" which describes
414 the methods that can be performed on individual inodes.
415
416
417 struct xattr_handler
418 ---------------------
419
420 On filesystems that support extended attributes (xattrs), the s_xattr
421 superblock field points to a NULL-terminated array of xattr handlers.
422 Extended attributes are name:value pairs.
423
424 ``name``
425 Indicates that the handler matches attributes with the specified
426 name (such as "system.posix_acl_access"); the prefix field must
427 be NULL.
428
429 ``prefix``
430 Indicates that the handler matches all attributes with the
431 specified name prefix (such as "user."); the name field must be
432 NULL.
433
434 ``list``
435 Determine if attributes matching this xattr handler should be
436 listed for a particular dentry. Used by some listxattr
437 implementations like generic_listxattr.
438
439 ``get``
440 Called by the VFS to get the value of a particular extended
441 attribute. This method is called by the getxattr(2) system
442 call.
443
444 ``set``
445 Called by the VFS to set the value of a particular extended
446 attribute. When the new value is NULL, called to remove a
447 particular extended attribute. This method is called by the
448 setxattr(2) and removexattr(2) system calls.
449
450 When none of the xattr handlers of a filesystem match the specified
451 attribute name or when a filesystem doesn't support extended attributes,
452 the various ``*xattr(2)`` system calls return -EOPNOTSUPP.
453
454
455 The Inode Object
456 ================
457
458 An inode object represents an object within the filesystem.
459
460
461 struct inode_operations
462 -----------------------
463
464 This describes how the VFS can manipulate an inode in your filesystem.
465 As of kernel 2.6.22, the following members are defined:
466
467 .. code-block:: c
468
469 struct inode_operations {
470 int (*create) (struct mnt_idmap *, struct inode *,struct dentry *, umode_t, bool);
471 struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
472 int (*link) (struct dentry *,struct inode *,struct dentry *);
473 int (*unlink) (struct inode *,struct dentry *);
474 int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
475 struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
476 int (*rmdir) (struct inode *,struct dentry *);
477 int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
478 int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
479 struct inode *, struct dentry *, unsigned int);
480 int (*readlink) (struct dentry *, char __user *,int);
481 const char *(*get_link) (struct dentry *, struct inode *,
482 struct delayed_call *);
483 int (*permission) (struct mnt_idmap *, struct inode *, int);
484 struct posix_acl * (*get_inode_acl)(struct inode *, int, bool);
485 int (*setattr) (struct mnt_idmap *, struct dentry *, struct iattr *);
486 int (*getattr) (struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int);
487 ssize_t (*listxattr) (struct dentry *, char *, size_t);
488 void (*update_time)(struct inode *, struct timespec *, int);
489 int (*atomic_open)(struct inode *, struct dentry *, struct file *,
490 unsigned open_flag, umode_t create_mode);
491 int (*tmpfile) (struct mnt_idmap *, struct inode *, struct file *, umode_t);
492 struct posix_acl * (*get_acl)(struct mnt_idmap *, struct dentry *, int);
493 int (*set_acl)(struct mnt_idmap *, struct dentry *, struct posix_acl *, int);
494 int (*fileattr_set)(struct mnt_idmap *idmap,
495 struct dentry *dentry, struct file_kattr *fa);
496 int (*fileattr_get)(struct dentry *dentry, struct file_kattr *fa);
497 struct offset_ctx *(*get_offset_ctx)(struct inode *inode);
498 };
499
500 Again, all methods are called without any locks being held, unless
501 otherwise noted.
502
503 ``create``
504 called by the open(2) and creat(2) system calls. Only required
505 if you want to support regular files. The dentry you get should
506 not have an inode (i.e. it should be a negative dentry). Here
507 you will probably call d_instantiate() with the dentry and the
508 newly created inode
509
510 ``lookup``
511 called when the VFS needs to look up an inode in a parent
512 directory. The name to look for is found in the dentry. This
513 method must call d_add() to insert the found inode into the
514 dentry. The "i_count" field in the inode structure should be
515 incremented. If the named inode does not exist a NULL inode
516 should be inserted into the dentry (this is called a negative
517 dentry). Returning an error code from this routine must only be
518 done on a real error, otherwise creating inodes with system
519 calls like create(2), mknod(2), mkdir(2) and so on will fail.
520 If you wish to overload the dentry methods then you should
521 initialise the "d_dop" field in the dentry; this is a pointer to
522 a struct "dentry_operations". This method is called with the
523 directory inode semaphore held
524
525 ``link``
526 called by the link(2) system call. Only required if you want to
527 support hard links. You will probably need to call
528 d_instantiate() just as you would in the create() method
529
530 ``unlink``
531 called by the unlink(2) system call. Only required if you want
532 to support deleting inodes
533
534 ``symlink``
535 called by the symlink(2) system call. Only required if you want
536 to support symlinks. You will probably need to call
537 d_instantiate() just as you would in the create() method
538
539 ``mkdir``
540 called by the mkdir(2) system call. Only required if you want
541 to support creating subdirectories. You will probably need to
542 call d_instantiate_new() just as you would in the create() method.
543
544 If d_instantiate_new() is not used and if the fh_to_dentry()
545 export operation is provided, or if the storage might be
546 accessible by another path (e.g. with a network filesystem)
547 then more care may be needed. Importantly d_instantate()
548 should not be used with an inode that is no longer I_NEW if there
549 any chance that the inode could already be attached to a dentry.
550 This is because of a hard rule in the VFS that a directory must
551 only ever have one dentry.
552
553 For example, if an NFS filesystem is mounted twice the new directory
554 could be visible on the other mount before it is on the original
555 mount, and a pair of name_to_handle_at(), open_by_handle_at()
556 calls could instantiate the directory inode with an IS_ROOT()
557 dentry before the first mkdir returns.
558
559 If there is any chance this could happen, then the new inode
560 should be d_drop()ed and attached with d_splice_alias(). The
561 returned dentry (if any) should be returned by ->mkdir().
562
563 ``rmdir``
564 called by the rmdir(2) system call. Only required if you want
565 to support deleting subdirectories
566
567 ``mknod``
568 called by the mknod(2) system call to create a device (char,
569 block) inode or a named pipe (FIFO) or socket. Only required if
570 you want to support creating these types of inodes. You will
571 probably need to call d_instantiate() just as you would in the
572 create() method
573
574 ``rename``
575 called by the rename(2) system call to rename the object to have
576 the parent and name given by the second inode and dentry.
577
578 The filesystem must return -EINVAL for any unsupported or
579 unknown flags. Currently the following flags are implemented:
580 (1) RENAME_NOREPLACE: this flag indicates that if the target of
581 the rename exists the rename should fail with -EEXIST instead of
582 replacing the target. The VFS already checks for existence, so
583 for local filesystems the RENAME_NOREPLACE implementation is
584 equivalent to plain rename.
585 (2) RENAME_EXCHANGE: exchange source and target. Both must
586 exist; this is checked by the VFS. Unlike plain rename, source
587 and target may be of different type.
588
589 ``get_link``
590 called by the VFS to follow a symbolic link to the inode it
591 points to. Only required if you want to support symbolic links.
592 This method returns the symlink body to traverse (and possibly
593 resets the current position with nd_jump_link()). If the body
594 won't go away until the inode is gone, nothing else is needed;
595 if it needs to be otherwise pinned, arrange for its release by
596 having get_link(..., ..., done) do set_delayed_call(done,
597 destructor, argument). In that case destructor(argument) will
598 be called once VFS is done with the body you've returned. May
599 be called in RCU mode; that is indicated by NULL dentry
600 argument. If request can't be handled without leaving RCU mode,
601 have it return ERR_PTR(-ECHILD).
602
603 If the filesystem stores the symlink target in ->i_link, the
604 VFS may use it directly without calling ->get_link(); however,
605 ->get_link() must still be provided. ->i_link must not be
606 freed until after an RCU grace period. Writing to ->i_link
607 post-iget() time requires a 'release' memory barrier.
608
609 ``readlink``
610 this is now just an override for use by readlink(2) for the
611 cases when ->get_link uses nd_jump_link() or object is not in
612 fact a symlink. Normally filesystems should only implement
613 ->get_link for symlinks and readlink(2) will automatically use
614 that.
615
616 ``permission``
617 called by the VFS to check for access rights on a POSIX-like
618 filesystem.
619
620 May be called in rcu-walk mode (mask & MAY_NOT_BLOCK). If in
621 rcu-walk mode, the filesystem must check the permission without
622 blocking or storing to the inode.
623
624 If a situation is encountered that rcu-walk cannot handle,
625 return
626 -ECHILD and it will be called again in ref-walk mode.
627
628 ``setattr``
629 called by the VFS to set attributes for a file. This method is
630 called by chmod(2) and related system calls.
631
632 ``getattr``
633 called by the VFS to get attributes of a file. This method is
634 called by stat(2) and related system calls.
635
636 ``listxattr``
637 called by the VFS to list all extended attributes for a given
638 file. This method is called by the listxattr(2) system call.
639
640 ``update_time``
641 called by the VFS to update a specific time or the i_version of
642 an inode. If this is not defined the VFS will update the inode
643 itself and call mark_inode_dirty_sync.
644
645 ``atomic_open``
646 called on the last component of an open. Using this optional
647 method the filesystem can look up, possibly create and open the
648 file in one atomic operation. If it wants to leave actual
649 opening to the caller (e.g. if the file turned out to be a
650 symlink, device, or just something filesystem won't do atomic
651 open for), it may signal this by returning finish_no_open(file,
652 dentry). This method is only called if the last component is
653 negative or needs lookup. Cached positive dentries are still
654 handled by f_op->open(). If the file was created, FMODE_CREATED
655 flag should be set in file->f_mode. In case of O_EXCL the
656 method must only succeed if the file didn't exist and hence
657 FMODE_CREATED shall always be set on success.
658
659 ``tmpfile``
660 called in the end of O_TMPFILE open(). Optional, equivalent to
661 atomically creating, opening and unlinking a file in given
662 directory. On success needs to return with the file already
663 open; this can be done by calling finish_open_simple() right at
664 the end.
665
666 ``fileattr_get``
667 called on ioctl(FS_IOC_GETFLAGS) and ioctl(FS_IOC_FSGETXATTR) to
668 retrieve miscellaneous file flags and attributes. Also called
669 before the relevant SET operation to check what is being changed
670 (in this case with i_rwsem locked exclusive). If unset, then
671 fall back to f_op->ioctl().
672
673 ``fileattr_set``
674 called on ioctl(FS_IOC_SETFLAGS) and ioctl(FS_IOC_FSSETXATTR) to
675 change miscellaneous file flags and attributes. Callers hold
676 i_rwsem exclusive. If unset, then fall back to f_op->ioctl().
677 ``get_offset_ctx``
678 called to get the offset context for a directory inode. A
679 filesystem must define this operation to use
680 simple_offset_dir_operations.
681
682 The Address Space Object
683 ========================
684
685 The address space object is used to group and manage pages in the page
686 cache. It can be used to keep track of the pages in a file (or anything
687 else) and also track the mapping of sections of the file into process
688 address spaces.
689
690 There are a number of distinct yet related services that an
691 address-space can provide. These include communicating memory pressure,
692 page lookup by address, and keeping track of pages tagged as Dirty or
693 Writeback.
694
695 The first can be used independently to the others. The VM can try to
696 release clean pages in order to reuse them. To do this it can call
697 ->release_folio on clean folios with the private
698 flag set. Clean pages without PagePrivate and with no external references
699 will be released without notice being given to the address_space.
700
701 To achieve this functionality, pages need to be placed on an LRU with
702 lru_cache_add and mark_page_active needs to be called whenever the page
703 is used.
704
705 Pages are normally kept in a radix tree index by ->index. This tree
706 maintains information about the PG_Dirty and PG_Writeback status of each
707 page, so that pages with either of these flags can be found quickly.
708
709 The Dirty tag is primarily used by mpage_writepages - the default
710 ->writepages method. It uses the tag to find dirty pages to
711 write back. If mpage_writepages is not used (i.e. the address
712 provides its own ->writepages) , the PAGECACHE_TAG_DIRTY tag is almost
713 unused. write_inode_now and sync_inode do use it (through
714 __sync_single_inode) to check if ->writepages has been successful in
715 writing out the whole address_space.
716
717 The Writeback tag is used by filemap*wait* and sync_page* functions, via
718 filemap_fdatawait_range, to wait for all writeback to complete.
719
720 An address_space handler may attach extra information to a page,
721 typically using the 'private' field in the 'struct page'. If such
722 information is attached, the PG_Private flag should be set. This will
723 cause various VM routines to make extra calls into the address_space
724 handler to deal with that data.
725
726 An address space acts as an intermediate between storage and
727 application. Data is read into the address space a whole page at a
728 time, and provided to the application either by copying of the page, or
729 by memory-mapping the page. Data is written into the address space by
730 the application, and then written-back to storage typically in whole
731 pages, however the address_space has finer control of write sizes.
732
733 The read process essentially only requires 'read_folio'. The write
734 process is more complicated and uses write_begin/write_end or
735 dirty_folio to write data into the address_space, and
736 writepages to writeback data to storage.
737
738 Removing pages from an address_space requires holding the inode's i_rwsem
739 exclusively, while adding pages to the address_space requires holding the
740 inode's i_mapping->invalidate_lock exclusively.
741
742 When data is written to a page, the PG_Dirty flag should be set. It
743 typically remains set until writepages asks for it to be written. This
744 should clear PG_Dirty and set PG_Writeback. It can be actually written
745 at any point after PG_Dirty is clear. Once it is known to be safe,
746 PG_Writeback is cleared.
747
748 Writeback makes use of a writeback_control structure to direct the
749 operations. This gives the writepages operation some
750 information about the nature of and reason for the writeback request,
751 and the constraints under which it is being done. It is also used to
752 return information back to the caller about the result of a
753 writepages request.
754
755
756 Handling errors during writeback
757 --------------------------------
758
759 Most applications that do buffered I/O will periodically call a file
760 synchronization call (fsync, fdatasync, msync or sync_file_range) to
761 ensure that data written has made it to the backing store. When there
762 is an error during writeback, they expect that error to be reported when
763 a file sync request is made. After an error has been reported on one
764 request, subsequent requests on the same file descriptor should return
765 0, unless further writeback errors have occurred since the previous file
766 synchronization.
767
768 Ideally, the kernel would report errors only on file descriptions on
769 which writes were done that subsequently failed to be written back. The
770 generic pagecache infrastructure does not track the file descriptions
771 that have dirtied each individual page however, so determining which
772 file descriptors should get back an error is not possible.
773
774 Instead, the generic writeback error tracking infrastructure in the
775 kernel settles for reporting errors to fsync on all file descriptions
776 that were open at the time that the error occurred. In a situation with
777 multiple writers, all of them will get back an error on a subsequent
778 fsync, even if all of the writes done through that particular file
779 descriptor succeeded (or even if there were no writes on that file
780 descriptor at all).
781
782 Filesystems that wish to use this infrastructure should call
783 mapping_set_error to record the error in the address_space when it
784 occurs. Then, after writing back data from the pagecache in their
785 file->fsync operation, they should call file_check_and_advance_wb_err to
786 ensure that the struct file's error cursor has advanced to the correct
787 point in the stream of errors emitted by the backing device(s).
788
789
790 struct address_space_operations
791 -------------------------------
792
793 This describes how the VFS can manipulate mapping of a file to page
794 cache in your filesystem. The following members are defined:
795
796 .. code-block:: c
797
798 struct address_space_operations {
799 int (*read_folio)(struct file *, struct folio *);
800 int (*writepages)(struct address_space *, struct writeback_control *);
801 bool (*dirty_folio)(struct address_space *, struct folio *);
802 void (*readahead)(struct readahead_control *);
803 int (*write_begin)(const struct kiocb *, struct address_space *mapping,
804 loff_t pos, unsigned len,
805 struct page **pagep, void **fsdata);
806 int (*write_end)(const struct kiocb *, struct address_space *mapping,
807 loff_t pos, unsigned len, unsigned copied,
808 struct folio *folio, void *fsdata);
809 sector_t (*bmap)(struct address_space *, sector_t);
810 void (*invalidate_folio) (struct folio *, size_t start, size_t len);
811 bool (*release_folio)(struct folio *, gfp_t);
812 void (*free_folio)(struct folio *);
813 ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
814 int (*migrate_folio)(struct mapping *, struct folio *dst,
815 struct folio *src, enum migrate_mode);
816 int (*launder_folio) (struct folio *);
817
818 bool (*is_partially_uptodate) (struct folio *, size_t from,
819 size_t count);
820 void (*is_dirty_writeback)(struct folio *, bool *, bool *);
821 int (*error_remove_folio)(struct mapping *mapping, struct folio *);
822 int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
823 int (*swap_deactivate)(struct file *);
824 int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
825 };
826
827 ``read_folio``
828 Called by the page cache to read a folio from the backing store.
829 The 'file' argument supplies authentication information to network
830 filesystems, and is generally not used by block based filesystems.
831 It may be NULL if the caller does not have an open file (eg if
832 the kernel is performing a read for itself rather than on behalf
833 of a userspace process with an open file).
834
835 If the mapping does not support large folios, the folio will
836 contain a single page. The folio will be locked when read_folio
837 is called. If the read completes successfully, the folio should
838 be marked uptodate. The filesystem should unlock the folio
839 once the read has completed, whether it was successful or not.
840 The filesystem does not need to modify the refcount on the folio;
841 the page cache holds a reference count and that will not be
842 released until the folio is unlocked.
843
844 Filesystems may implement ->read_folio() synchronously.
845 In normal operation, folios are read through the ->readahead()
846 method. Only if this fails, or if the caller needs to wait for
847 the read to complete will the page cache call ->read_folio().
848 Filesystems should not attempt to perform their own readahead
849 in the ->read_folio() operation.
850
851 If the filesystem cannot perform the read at this time, it can
852 unlock the folio, do whatever action it needs to ensure that the
853 read will succeed in the future and return AOP_TRUNCATED_PAGE.
854 In this case, the caller should look up the folio, lock it,
855 and call ->read_folio again.
856
857 Callers may invoke the ->read_folio() method directly, but using
858 read_mapping_folio() will take care of locking, waiting for the
859 read to complete and handle cases such as AOP_TRUNCATED_PAGE.
860
861 ``writepages``
862 called by the VM to write out pages associated with the
863 address_space object. If wbc->sync_mode is WB_SYNC_ALL, then
864 the writeback_control will specify a range of pages that must be
865 written out. If it is WB_SYNC_NONE, then a nr_to_write is
866 given and that many pages should be written if possible. If no
867 ->writepages is given, then mpage_writepages is used instead.
868 This will choose pages from the address space that are tagged as
869 DIRTY and will write them back.
870
871 ``dirty_folio``
872 called by the VM to mark a folio as dirty. This is particularly
873 needed if an address space attaches private data to a folio, and
874 that data needs to be updated when a folio is dirtied. This is
875 called, for example, when a memory mapped page gets modified.
876 If defined, it should set the folio dirty flag, and the
877 PAGECACHE_TAG_DIRTY search mark in i_pages.
878
879 ``readahead``
880 Called by the VM to read pages associated with the address_space
881 object. The pages are consecutive in the page cache and are
882 locked. The implementation should decrement the page refcount
883 after starting I/O on each page. Usually the page will be
884 unlocked by the I/O completion handler. The set of pages are
885 divided into some sync pages followed by some async pages,
886 rac->ra->async_size gives the number of async pages. The
887 filesystem should attempt to read all sync pages but may decide
888 to stop once it reaches the async pages. If it does decide to
889 stop attempting I/O, it can simply return. The caller will
890 remove the remaining pages from the address space, unlock them
891 and decrement the page refcount. Set PageUptodate if the I/O
892 completes successfully.
893
894 ``write_begin``
895 Called by the generic buffered write code to ask the filesystem
896 to prepare to write len bytes at the given offset in the file.
897 The address_space should check that the write will be able to
898 complete, by allocating space if necessary and doing any other
899 internal housekeeping. If the write will update parts of any
900 basic-blocks on storage, then those blocks should be pre-read
901 (if they haven't been read already) so that the updated blocks
902 can be written out properly.
903
904 The filesystem must return the locked pagecache folio for the
905 specified offset, in ``*foliop``, for the caller to write into.
906
907 It must be able to cope with short writes (where the length
908 passed to write_begin is greater than the number of bytes copied
909 into the folio).
910
911 A void * may be returned in fsdata, which then gets passed into
912 write_end.
913
914 Returns 0 on success; < 0 on failure (which is the error code),
915 in which case write_end is not called.
916
917 ``write_end``
918 After a successful write_begin, and data copy, write_end must be
919 called. len is the original len passed to write_begin, and
920 copied is the amount that was able to be copied.
921
922 The filesystem must take care of unlocking the folio,
923 decrementing its refcount, and updating i_size.
924
925 Returns < 0 on failure, otherwise the number of bytes (<=
926 'copied') that were able to be copied into pagecache.
927
928 ``bmap``
929 called by the VFS to map a logical block offset within object to
930 physical block number. This method is used by the FIBMAP ioctl
931 and for working with swap-files. To be able to swap to a file,
932 the file must have a stable mapping to a block device. The swap
933 system does not go through the filesystem but instead uses bmap
934 to find out where the blocks in the file are and uses those
935 addresses directly.
936
937 ``invalidate_folio``
938 If a folio has private data, then invalidate_folio will be
939 called when part or all of the folio is to be removed from the
940 address space. This generally corresponds to either a
941 truncation, punch hole or a complete invalidation of the address
942 space (in the latter case 'offset' will always be 0 and 'length'
943 will be folio_size()). Any private data associated with the folio
944 should be updated to reflect this truncation. If offset is 0
945 and length is folio_size(), then the private data should be
946 released, because the folio must be able to be completely
947 discarded. This may be done by calling the ->release_folio
948 function, but in this case the release MUST succeed.
949
950 ``release_folio``
951 release_folio is called on folios with private data to tell the
952 filesystem that the folio is about to be freed. ->release_folio
953 should remove any private data from the folio and clear the
954 private flag. If release_folio() fails, it should return false.
955 release_folio() is used in two distinct though related cases.
956 The first is when the VM wants to free a clean folio with no
957 active users. If ->release_folio succeeds, the folio will be
958 removed from the address_space and be freed.
959
960 The second case is when a request has been made to invalidate
961 some or all folios in an address_space. This can happen
962 through the fadvise(POSIX_FADV_DONTNEED) system call or by the
963 filesystem explicitly requesting it as nfs and 9p do (when they
964 believe the cache may be out of date with storage) by calling
965 invalidate_inode_pages2(). If the filesystem makes such a call,
966 and needs to be certain that all folios are invalidated, then
967 its release_folio will need to ensure this. Possibly it can
968 clear the uptodate flag if it cannot free private data yet.
969
970 ``free_folio``
971 free_folio is called once the folio is no longer visible in the
972 page cache in order to allow the cleanup of any private data.
973 Since it may be called by the memory reclaimer, it should not
974 assume that the original address_space mapping still exists, and
975 it should not block.
976
977 ``direct_IO``
978 called by the generic read/write routines to perform direct_IO -
979 that is IO requests which bypass the page cache and transfer
980 data directly between the storage and the application's address
981 space.
982
983 ``migrate_folio``
984 This is used to compact the physical memory usage. If the VM
985 wants to relocate a folio (maybe from a memory device that is
986 signalling imminent failure) it will pass a new folio and an old
987 folio to this function. migrate_folio should transfer any private
988 data across and update any references that it has to the folio.
989
990 ``launder_folio``
991 Called before freeing a folio - it writes back the dirty folio.
992 To prevent redirtying the folio, it is kept locked during the
993 whole operation.
994
995 ``is_partially_uptodate``
996 Called by the VM when reading a file through the pagecache when
997 the underlying blocksize is smaller than the size of the folio.
998 If the required block is up to date then the read can complete
999 without needing I/O to bring the whole page up to date.
1001 ``is_dirty_writeback``
1002 Called by the VM when attempting to reclaim a folio. The VM uses
1003 dirty and writeback information to determine if it needs to
1004 stall to allow flushers a chance to complete some IO.
1005 Ordinarily it can use folio_test_dirty and folio_test_writeback but
1006 some filesystems have more complex state (unstable folios in NFS
1007 prevent reclaim) or do not set those flags due to locking
1008 problems. This callback allows a filesystem to indicate to the
1009 VM if a folio should be treated as dirty or writeback for the
1010 purposes of stalling.
1012 ``error_remove_folio``
1013 normally set to generic_error_remove_folio if truncation is ok
1014 for this address space. Used for memory failure handling.
1015 Setting this implies you deal with pages going away under you,
1016 unless you have them locked or reference counts increased.
1018 ``swap_activate``
1020 Called to prepare the given file for swap. It should perform
1021 any validation and preparation necessary to ensure that writes
1022 can be performed with minimal memory allocation. It should call
1023 add_swap_extent(), or the helper iomap_swapfile_activate(), and
1024 return the number of extents added. If IO should be submitted
1025 through ->swap_rw(), it should set SWP_FS_OPS, otherwise IO will
1026 be submitted directly to the block device ``sis->bdev``.
1028 ``swap_deactivate``
1029 Called during swapoff on files where swap_activate was
1030 successful.
1032 ``swap_rw``
1033 Called to read or write swap pages when SWP_FS_OPS is set.
1035 The File Object
1036 ===============
1038 A file object represents a file opened by a process. This is also known
1039 as an "open file description" in POSIX parlance.
1042 struct file_operations
1043 ----------------------
1045 This describes how the VFS can manipulate an open file. As of kernel
1046 4.18, the following members are defined:
1048 .. code-block:: c
1050 struct file_operations {
1051 struct module *owner;
1052 fop_flags_t fop_flags;
1053 loff_t (*llseek) (struct file *, loff_t, int);
1054 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
1055 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
1056 ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
1057 ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
1058 int (*iopoll)(struct kiocb *kiocb, struct io_comp_batch *,
1059 unsigned int flags);
1060 int (*iterate_shared) (struct file *, struct dir_context *);
1061 __poll_t (*poll) (struct file *, struct poll_table_struct *);
1062 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
1063 long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
1064 int (*mmap) (struct file *, struct vm_area_struct *);
1065 int (*open) (struct inode *, struct file *);
1066 int (*flush) (struct file *, fl_owner_t id);
1067 int (*release) (struct inode *, struct file *);
1068 int (*fsync) (struct file *, loff_t, loff_t, int datasync);
1069 int (*fasync) (int, struct file *, int);
1070 int (*lock) (struct file *, int, struct file_lock *);
1071 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
1072 int (*check_flags)(int);
1073 int (*flock) (struct file *, int, struct file_lock *);
1074 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
1075 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
1076 void (*splice_eof)(struct file *file);
1077 int (*setlease)(struct file *, int, struct file_lease **, void **);
1078 long (*fallocate)(struct file *file, int mode, loff_t offset,
1079 loff_t len);
1080 void (*show_fdinfo)(struct seq_file *m, struct file *f);
1081 #ifndef CONFIG_MMU
1082 unsigned (*mmap_capabilities)(struct file *);
1083 #endif
1084 ssize_t (*copy_file_range)(struct file *, loff_t, struct file *,
1085 loff_t, size_t, unsigned int);
1086 loff_t (*remap_file_range)(struct file *file_in, loff_t pos_in,
1087 struct file *file_out, loff_t pos_out,
1088 loff_t len, unsigned int remap_flags);
1089 int (*fadvise)(struct file *, loff_t, loff_t, int);
1090 int (*uring_cmd)(struct io_uring_cmd *ioucmd, unsigned int issue_flags);
1091 int (*uring_cmd_iopoll)(struct io_uring_cmd *, struct io_comp_batch *,
1092 unsigned int poll_flags);
1093 int (*mmap_prepare)(struct vm_area_desc *);
1094 };
1096 Again, all methods are called without any locks being held, unless
1097 otherwise noted.
1099 ``llseek``
1100 called when the VFS needs to move the file position index
1102 ``read``
1103 called by read(2) and related system calls
1105 ``read_iter``
1106 possibly asynchronous read with iov_iter as destination
1108 ``write``
1109 called by write(2) and related system calls
1111 ``write_iter``
1112 possibly asynchronous write with iov_iter as source
1114 ``iopoll``
1115 called when aio wants to poll for completions on HIPRI iocbs
1117 ``iterate_shared``
1118 called when the VFS needs to read the directory contents
1120 ``poll``
1121 called by the VFS when a process wants to check if there is
1122 activity on this file and (optionally) go to sleep until there
1123 is activity. Called by the select(2) and poll(2) system calls
1125 ``unlocked_ioctl``
1126 called by the ioctl(2) system call.
1128 ``compat_ioctl``
1129 called by the ioctl(2) system call when 32 bit system calls are
1130 used on 64 bit kernels.
1132 ``mmap``
1133 called by the mmap(2) system call. Deprecated in favour of
1134 ``mmap_prepare``.
1136 ``open``
1137 called by the VFS when an inode should be opened. When the VFS
1138 opens a file, it creates a new "struct file". It then calls the
1139 open method for the newly allocated file structure. You might
1140 think that the open method really belongs in "struct
1141 inode_operations", and you may be right. I think it's done the
1142 way it is because it makes filesystems simpler to implement.
1143 The open() method is a good place to initialize the
1144 "private_data" member in the file structure if you want to point
1145 to a device structure
1147 ``flush``
1148 called by the close(2) system call to flush a file
1150 ``release``
1151 called when the last reference to an open file is closed
1153 ``fsync``
1154 called by the fsync(2) system call. Also see the section above
1155 entitled "Handling errors during writeback".
1157 ``fasync``
1158 called by the fcntl(2) system call when asynchronous
1159 (non-blocking) mode is enabled for a file
1161 ``lock``
1162 called by the fcntl(2) system call for F_GETLK, F_SETLK, and
1163 F_SETLKW commands
1165 ``get_unmapped_area``
1166 called by the mmap(2) system call
1168 ``check_flags``
1169 called by the fcntl(2) system call for F_SETFL command
1171 ``flock``
1172 called by the flock(2) system call
1174 ``splice_write``
1175 called by the VFS to splice data from a pipe to a file. This
1176 method is used by the splice(2) system call
1178 ``splice_read``
1179 called by the VFS to splice data from file to a pipe. This
1180 method is used by the splice(2) system call
1182 ``setlease``
1183 called by the VFS to set or release a file lock lease. setlease
1184 implementations should call generic_setlease to record or remove
1185 the lease in the inode after setting it.
1187 ``fallocate``
1188 called by the VFS to preallocate blocks or punch a hole.
1190 ``copy_file_range``
1191 called by the copy_file_range(2) system call.
1193 ``remap_file_range``
1194 called by the ioctl(2) system call for FICLONERANGE and FICLONE
1195 and FIDEDUPERANGE commands to remap file ranges. An
1196 implementation should remap len bytes at pos_in of the source
1197 file into the dest file at pos_out. Implementations must handle
1198 callers passing in len == 0; this means "remap to the end of the
1199 source file". The return value should the number of bytes
1200 remapped, or the usual negative error code if errors occurred
1201 before any bytes were remapped. The remap_flags parameter
1202 accepts REMAP_FILE_* flags. If REMAP_FILE_DEDUP is set then the
1203 implementation must only remap if the requested file ranges have
1204 identical contents. If REMAP_FILE_CAN_SHORTEN is set, the caller is
1205 ok with the implementation shortening the request length to
1206 satisfy alignment or EOF requirements (or any other reason).
1208 ``fadvise``
1209 possibly called by the fadvise64() system call.
1211 ``mmap_prepare``
1212 Called by the mmap(2) system call. Allows a VFS to set up a
1213 file-backed memory mapping, most notably establishing relevant
1214 private state and VMA callbacks.
1216 Note that the file operations are implemented by the specific
1217 filesystem in which the inode resides. When opening a device node
1218 (character or block special) most filesystems will call special
1219 support routines in the VFS which will locate the required device
1220 driver information. These support routines replace the filesystem file
1221 operations with those for the device driver, and then proceed to call
1222 the new open() method for the file. This is how opening a device file
1223 in the filesystem eventually ends up calling the device driver open()
1224 method.
1227 Directory Entry Cache (dcache)
1228 ==============================
1231 struct dentry_operations
1232 ------------------------
1234 This describes how a filesystem can overload the standard dentry
1235 operations. Dentries and the dcache are the domain of the VFS and the
1236 individual filesystem implementations. Device drivers have no business
1237 here. These methods may be set to NULL, as they are either optional or
1238 the VFS uses a default. As of kernel 2.6.22, the following members are
1239 defined:
1241 .. code-block:: c
1243 struct dentry_operations {
1244 int (*d_revalidate)(struct inode *, const struct qstr *,
1245 struct dentry *, unsigned int);
1246 int (*d_weak_revalidate)(struct dentry *, unsigned int);
1247 int (*d_hash)(const struct dentry *, struct qstr *);
1248 int (*d_compare)(const struct dentry *,
1249 unsigned int, const char *, const struct qstr *);
1250 int (*d_delete)(const struct dentry *);
1251 int (*d_init)(struct dentry *);
1252 void (*d_release)(struct dentry *);
1253 void (*d_iput)(struct dentry *, struct inode *);
1254 char *(*d_dname)(struct dentry *, char *, int);
1255 struct vfsmount *(*d_automount)(struct path *);
1256 int (*d_manage)(const struct path *, bool);
1257 struct dentry *(*d_real)(struct dentry *, enum d_real_type type);
1258 bool (*d_unalias_trylock)(const struct dentry *);
1259 void (*d_unalias_unlock)(const struct dentry *);
1260 };
1262 ``d_revalidate``
1263 called when the VFS needs to revalidate a dentry. This is
1264 called whenever a name look-up finds a dentry in the dcache.
1265 Most local filesystems leave this as NULL, because all their
1266 dentries in the dcache are valid. Network filesystems are
1267 different since things can change on the server without the
1268 client necessarily being aware of it.
1270 This function should return a positive value if the dentry is
1271 still valid, and zero or a negative error code if it isn't.
1273 d_revalidate may be called in rcu-walk mode (flags &
1274 LOOKUP_RCU). If in rcu-walk mode, the filesystem must
1275 revalidate the dentry without blocking or storing to the dentry,
1276 d_parent and d_inode should not be used without care (because
1277 they can change and, in d_inode case, even become NULL under
1278 us).
1280 If a situation is encountered that rcu-walk cannot handle,
1281 return
1282 -ECHILD and it will be called again in ref-walk mode.
1284 ``d_weak_revalidate``
1285 called when the VFS needs to revalidate a "jumped" dentry. This
1286 is called when a path-walk ends at dentry that was not acquired
1287 by doing a lookup in the parent directory. This includes "/",
1288 "." and "..", as well as procfs-style symlinks and mountpoint
1289 traversal.
1291 In this case, we are less concerned with whether the dentry is
1292 still fully correct, but rather that the inode is still valid.
1293 As with d_revalidate, most local filesystems will set this to
1294 NULL since their dcache entries are always valid.
1296 This function has the same return code semantics as
1297 d_revalidate.
1299 d_weak_revalidate is only called after leaving rcu-walk mode.
1301 ``d_hash``
1302 called when the VFS adds a dentry to the hash table. The first
1303 dentry passed to d_hash is the parent directory that the name is
1304 to be hashed into.
1306 Same locking and synchronisation rules as d_compare regarding
1307 what is safe to dereference etc.
1309 ``d_compare``
1310 called to compare a dentry name with a given name. The first
1311 dentry is the parent of the dentry to be compared, the second is
1312 the child dentry. len and name string are properties of the
1313 dentry to be compared. qstr is the name to compare it with.
1315 Must be constant and idempotent, and should not take locks if
1316 possible, and should not or store into the dentry. Should not
1317 dereference pointers outside the dentry without lots of care
1318 (eg. d_parent, d_inode, d_name should not be used).
1320 However, our vfsmount is pinned, and RCU held, so the dentries
1321 and inodes won't disappear, neither will our sb or filesystem
1322 module. ->d_sb may be used.
1324 It is a tricky calling convention because it needs to be called
1325 under "rcu-walk", ie. without any locks or references on things.
1327 ``d_delete``
1328 called when the last reference to a dentry is dropped and the
1329 dcache is deciding whether or not to cache it. Return 1 to
1330 delete immediately, or 0 to cache the dentry. Default is NULL
1331 which means to always cache a reachable dentry. d_delete must
1332 be constant and idempotent.
1334 ``d_init``
1335 called when a dentry is allocated
1337 ``d_release``
1338 called when a dentry is really deallocated
1340 ``d_iput``
1341 called when a dentry loses its inode (just prior to its being
1342 deallocated). The default when this is NULL is that the VFS
1343 calls iput(). If you define this method, you must call iput()
1344 yourself
1346 ``d_dname``
1347 called when the pathname of a dentry should be generated.
1348 Useful for some pseudo filesystems (sockfs, pipefs, ...) to
1349 delay pathname generation. (Instead of doing it when dentry is
1350 created, it's done only when the path is needed.). Real
1351 filesystems probably dont want to use it, because their dentries
1352 are present in global dcache hash, so their hash should be an
1353 invariant. As no lock is held, d_dname() should not try to
1354 modify the dentry itself, unless appropriate SMP safety is used.
1355 CAUTION : d_path() logic is quite tricky. The correct way to
1356 return for example "Hello" is to put it at the end of the
1357 buffer, and returns a pointer to the first char.
1358 dynamic_dname() helper function is provided to take care of
1359 this.
1361 Example :
1363 .. code-block:: c
1365 static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
1366 {
1367 return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
1368 dentry->d_inode->i_ino);
1369 }
1371 ``d_automount``
1372 called when an automount dentry is to be traversed (optional).
1373 This should create a new VFS mount record and return the record
1374 to the caller. The caller is supplied with a path parameter
1375 giving the automount directory to describe the automount target
1376 and the parent VFS mount record to provide inheritable mount
1377 parameters. NULL should be returned if someone else managed to
1378 make the automount first. If the vfsmount creation failed, then
1379 an error code should be returned. If -EISDIR is returned, then
1380 the directory will be treated as an ordinary directory and
1381 returned to pathwalk to continue walking.
1383 If a vfsmount is returned, the caller will attempt to mount it
1384 on the mountpoint and will remove the vfsmount from its
1385 expiration list in the case of failure.
1387 This function is only used if DCACHE_NEED_AUTOMOUNT is set on
1388 the dentry. This is set by __d_instantiate() if S_AUTOMOUNT is
1389 set on the inode being added.
1391 ``d_manage``
1392 called to allow the filesystem to manage the transition from a
1393 dentry (optional). This allows autofs, for example, to hold up
1394 clients waiting to explore behind a 'mountpoint' while letting
1395 the daemon go past and construct the subtree there. 0 should be
1396 returned to let the calling process continue. -EISDIR can be
1397 returned to tell pathwalk to use this directory as an ordinary
1398 directory and to ignore anything mounted on it and not to check
1399 the automount flag. Any other error code will abort pathwalk
1400 completely.
1402 If the 'rcu_walk' parameter is true, then the caller is doing a
1403 pathwalk in RCU-walk mode. Sleeping is not permitted in this
1404 mode, and the caller can be asked to leave it and call again by
1405 returning -ECHILD. -EISDIR may also be returned to tell
1406 pathwalk to ignore d_automount or any mounts.
1408 This function is only used if DCACHE_MANAGE_TRANSIT is set on
1409 the dentry being transited from.
1411 ``d_real``
1412 overlay/union type filesystems implement this method to return one
1413 of the underlying dentries of a regular file hidden by the overlay.
1415 The 'type' argument takes the values D_REAL_DATA or D_REAL_METADATA
1416 for returning the real underlying dentry that refers to the inode
1417 hosting the file's data or metadata respectively.
1419 For non-regular files, the 'dentry' argument is returned.
1421 ``d_unalias_trylock``
1422 if present, will be called by d_splice_alias() before moving a
1423 preexisting attached alias. Returning false prevents __d_move(),
1424 making d_splice_alias() fail with -ESTALE.
1426 Rationale: setting FS_RENAME_DOES_D_MOVE will prevent d_move()
1427 and d_exchange() calls from the outside of filesystem methods;
1428 however, it does not guarantee that attached dentries won't
1429 be renamed or moved by d_splice_alias() finding a preexisting
1430 alias for a directory inode. Normally we would not care;
1431 however, something that wants to stabilize the entire path to
1432 root over a blocking operation might need that. See 9p for one
1433 (and hopefully only) example.
1435 ``d_unalias_unlock``
1436 should be paired with ``d_unalias_trylock``; that one is called after
1437 __d_move() call in __d_unalias().
1440 Each dentry has a pointer to its parent dentry, as well as a hash list
1441 of child dentries. Child dentries are basically like files in a
1442 directory.
1445 Directory Entry Cache API
1446 --------------------------
1448 There are a number of functions defined which permit a filesystem to
1449 manipulate dentries:
1451 ``dget``
1452 open a new handle for an existing dentry (this just increments
1453 the usage count)
1455 ``dput``
1456 close a handle for a dentry (decrements the usage count). If
1457 the usage count drops to 0, and the dentry is still in its
1458 parent's hash, the "d_delete" method is called to check whether
1459 it should be cached. If it should not be cached, or if the
1460 dentry is not hashed, it is deleted. Otherwise cached dentries
1461 are put into an LRU list to be reclaimed on memory shortage.
1463 ``d_drop``
1464 this unhashes a dentry from its parents hash list. A subsequent
1465 call to dput() will deallocate the dentry if its usage count
1466 drops to 0
1468 ``d_delete``
1469 delete a dentry. If there are no other open references to the
1470 dentry then the dentry is turned into a negative dentry (the
1471 d_iput() method is called). If there are other references, then
1472 d_drop() is called instead
1474 ``d_add``
1475 add a dentry to its parents hash list and then calls
1476 d_instantiate()
1478 ``d_instantiate``
1479 add a dentry to the alias hash list for the inode and updates
1480 the "d_inode" member. The "i_count" member in the inode
1481 structure should be set/incremented. If the inode pointer is
1482 NULL, the dentry is called a "negative dentry". This function
1483 is commonly called when an inode is created for an existing
1484 negative dentry
1486 ``d_lookup``
1487 look up a dentry given its parent and path name component It
1488 looks up the child of that given name from the dcache hash
1489 table. If it is found, the reference count is incremented and
1490 the dentry is returned. The caller must use dput() to free the
1491 dentry when it finishes using it.
1494 Mount Options
1495 =============
1498 Parsing options
1499 ---------------
1501 On mount and remount the filesystem is passed a string containing a
1502 comma separated list of mount options. The options can have either of
1503 these forms:
1505 option
1506 option=value
1508 The <linux/parser.h> header defines an API that helps parse these
1509 options. There are plenty of examples on how to use it in existing
1510 filesystems.
1513 Showing options
1514 ---------------
1516 If a filesystem accepts mount options, it must define show_options() to
1517 show all the currently active options. The rules are:
1519 - options MUST be shown which are not default or their values differ
1520 from the default
1522 - options MAY be shown which are enabled by default or have their
1523 default value
1525 Options used only internally between a mount helper and the kernel (such
1526 as file descriptors), or which only have an effect during the mounting
1527 (such as ones controlling the creation of a journal) are exempt from the
1528 above rules.
1530 The underlying reason for the above rules is to make sure, that a mount
1531 can be accurately replicated (e.g. umounting and mounting again) based
1532 on the information found in /proc/mounts.
1535 Resources
1536 =========
1538 (Note some of these resources are not up-to-date with the latest kernel
1539 version.)
1541 Creating Linux virtual filesystems. 2002
1542 <https://lwn.net/Articles/13325/>
1544 The Linux Virtual File-system Layer by Neil Brown. 1999
1545 <http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html>
1547 A tour of the Linux VFS by Michael K. Johnson. 1996
1548 <https://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html>
1550 A small trail through the Linux kernel by Andries Brouwer. 2001
1551 <https://www.win.tue.nl/~aeb/linux/vfs/trail.html>

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

VFS 개요와 핵심 객체

1-81

Virtual File System(Virtual Filesystem Switch, VFS)은 userspace program에 파일 시스템 interface를 제공하는 kernel software layer다. 동시에 서로 다른 파일 시스템 구현이 공존하도록 kernel 내부 추상화를 제공한다. `open(2)`, `stat(2)`, `read(2)`, `write(2)`, `chmod(2)` 같은 VFS system call은 process context에서 호출되며, 잠금 규칙은 `Documentation/filesystems/locking.rst`에 설명되어 있다.

pathname을 받는 system call은 directory entry cache, 즉 dentry cache 또는 dcache를 탐색한다. dcache는 pathname을 특정 dentry로 빠르게 변환한다. dentry는 성능만을 위해 RAM에 존재하고 디스크에는 저장되지 않는다. 전체 filespace의 view를 의도하지만 모든 dentry를 동시에 RAM에 둘 수 없으므로, 빠진 경로 성분은 탐색 중 새 dentry를 만들고 inode를 lookup하여 채운다.

각 dentry는 보통 inode를 가리킨다. inode는 regular file, directory, FIFO 같은 파일 시스템 object다. block device 파일 시스템에서는 디스크에, pseudo filesystem에서는 memory에 존재한다. 디스크 inode는 필요할 때 memory로 복사되고 변경 내용은 다시 디스크에 기록된다. hard link처럼 여러 dentry가 하나의 inode를 가리킬 수 있다.

inode lookup은 parent directory inode의 `lookup()` method를 호출하며 실제 파일 시스템 구현이 이 method를 설치한다. dentry와 inode를 얻은 뒤 VFS는 `open(2)`이나 `stat(2)`를 수행한다. `stat(2)`은 inode data 일부를 userspace로 돌려주는 비교적 단순한 작업이다.

file을 열 때는 file descriptor의 kernel 측 구현인 `struct file`을 할당한다. 새 file object에는 dentry pointer와 inode에서 가져온 file operation method가 설정되고, 실제 파일 시스템의 `open()`이 호출된다. 그 뒤 process의 file descriptor table에 들어간다. read·write·close는 file descriptor로 해당 file object를 얻어 method를 호출한다. 열린 file은 dentry를 사용 중으로 유지하고, 그 결과 inode도 계속 사용 중이다.

VFS pathname에서 I/O까지
userspace system call과 pathnamedcache에서 dentry 탐색·생성parent inode의 lookup()inode에서 operation table 선택struct file 생성과 file descriptor 등록filesystem callback으로 read·write·stat 수행

userspace 호출이 공통 VFS 객체를 거쳐 파일 시스템 구현으로 전달되는 과정이다.

VFS 핵심 객체
객체역할수명·관계
dentrypathname component와 inode 연결RAM 전용 cache, 여러 dentry가 한 inode를 가리킬 수 있음
inode파일 시스템 object metadatadisk 또는 memory에 존재, 필요 시 memory로 적재
struct file열린 file descriptionfile descriptor가 참조하며 열린 동안 dentry·inode 유지
superblock마운트된 파일 시스템 instancemount tree의 root와 operation table 보유
address_spacepage cache와 file mapping 관리storage와 application 사이의 page 단위 중간 계층

공통 object가 나타내는 상태와 수명 관계다.

.. SPDX-License-Identifier: GPL-2.0

=========================================
Overview of the Linux Virtual File System
=========================================

Original author: Richard Gooch <[email protected]>

- Copyright (C) 1999 Richard Gooch
- Copyright (C) 2005 Pekka Enberg


Introduction
============

The Virtual File System (also known as the Virtual Filesystem Switch) is
the software layer in the kernel that provides the filesystem interface
to userspace programs.  It also provides an abstraction within the
kernel which allows different filesystem implementations to coexist.

VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so on
are called from a process context.  Filesystem locking is described in
the document Documentation/filesystems/locking.rst.


Directory Entry Cache (dcache)
------------------------------

The VFS implements the open(2), stat(2), chmod(2), and similar system
calls.  The pathname argument that is passed to them is used by the VFS
to search through the directory entry cache (also known as the dentry
cache or dcache).  This provides a very fast look-up mechanism to
translate a pathname (filename) into a specific dentry.  Dentries live
in RAM and are never saved to disc: they exist only for performance.

The dentry cache is meant to be a view into your entire filespace.  As
most computers cannot fit all dentries in the RAM at the same time, some
bits of the cache are missing.  In order to resolve your pathname into a
dentry, the VFS may have to resort to creating dentries along the way,
and then loading the inode.  This is done by looking up the inode.


The Inode Object
----------------

An individual dentry usually has a pointer to an inode.  Inodes are
filesystem objects such as regular files, directories, FIFOs and other
beasts.  They live either on the disc (for block device filesystems) or
in the memory (for pseudo filesystems).  Inodes that live on the disc
are copied into the memory when required and changes to the inode are
written back to disc.  A single inode can be pointed to by multiple
dentries (hard links, for example, do this).

To look up an inode requires that the VFS calls the lookup() method of
the parent directory inode.  This method is installed by the specific
filesystem implementation that the inode lives in.  Once the VFS has the
required dentry (and hence the inode), we can do all those boring things
like open(2) the file, or stat(2) it to peek at the inode data.  The
stat(2) operation is fairly simple: once the VFS has the dentry, it
peeks at the inode data and passes some of it back to userspace.


The File Object
---------------

Opening a file requires another operation: allocation of a file
structure (this is the kernel-side implementation of file descriptors).
The freshly allocated file structure is initialized with a pointer to
the dentry and a set of file operation member functions.  These are
taken from the inode data.  The open() file method is then called so the
specific filesystem implementation can do its work.  You can see that
this is another switch performed by the VFS.  The file structure is
placed into the file descriptor table for the process.

Reading, writing and closing files (and other assorted VFS operations)
is done by using the userspace file descriptor to grab the appropriate
file structure, and then calling the required file structure method to
do whatever is required.  For as long as the file is open, it keeps the
dentry in use, which in turn means that the VFS inode is still in use.

파일 시스템 등록과 마운트

82-214

파일 시스템 등록과 해제에는 `register_filesystem(struct file_system_type *)`과 `unregister_filesystem(struct file_system_type *)`을 사용한다. 전달하는 `struct file_system_type`이 파일 시스템 형식을 기술한다. 등록된 형식은 `/proc/filesystems`에서 볼 수 있다.

.. code-block:: c

        #include <linux/fs.h>

        extern int register_filesystem(struct file_system_type *);
        extern int unregister_filesystem(struct file_system_type *);

namespace의 directory에 파일 시스템을 mount하라는 요청이 오면 VFS는 해당 형식의 `mount()`를 호출한다. `->mount()`가 반환한 tree를 가리키는 새 `vfsmount`가 mountpoint에 연결되고, pathname resolution이 mountpoint에 도달하면 그 `vfsmount`의 root로 넘어간다.

        struct file_system_type {
                const char *name;
                int fs_flags;
                int (*init_fs_context)(struct fs_context *);
                const struct fs_parameter_spec *parameters;
                struct dentry *(*mount) (struct file_system_type *, int,
                        const char *, void *);
                void (*kill_sb) (struct super_block *);
                struct module *owner;
                struct file_system_type * next;
                struct hlist_head fs_supers;

                struct lock_class_key s_lock_key;
                struct lock_class_key s_umount_key;
                struct lock_class_key s_vfs_rename_key;
                struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];

                struct lock_class_key i_lock_key;
                struct lock_class_key i_mutex_key;
                struct lock_class_key invalidate_lock_key;
                struct lock_class_key i_mutex_dir_key;
        };
struct file_system_type 주요 member
member의미초기화·주의
nameext2·iso9660·msdos 같은 filesystem type 이름고유한 문자열
fs_flagsFS_REQUIRES_DEV·FS_NO_DCACHE 등 flag형식 특성 표시
init_fs_contextfs_context의 ops·fs_private 초기화filesystem-specific data 설정
parametersfs_parameter_spec descriptor 배열mount_api.rst 참조
mount새 instance를 mount할 때 호출root dentry 또는 ERR_PTR(error) 반환
kill_sbinstance 종료 시 호출superblock 해제 경로
ownerVFS 내부 module owner대개 THIS_MODULE
nextVFS 내부 연결NULL로 초기화
fs_supersfilesystem instance(superblock)의 hlistVFS 내부 사용
lock class keyssuperblock·inode lockdep classlockdep 전용

등록·parameter 처리·mount와 종료에 필요한 필드다.

`mount()` 인자는 파일 시스템 형식, mount flag, device name, 임의 mount option data다. `data`는 보통 ASCII 문자열이며 해석은 파일 시스템 형식에 달려 있다. method는 caller가 요청한 tree의 root dentry를 반환해야 하고, 해당 superblock의 active reference를 잡고 lock한 상태여야 한다. 실패하면 `ERR_PTR(error)`를 반환한다.

block filesystem에서는 `dev_name`을 block device 이름으로 해석해 장치를 열고, 적합한 image가 있으면 `struct super_block`을 만들고 초기화한 뒤 root dentry를 반환한다. `->mount()`는 꼭 새 파일 시스템을 만들 필요 없이 기존 파일 시스템의 subtree를 반환할 수도 있다. caller 관점의 핵심 결과는 연결할 tree 또는 subtree root dentry reference다.

mount 구현이 채우는 superblock의 중요한 `s_op`은 다음 구현 계층을 설명하는 `struct super_operations` pointer다. 새 mount API의 자세한 내용은 `Documentation/filesystems/mount_api.rst`에 있다.

파일 시스템 mount dispatch
register_filesystem()으로 file_system_type 등록mount request에서 type과 dev_name·data 선택VFS가 해당 ->mount() 호출root dentry·locked active superblock 획득새 vfsmount를 mountpoint에 연결pathwalk가 mount root로 전환

등록된 형식에서 namespace의 새 mount까지 이어지는 경로다.

Registering and Mounting a Filesystem
=====================================

To register and unregister a filesystem, use the following API
functions:

.. code-block:: c

        #include <linux/fs.h>

        extern int register_filesystem(struct file_system_type *);
        extern int unregister_filesystem(struct file_system_type *);

The passed struct file_system_type describes your filesystem.  When a
request is made to mount a filesystem onto a directory in your
namespace, the VFS will call the appropriate mount() method for the
specific filesystem.  New vfsmount referring to the tree returned by
->mount() will be attached to the mountpoint, so that when pathname
resolution reaches the mountpoint it will jump into the root of that
vfsmount.

You can see all filesystems that are registered to the kernel in the
file /proc/filesystems.


struct file_system_type
-----------------------

This describes the filesystem.  The following
members are defined:

.. code-block:: c

        struct file_system_type {
                const char *name;
                int fs_flags;
                int (*init_fs_context)(struct fs_context *);
                const struct fs_parameter_spec *parameters;
                struct dentry *(*mount) (struct file_system_type *, int,
                        const char *, void *);
                void (*kill_sb) (struct super_block *);
                struct module *owner;
                struct file_system_type * next;
                struct hlist_head fs_supers;

                struct lock_class_key s_lock_key;
                struct lock_class_key s_umount_key;
                struct lock_class_key s_vfs_rename_key;
                struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];

                struct lock_class_key i_lock_key;
                struct lock_class_key i_mutex_key;
                struct lock_class_key invalidate_lock_key;
                struct lock_class_key i_mutex_dir_key;
        };

``name``
        the name of the filesystem type, such as "ext2", "iso9660",
        "msdos" and so on

``fs_flags``
        various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)

``init_fs_context``
        Initializes 'struct fs_context' ->ops and ->fs_private fields with
        filesystem-specific data.

``parameters``
        Pointer to the array of filesystem parameters descriptors
        'struct fs_parameter_spec'.
        More info in Documentation/filesystems/mount_api.rst.

``mount``
        the method to call when a new instance of this filesystem should
        be mounted

``kill_sb``
        the method to call when an instance of this filesystem should be
        shut down


``owner``
        for internal VFS use: you should initialize this to THIS_MODULE
        in most cases.

``next``
        for internal VFS use: you should initialize this to NULL

``fs_supers``
        for internal VFS use: hlist of filesystem instances (superblocks)

  s_lock_key, s_umount_key, s_vfs_rename_key, s_writers_key,
  i_lock_key, i_mutex_key, invalidate_lock_key, i_mutex_dir_key: lockdep-specific

The mount() method has the following arguments:

``struct file_system_type *fs_type``
        describes the filesystem, partly initialized by the specific
        filesystem code

``int flags``
        mount flags

``const char *dev_name``
        the device name we are mounting.

``void *data``
        arbitrary mount options, usually comes as an ASCII string (see
        "Mount Options" section)

The mount() method must return the root dentry of the tree requested by
caller.  An active reference to its superblock must be grabbed and the
superblock must be locked.  On failure it should return ERR_PTR(error).

The arguments match those of mount(2) and their interpretation depends
on filesystem type.  E.g. for block filesystems, dev_name is interpreted
as block device name, that device is opened and if it contains a
suitable filesystem image the method creates and initializes struct
super_block accordingly, returning its root dentry to caller.

->mount() may choose to return a subtree of existing filesystem - it
doesn't have to create a new one.  The main result from the caller's
point of view is a reference to dentry at the root of (sub)tree to be
attached; creation of new superblock is a common side effect.

The most interesting member of the superblock structure that the mount()
method fills in is the "s_op" field.  This is a pointer to a "struct
super_operations" which describes the next level of the filesystem
implementation.

For more information on mounting (and the new mount API), see
Documentation/filesystems/mount_api.rst.

Superblock inode 수명과 동기화

215-330

superblock object는 마운트된 파일 시스템을 나타낸다. `struct super_operations`는 VFS가 이 superblock과 소속 inode를 어떻게 조작할지 정의한다. 별도 언급이 없으면 모든 method는 lock 없이 process context에서 호출되므로 대부분 안전하게 block할 수 있다.

        struct super_operations {
                struct inode *(*alloc_inode)(struct super_block *sb);
                void (*destroy_inode)(struct inode *);
                void (*free_inode)(struct inode *);

                void (*dirty_inode) (struct inode *, int flags);
                int (*write_inode) (struct inode *, struct writeback_control *wbc);
                int (*drop_inode) (struct inode *);
                void (*evict_inode) (struct inode *);
                void (*put_super) (struct super_block *);
                int (*sync_fs)(struct super_block *sb, int wait);
                int (*freeze_super) (struct super_block *sb,
                                        enum freeze_holder who);
                int (*freeze_fs) (struct super_block *);
                int (*thaw_super) (struct super_block *sb,
                                        enum freeze_wholder who);
                int (*unfreeze_fs) (struct super_block *);
                int (*statfs) (struct dentry *, struct kstatfs *);
                int (*remount_fs) (struct super_block *, int *, char *);
                void (*umount_begin) (struct super_block *);

                int (*show_options)(struct seq_file *, struct dentry *);
                int (*show_devname)(struct seq_file *, struct dentry *);
                int (*show_path)(struct seq_file *, struct dentry *);
                int (*show_stats)(struct seq_file *, struct dentry *);

                ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
                ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
                struct dquot **(*get_dquots)(struct inode *);

                long (*nr_cached_objects)(struct super_block *,
                                        struct shrink_control *);
                long (*free_cached_objects)(struct super_block *,
                                        struct shrink_control *);
        };
super_operations inode·동기화 callback
callback호출 시점요구 사항
alloc_inodealloc_inode()가 struct inode memory를 할당할 때미정의 시 단순 inode 할당, 보통 embedding한 큰 구조 할당
destroy_inodeinode resource 해제alloc_inode가 한 작업을 되돌림
free_inodeRCU callback에서 memory 해제destroy_inode의 call_rcu 사용 시 적합
dirty_inodeinode 자체가 dirty로 표시될 때data dirty와 다름, I_DIRTY_DATASYNC·I_DIRTY_TIME flag 확인
write_inodeVFS가 inode를 disk에 기록할 때writeback_control의 sync 여부 해석
drop_inodeinode 마지막 access가 사라질 때inode->i_lock 보유, NULL 또는 inode_just_drop 사용
evict_inodeVFS가 inode를 축출할 때truncate_inode_pages_final()로 pagecache·metadata buffer 제거
put_superunmount에서 superblock 해제superblock lock 보유
sync_fssuperblock의 dirty data 전체 기록wait 인자로 완료 대기 여부 결정, optional

inode 할당부터 writeback과 unmount까지의 핵심 callback이다.

`drop_inode`를 NULL로 두면 일반 UNIX semantics를 따른다. inode cache를 원하지 않으면 `inode_just_drop`을 사용하여 `i_nlink`와 무관하게 삭제 경로를 타게 한다. 이는 과거 `force_delete` 관행과 동등한 동작이지만 그 방식의 race는 없다.

`evict_inode` caller는 pagecache나 inode-associated metadata buffer를 제거하지 않으므로 callback이 직접 `truncate_inode_pages_final()`을 호출해야 한다. 반면 caller는 callback 실행 중과 이후 해당 inode의 asynchronous writeback이 돌지 않도록 보장한다.

Superblock 아래 inode 수명
alloc_inode에서 filesystem-specific inode 구조 할당dirty_inode·write_inode로 metadata 변경 지속마지막 reference에서 drop_inode 결정evict_inode에서 pagecache와 private metadata 정리destroy_inode에서 resource 해제free_inode 또는 RCU grace period 뒤 memory 반환

파일 시스템 구현이 확장 inode를 관리하는 일반 순서다.

The Superblock Object
=====================

A superblock object represents a mounted filesystem.


struct super_operations
-----------------------

This describes how the VFS can manipulate the superblock of your
filesystem.  The following members are defined:

.. code-block:: c

        struct super_operations {
                struct inode *(*alloc_inode)(struct super_block *sb);
                void (*destroy_inode)(struct inode *);
                void (*free_inode)(struct inode *);

                void (*dirty_inode) (struct inode *, int flags);
                int (*write_inode) (struct inode *, struct writeback_control *wbc);
                int (*drop_inode) (struct inode *);
                void (*evict_inode) (struct inode *);
                void (*put_super) (struct super_block *);
                int (*sync_fs)(struct super_block *sb, int wait);
                int (*freeze_super) (struct super_block *sb,
                                        enum freeze_holder who);
                int (*freeze_fs) (struct super_block *);
                int (*thaw_super) (struct super_block *sb,
                                        enum freeze_wholder who);
                int (*unfreeze_fs) (struct super_block *);
                int (*statfs) (struct dentry *, struct kstatfs *);
                int (*remount_fs) (struct super_block *, int *, char *);
                void (*umount_begin) (struct super_block *);

                int (*show_options)(struct seq_file *, struct dentry *);
                int (*show_devname)(struct seq_file *, struct dentry *);
                int (*show_path)(struct seq_file *, struct dentry *);
                int (*show_stats)(struct seq_file *, struct dentry *);

                ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
                ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
                struct dquot **(*get_dquots)(struct inode *);

                long (*nr_cached_objects)(struct super_block *,
                                        struct shrink_control *);
                long (*free_cached_objects)(struct super_block *,
                                        struct shrink_control *);
        };

All methods are called without any locks being held, unless otherwise
noted.  This means that most methods can block safely.  All methods are
only called from a process context (i.e. not from an interrupt handler
or bottom half).

``alloc_inode``
        this method is called by alloc_inode() to allocate memory for
        struct inode and initialize it.  If this function is not
        defined, a simple 'struct inode' is allocated.  Normally
        alloc_inode will be used to allocate a larger structure which
        contains a 'struct inode' embedded within it.

``destroy_inode``
        this method is called by destroy_inode() to release resources
        allocated for struct inode.  It is only required if
        ->alloc_inode was defined and simply undoes anything done by
        ->alloc_inode.

``free_inode``
        this method is called from RCU callback. If you use call_rcu()
        in ->destroy_inode to free 'struct inode' memory, then it's
        better to release memory in this method.

``dirty_inode``
        this method is called by the VFS when an inode is marked dirty.
        This is specifically for the inode itself being marked dirty,
        not its data.  If the update needs to be persisted by fdatasync(),
        then I_DIRTY_DATASYNC will be set in the flags argument.
        I_DIRTY_TIME will be set in the flags in case lazytime is enabled
        and struct inode has times updated since the last ->dirty_inode
        call.

``write_inode``
        this method is called when the VFS needs to write an inode to
        disc.  The second parameter indicates whether the write should
        be synchronous or not, not all filesystems check this flag.

``drop_inode``
        called when the last access to the inode is dropped, with the
        inode->i_lock spinlock held.

        This method should be either NULL (normal UNIX filesystem
        semantics) or "inode_just_drop" (for filesystems that do
        not want to cache inodes - causing "delete_inode" to always be
        called regardless of the value of i_nlink)

        The "inode_just_drop()" behavior is equivalent to the old
        practice of using "force_delete" in the put_inode() case, but
        does not have the races that the "force_delete()" approach had.

``evict_inode``
        called when the VFS wants to evict an inode. Caller does
        *not* evict the pagecache or inode-associated metadata buffers;
        the method has to use truncate_inode_pages_final() to get rid
        of those. Caller makes sure async writeback cannot be running for
        the inode while (or after) ->evict_inode() is called. Optional.

``put_super``
        called when the VFS wishes to free the superblock
        (i.e. unmount).  This is called with the superblock lock held

``sync_fs``
        called when VFS is writing out all dirty data associated with a
        superblock.  The second parameter indicates whether the method
        should wait until the write out has been completed.  Optional.

Freeze·통계·표시·quota·cache 회수

331-416

`freeze_super`가 있으면 `freeze_fs` 대신 호출되며 `down_write(&sb->s_umount)` 없이 진입한다. 구현이 `freeze_fs`도 원하면 callback 안에서 명시적으로 호출해야 한다. `freeze_fs`는 VFS가 파일 시스템을 lock하고 일관된 상태로 강제할 때 호출되며 LVM과 `ioctl(FIFREEZE)`가 사용한다. `thaw_super`와 `unfreeze_fs`는 각각 freeze_super와 freeze_fs 뒤 파일 시스템을 다시 writable로 만든다.

super_operations 관리 callback
callback역할비고
freeze_super / freeze_fs파일 시스템을 일관된 frozen 상태로 전환모두 optional, lock 진입 방식이 다름
thaw_super / unfreeze_fsfreeze 뒤 writable 상태 복구대응 freeze callback별 사용
statfs파일 시스템 통계 반환VFS 요청
remount_fs파일 시스템 remountkernel lock 보유
umount_beginunmount 시작 처리VFS가 호출
show_options/proc/<pid>/mounts·mountinfo 옵션 출력Mount Options 규칙 준수
show_devnamemounts·mountinfo·mountstats의 device name 출력없으면 mnt_devname 사용
show_pathmountinfo에 filesystem root 기준 mount root path 출력optional
show_statsmountstats에 filesystem-specific 통계 출력optional
quota_read / quota_writequota file 읽기·쓰기VFS quota I/O
get_dquotsinode의 struct dquot 배열 획득optional
nr_cached_objects해제 가능한 cached object 수 반환optional
free_cached_objects지정 수의 cached object scan·해제 시도nr_cached_objects와 함께 구현

freeze, remount, proc 표시, quota와 shrinker 역할을 정리한다.

`free_cached_objects`의 void 반환 때문에 파일 시스템이 만난 error를 caller가 처리할 수는 없다. VM이 `GFP_NOFS` 조건으로 reclaim할 때는 호출되지 않으므로 구현이 그 상황을 별도로 처리할 필요가 없다. scan loop 안에는 conditional reschedule call을 넣어야 VFS가 큰 batch로 인한 holdoff를 걱정하지 않고 적절한 scan batch size를 정할 수 있다.

inode를 설정하는 주체는 `i_op` field도 채워야 한다. `i_op`은 개별 inode에 수행할 method를 설명하는 `struct inode_operations` pointer다.

Superblock cache shrink
nr_cached_objects로 해제 가능 수 확인VFS가 scan batch size 결정free_cached_objects에 목표 수 전달구현은 scan loop에서 conditional rescheduleGFP_NOFS reclaim에서는 callback을 호출하지 않음

VFS shrinker가 파일 시스템 cache를 회수하는 계약이다.

``freeze_super``
        Called instead of ->freeze_fs callback if provided.
        Main difference is that ->freeze_super is called without taking
        down_write(&sb->s_umount). If filesystem implements it and wants
        ->freeze_fs to be called too, then it has to call ->freeze_fs
        explicitly from this callback. Optional.

``freeze_fs``
        called when VFS is locking a filesystem and forcing it into a
        consistent state.  This method is currently used by the Logical
        Volume Manager (LVM) and ioctl(FIFREEZE). Optional.

``thaw_super``
        called when VFS is unlocking a filesystem and making it writable
        again after ->freeze_super. Optional.

``unfreeze_fs``
        called when VFS is unlocking a filesystem and making it writable
        again after ->freeze_fs. Optional.

``statfs``
        called when the VFS needs to get filesystem statistics.

``remount_fs``
        called when the filesystem is remounted.  This is called with
        the kernel lock held

``umount_begin``
        called when the VFS is unmounting a filesystem.

``show_options``
        called by the VFS to show mount options for /proc/<pid>/mounts
        and /proc/<pid>/mountinfo.
        (see "Mount Options" section)

``show_devname``
        Optional. Called by the VFS to show device name for
        /proc/<pid>/{mounts,mountinfo,mountstats}. If not provided then
        '(struct mount).mnt_devname' will be used.

``show_path``
        Optional. Called by the VFS (for /proc/<pid>/mountinfo) to show
        the mount root dentry path relative to the filesystem root.

``show_stats``
        Optional. Called by the VFS (for /proc/<pid>/mountstats) to show
        filesystem-specific mount statistics.

``quota_read``
        called by the VFS to read from filesystem quota file.

``quota_write``
        called by the VFS to write to filesystem quota file.

``get_dquots``
        called by quota to get 'struct dquot' array for a particular inode.
        Optional.

``nr_cached_objects``
        called by the sb cache shrinking function for the filesystem to
        return the number of freeable cached objects it contains.
        Optional.

``free_cache_objects``
        called by the sb cache shrinking function for the filesystem to
        scan the number of objects indicated to try to free them.
        Optional, but any filesystem implementing this method needs to
        also implement ->nr_cached_objects for it to be called
        correctly.

        We can't do anything with any errors that the filesystem might
        encountered, hence the void return type.  This will never be
        called if the VM is trying to reclaim under GFP_NOFS conditions,
        hence this method does not need to handle that situation itself.

        Implementations must include conditional reschedule calls inside
        any scanning loop that is done.  This allows the VFS to
        determine appropriate scan batch sizes without having to worry
        about whether implementations will cause holdoff problems due to
        large scan batch sizes.

Whoever sets up the inode is responsible for filling in the "i_op"
field.  This is a pointer to a "struct inode_operations" which describes
the methods that can be performed on individual inodes.

Extended attribute handler

417-454

extended attribute(xattr)를 지원하는 파일 시스템은 superblock의 `s_xattr`이 NULL로 끝나는 xattr handler 배열을 가리키게 한다. xattr은 `name:value` 쌍이다.

struct xattr_handler member
member동작제약
namesystem.posix_acl_access 같은 정확한 attribute name과 match사용할 때 prefix는 NULL
prefixuser. 같은 name prefix 전체와 match사용할 때 name은 NULL
list특정 dentry에서 handler의 attribute를 나열할지 결정generic_listxattr 등에서 사용
get특정 xattr value 획득getxattr(2)에서 호출
setxattr value 설정setxattr(2), value NULL이면 removexattr(2)

정확한 이름 또는 prefix를 선택하고 list·get·set 동작을 제공한다.

어떤 handler도 지정한 attribute name과 match하지 않거나 파일 시스템이 xattr을 지원하지 않으면 여러 `*xattr(2)` system call은 `-EOPNOTSUPP`를 반환한다.

struct xattr_handler
---------------------

On filesystems that support extended attributes (xattrs), the s_xattr
superblock field points to a NULL-terminated array of xattr handlers.
Extended attributes are name:value pairs.

``name``
        Indicates that the handler matches attributes with the specified
        name (such as "system.posix_acl_access"); the prefix field must
        be NULL.

``prefix``
        Indicates that the handler matches all attributes with the
        specified name prefix (such as "user."); the name field must be
        NULL.

``list``
        Determine if attributes matching this xattr handler should be
        listed for a particular dentry.  Used by some listxattr
        implementations like generic_listxattr.

``get``
        Called by the VFS to get the value of a particular extended
        attribute.  This method is called by the getxattr(2) system
        call.

``set``
        Called by the VFS to set the value of a particular extended
        attribute.  When the new value is NULL, called to remove a
        particular extended attribute.  This method is called by the
        setxattr(2) and removexattr(2) system calls.

When none of the xattr handlers of a filesystem match the specified
attribute name or when a filesystem doesn't support extended attributes,
the various ``*xattr(2)`` system calls return -EOPNOTSUPP.

Inode 생성·lookup·directory 연결

455-561

inode object는 파일 시스템 내부 object를 나타낸다. `struct inode_operations`는 VFS가 inode를 조작하는 방법을 정의한다. 별도 언급이 없으면 method는 lock 없이 호출된다.

        struct inode_operations {
                int (*create) (struct mnt_idmap *, struct inode *,struct dentry *, umode_t, bool);
                struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
                int (*link) (struct dentry *,struct inode *,struct dentry *);
                int (*unlink) (struct inode *,struct dentry *);
                int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
                struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
                int (*rmdir) (struct inode *,struct dentry *);
                int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
                int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
                               struct inode *, struct dentry *, unsigned int);
                int (*readlink) (struct dentry *, char __user *,int);
                const char *(*get_link) (struct dentry *, struct inode *,
                                         struct delayed_call *);
                int (*permission) (struct mnt_idmap *, struct inode *, int);
                struct posix_acl * (*get_inode_acl)(struct inode *, int, bool);
                int (*setattr) (struct mnt_idmap *, struct dentry *, struct iattr *);
                int (*getattr) (struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int);
                ssize_t (*listxattr) (struct dentry *, char *, size_t);
                void (*update_time)(struct inode *, struct timespec *, int);
                int (*atomic_open)(struct inode *, struct dentry *, struct file *,
                                   unsigned open_flag, umode_t create_mode);
                int (*tmpfile) (struct mnt_idmap *, struct inode *, struct file *, umode_t);
                struct posix_acl * (*get_acl)(struct mnt_idmap *, struct dentry *, int);
                int (*set_acl)(struct mnt_idmap *, struct dentry *, struct posix_acl *, int);
                int (*fileattr_set)(struct mnt_idmap *idmap,
                                    struct dentry *dentry, struct file_kattr *fa);
                int (*fileattr_get)(struct dentry *dentry, struct file_kattr *fa);
                struct offset_ctx *(*get_offset_ctx)(struct inode *inode);
        };
inode_operations 생성·이름 callback
callbacksystem call·역할핵심 계약
createopen(2)·creat(2)의 regular file 생성negative dentry를 받고 새 inode로 d_instantiate()
lookupparent directory에서 name의 inode 탐색d_add() 필수, 없음은 NULL inode의 negative dentry
linklink(2) hard link필요 시 d_instantiate()
unlinkunlink(2) inode 삭제삭제 지원 시 구현
symlinksymlink(2) symbolic link 생성필요 시 d_instantiate()
mkdirmkdir(2) subdirectory 생성보통 d_instantiate_new() 사용
rmdirrmdir(2) subdirectory 삭제directory 삭제 지원 시 구현
mknodchar·block device, FIFO, socket inode 생성mknod(2)에서 호출

regular file, link와 directory entry를 만들고 찾는 method다.

`lookup`은 찾을 이름을 dentry에서 받고, 찾은 inode를 `d_add()`로 dentry에 넣으며 inode `i_count`가 증가해야 한다. 이름이 없으면 NULL inode를 넣어 negative dentry로 만든다. 실제 error가 아닌데 error code를 반환하면 `create(2)`, `mknod(2)`, `mkdir(2)` 같은 생성 call이 실패한다. dentry method를 override하려면 dentry의 `d_dop`에 `struct dentry_operations`를 설정한다. directory inode semaphore를 보유한 상태로 호출된다.

directory는 VFS에서 언제나 dentry 하나만 가져야 한다. `mkdir`에서 `d_instantiate_new()`를 쓰지 않고 `fh_to_dentry()` export가 있거나 network filesystem처럼 다른 path로 storage에 접근할 수 있으면 race를 주의해야 한다. 다른 mount가 먼저 새 directory를 보고 `name_to_handle_at()`·`open_by_handle_at()`으로 IS_ROOT dentry에 붙일 수 있다.

그 가능성이 있으면 새 inode를 `d_drop()`하고 `d_splice_alias()`로 연결하며, 반환된 dentry가 있으면 `->mkdir()`에서 돌려줘야 한다. 이미 dentry에 붙을 수 있는 I_NEW가 아닌 inode에는 `d_instantiate()`를 사용하면 안 된다.

mkdir alias race 처리
새 directory inode 생성다른 mount·filehandle 경로 노출 가능성 확인가능하면 새 dentry를 d_drop()d_splice_alias()로 기존 alias와 조정반환된 dentry를 ->mkdir() caller에 반환

다른 path에서 directory inode가 먼저 보일 수 있는 파일 시스템의 안전한 연결 순서다.

The Inode Object
================

An inode object represents an object within the filesystem.


struct inode_operations
-----------------------

This describes how the VFS can manipulate an inode in your filesystem.
As of kernel 2.6.22, the following members are defined:

.. code-block:: c

        struct inode_operations {
                int (*create) (struct mnt_idmap *, struct inode *,struct dentry *, umode_t, bool);
                struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
                int (*link) (struct dentry *,struct inode *,struct dentry *);
                int (*unlink) (struct inode *,struct dentry *);
                int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
                struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
                int (*rmdir) (struct inode *,struct dentry *);
                int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
                int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
                               struct inode *, struct dentry *, unsigned int);
                int (*readlink) (struct dentry *, char __user *,int);
                const char *(*get_link) (struct dentry *, struct inode *,
                                         struct delayed_call *);
                int (*permission) (struct mnt_idmap *, struct inode *, int);
                struct posix_acl * (*get_inode_acl)(struct inode *, int, bool);
                int (*setattr) (struct mnt_idmap *, struct dentry *, struct iattr *);
                int (*getattr) (struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int);
                ssize_t (*listxattr) (struct dentry *, char *, size_t);
                void (*update_time)(struct inode *, struct timespec *, int);
                int (*atomic_open)(struct inode *, struct dentry *, struct file *,
                                   unsigned open_flag, umode_t create_mode);
                int (*tmpfile) (struct mnt_idmap *, struct inode *, struct file *, umode_t);
                struct posix_acl * (*get_acl)(struct mnt_idmap *, struct dentry *, int);
                int (*set_acl)(struct mnt_idmap *, struct dentry *, struct posix_acl *, int);
                int (*fileattr_set)(struct mnt_idmap *idmap,
                                    struct dentry *dentry, struct file_kattr *fa);
                int (*fileattr_get)(struct dentry *dentry, struct file_kattr *fa);
                struct offset_ctx *(*get_offset_ctx)(struct inode *inode);
        };

Again, all methods are called without any locks being held, unless
otherwise noted.

``create``
        called by the open(2) and creat(2) system calls.  Only required
        if you want to support regular files.  The dentry you get should
        not have an inode (i.e. it should be a negative dentry).  Here
        you will probably call d_instantiate() with the dentry and the
        newly created inode

``lookup``
        called when the VFS needs to look up an inode in a parent
        directory.  The name to look for is found in the dentry.  This
        method must call d_add() to insert the found inode into the
        dentry.  The "i_count" field in the inode structure should be
        incremented.  If the named inode does not exist a NULL inode
        should be inserted into the dentry (this is called a negative
        dentry).  Returning an error code from this routine must only be
        done on a real error, otherwise creating inodes with system
        calls like create(2), mknod(2), mkdir(2) and so on will fail.
        If you wish to overload the dentry methods then you should
        initialise the "d_dop" field in the dentry; this is a pointer to
        a struct "dentry_operations".  This method is called with the
        directory inode semaphore held

``link``
        called by the link(2) system call.  Only required if you want to
        support hard links.  You will probably need to call
        d_instantiate() just as you would in the create() method

``unlink``
        called by the unlink(2) system call.  Only required if you want
        to support deleting inodes

``symlink``
        called by the symlink(2) system call.  Only required if you want
        to support symlinks.  You will probably need to call
        d_instantiate() just as you would in the create() method

``mkdir``
        called by the mkdir(2) system call.  Only required if you want
        to support creating subdirectories.  You will probably need to
        call d_instantiate_new() just as you would in the create() method.

        If d_instantiate_new() is not used and if the fh_to_dentry()
        export operation is provided, or if the storage might be
        accessible by another path (e.g. with a network filesystem)
        then more care may be needed.  Importantly d_instantate()
        should not be used with an inode that is no longer I_NEW if there
        any chance that the inode could already be attached to a dentry.
        This is because of a hard rule in the VFS that a directory must
        only ever have one dentry.

        For example, if an NFS filesystem is mounted twice the new directory
        could be visible on the other mount before it is on the original
        mount, and a pair of name_to_handle_at(), open_by_handle_at()
        calls could instantiate the directory inode with an IS_ROOT()
        dentry before the first mkdir returns.

        If there is any chance this could happen, then the new inode
        should be d_drop()ed and attached with d_splice_alias().  The
        returned dentry (if any) should be returned by ->mkdir().

Rename·symlink·권한·attribute·atomic open

562-680
inode_operations 나머지 callback
callback역할중요 조건
renamerename(2)으로 parent·name 변경모르는 flag는 -EINVAL
get_linksymbolic link body 반환RCU mode에서 불가하면 ERR_PTR(-ECHILD)
readlinkreadlink(2) 특수 override보통 get_link만 구현
permissionPOSIX-like access right 검사MAY_NOT_BLOCK이면 block·inode write 금지
get_inode_acl / get_acl / set_aclinode 또는 idmapped dentry ACL 조회·설정operation table의 ACL hook
setattrchmod(2) 등 file attribute 설정iattr 적용
getattrstat(2) 등 file attribute 조회kstat 반환
listxattrfile의 xattr 전체 나열listxattr(2)에서 호출
update_timeinode time 또는 i_version 갱신없으면 VFS가 갱신 후 mark_inode_dirty_sync
atomic_open마지막 component lookup·create·open을 원자적으로 수행생성 시 FMODE_CREATED
tmpfileO_TMPFILE의 create·open·unlink성공 시 file이 이미 open
fileattr_get / fileattr_setFS_IOC_*FLAGS·FSGETXATTR 설정 조회없으면 f_op->ioctl fallback
get_offset_ctxdirectory inode offset context 반환simple_offset_dir_operations 사용 시 필수

이름 변경, link 탐색, 권한과 attribute, open을 다룬다.

rename flag
flag동작VFS 보장
RENAME_NOREPLACEtarget 존재 시 교체하지 않고 -EEXISTVFS가 존재 여부를 이미 검사
RENAME_EXCHANGEsource와 target 교환둘 다 존재해야 하며 type은 달라도 됨

현재 구현된 rename 확장 의미다.

`get_link`가 반환한 symlink body가 inode 수명까지 유지되지 않으면 `set_delayed_call(done, destructor, argument)`을 설정해 VFS 사용 완료 뒤 해제해야 한다. RCU mode는 NULL dentry로 표시되고 block이 필요하면 `ERR_PTR(-ECHILD)`를 반환해 ref-walk에서 재호출시킨다. target을 `->i_link`에 저장하면 VFS가 직접 사용할 수 있지만 `->get_link()`도 제공해야 하며, `->i_link`는 RCU grace period 전에는 해제할 수 없다. iget 뒤 쓰기에는 release memory barrier가 필요하다.

`permission`도 `mask & MAY_NOT_BLOCK`인 rcu-walk mode에서 호출될 수 있다. 이때 block하거나 inode에 저장해서는 안 되며 처리할 수 없으면 `-ECHILD`를 반환해 ref-walk 재호출을 요청한다.

`atomic_open`은 마지막 component가 negative이거나 lookup이 필요할 때만 호출된다. 실제 open을 caller에 맡기려면 symlink·device 등에서 `finish_no_open(file, dentry)`를 반환할 수 있다. cached positive dentry는 계속 `f_op->open()`이 처리한다. 생성 성공이면 `file->f_mode`에 `FMODE_CREATED`를 설정해야 하며 `O_EXCL` 성공에는 항상 설정되어야 한다. `tmpfile` 성공은 끝에서 `finish_open_simple()`로 file을 연 상태로 만들 수 있다.

RCU symlink·permission fallback
VFS가 LOOKUP_RCU 또는 MAY_NOT_BLOCK로 callback 호출lock 없이 즉시 처리 가능한지 판단가능하면 검증·target 반환불가능하면 -ECHILD 또는 ERR_PTR(-ECHILD)VFS가 ref-walk mode로 다시 호출

block할 수 없는 RCU walk에서 ref-walk로 안전하게 전환한다.


``rmdir``
        called by the rmdir(2) system call.  Only required if you want
        to support deleting subdirectories

``mknod``
        called by the mknod(2) system call to create a device (char,
        block) inode or a named pipe (FIFO) or socket.  Only required if
        you want to support creating these types of inodes.  You will
        probably need to call d_instantiate() just as you would in the
        create() method

``rename``
        called by the rename(2) system call to rename the object to have
        the parent and name given by the second inode and dentry.

        The filesystem must return -EINVAL for any unsupported or
        unknown flags.  Currently the following flags are implemented:
        (1) RENAME_NOREPLACE: this flag indicates that if the target of
        the rename exists the rename should fail with -EEXIST instead of
        replacing the target.  The VFS already checks for existence, so
        for local filesystems the RENAME_NOREPLACE implementation is
        equivalent to plain rename.
        (2) RENAME_EXCHANGE: exchange source and target.  Both must
        exist; this is checked by the VFS.  Unlike plain rename, source
        and target may be of different type.

``get_link``
        called by the VFS to follow a symbolic link to the inode it
        points to.  Only required if you want to support symbolic links.
        This method returns the symlink body to traverse (and possibly
        resets the current position with nd_jump_link()).  If the body
        won't go away until the inode is gone, nothing else is needed;
        if it needs to be otherwise pinned, arrange for its release by
        having get_link(..., ..., done) do set_delayed_call(done,
        destructor, argument).  In that case destructor(argument) will
        be called once VFS is done with the body you've returned.  May
        be called in RCU mode; that is indicated by NULL dentry
        argument.  If request can't be handled without leaving RCU mode,
        have it return ERR_PTR(-ECHILD).

        If the filesystem stores the symlink target in ->i_link, the
        VFS may use it directly without calling ->get_link(); however,
        ->get_link() must still be provided.  ->i_link must not be
        freed until after an RCU grace period.  Writing to ->i_link
        post-iget() time requires a 'release' memory barrier.

``readlink``
        this is now just an override for use by readlink(2) for the
        cases when ->get_link uses nd_jump_link() or object is not in
        fact a symlink.  Normally filesystems should only implement
        ->get_link for symlinks and readlink(2) will automatically use
        that.

``permission``
        called by the VFS to check for access rights on a POSIX-like
        filesystem.

        May be called in rcu-walk mode (mask & MAY_NOT_BLOCK).  If in
        rcu-walk mode, the filesystem must check the permission without
        blocking or storing to the inode.

        If a situation is encountered that rcu-walk cannot handle,
        return
        -ECHILD and it will be called again in ref-walk mode.

``setattr``
        called by the VFS to set attributes for a file.  This method is
        called by chmod(2) and related system calls.

``getattr``
        called by the VFS to get attributes of a file.  This method is
        called by stat(2) and related system calls.

``listxattr``
        called by the VFS to list all extended attributes for a given
        file.  This method is called by the listxattr(2) system call.

``update_time``
        called by the VFS to update a specific time or the i_version of
        an inode.  If this is not defined the VFS will update the inode
        itself and call mark_inode_dirty_sync.

``atomic_open``
        called on the last component of an open.  Using this optional
        method the filesystem can look up, possibly create and open the
        file in one atomic operation.  If it wants to leave actual
        opening to the caller (e.g. if the file turned out to be a
        symlink, device, or just something filesystem won't do atomic
        open for), it may signal this by returning finish_no_open(file,
        dentry).  This method is only called if the last component is
        negative or needs lookup.  Cached positive dentries are still
        handled by f_op->open().  If the file was created, FMODE_CREATED
        flag should be set in file->f_mode.  In case of O_EXCL the
        method must only succeed if the file didn't exist and hence
        FMODE_CREATED shall always be set on success.

``tmpfile``
        called in the end of O_TMPFILE open().  Optional, equivalent to
        atomically creating, opening and unlinking a file in given
        directory.  On success needs to return with the file already
        open; this can be done by calling finish_open_simple() right at
        the end.

``fileattr_get``
        called on ioctl(FS_IOC_GETFLAGS) and ioctl(FS_IOC_FSGETXATTR) to
        retrieve miscellaneous file flags and attributes.  Also called
        before the relevant SET operation to check what is being changed
        (in this case with i_rwsem locked exclusive).  If unset, then
        fall back to f_op->ioctl().

``fileattr_set``
        called on ioctl(FS_IOC_SETFLAGS) and ioctl(FS_IOC_FSSETXATTR) to
        change miscellaneous file flags and attributes.  Callers hold
        i_rwsem exclusive.  If unset, then fall back to f_op->ioctl().
``get_offset_ctx``
        called to get the offset context for a directory inode. A
        filesystem must define this operation to use
        simple_offset_dir_operations.

Address space와 page cache 상태

681-755

address space object는 page cache의 page를 묶어 관리하고 file section이 process address space에 mapping된 상태를 추적한다. memory pressure 전달, address에 의한 page lookup, Dirty·Writeback tag 추적처럼 서로 연관된 여러 서비스를 제공한다.

VM은 private flag가 있는 clean folio에 `->release_folio`를 호출해 재사용을 시도한다. PagePrivate가 없고 external reference도 없는 clean page는 address_space에 알리지 않고 해제된다. page는 `lru_cache_add`로 LRU에 넣고 사용할 때마다 `mark_page_active`를 호출해야 한다.

page는 보통 `->index`로 radix tree에 보관되고 tree가 `PG_Dirty`와 `PG_Writeback` 상태를 유지한다. Dirty tag는 기본 `->writepages`인 `mpage_writepages`가 기록할 page를 찾는 데 주로 쓴다. 자체 `->writepages`를 쓰면 `PAGECACHE_TAG_DIRTY` 사용은 적지만 `write_inode_now`와 `sync_inode`가 전체 address_space 기록 성공 여부를 확인할 때 사용한다. Writeback tag는 `filemap_fdatawait_range`를 거쳐 `filemap*wait*`와 `sync_page*`가 완료를 기다리는 데 쓴다.

address_space handler는 `struct page`의 `private` field에 추가 정보를 붙일 수 있고 이때 `PG_Private`를 설정해야 한다. 그러면 VM routine이 해당 data를 처리하려고 address_space handler를 추가 호출한다.

address_space는 storage와 application 사이의 중간 계층이다. storage에서 page 단위로 읽고 application에는 복사 또는 memory mapping으로 제공한다. application이 쓴 data는 address_space에 들어간 뒤 보통 전체 page 단위로 storage에 writeback되지만 write size는 address_space가 더 세밀하게 제어할 수 있다.

read는 본질적으로 `read_folio`만 필요하다. write는 `write_begin`·`write_end` 또는 `dirty_folio`로 data를 넣고 `writepages`로 storage에 기록한다. page 제거에는 inode `i_rwsem` exclusive, 추가에는 `i_mapping->invalidate_lock` exclusive가 필요하다.

page에 data를 쓰면 `PG_Dirty`를 설정하고 보통 `writepages`가 요청할 때까지 유지한다. writepages는 Dirty를 지우고 Writeback을 설정한다. 실제 기록은 Dirty가 지워진 뒤 언제든 가능하며 안전한 완료가 확인되면 Writeback을 지운다. `writeback_control`은 writeback 이유·제약을 전달하고 결과를 caller에 돌려준다.

Address space I/O 경로
read_folio·readahead로 storage에서 folio 적재page cache radix tree와 LRU에 등록application copy 또는 mmap 접근write_begin/write_end·dirty_folio로 PG_Dirtywritepages가 PG_Dirty 해제·PG_Writeback 설정storage 완료 뒤 PG_Writeback 해제

application data가 page cache를 거쳐 storage로 이동하는 상태 전이다.

Page cache 상태와 lock
작업상태·lock목적
page 추가i_mapping->invalidate_lock exclusiveinvalidation과 직렬화
page 제거inode i_rwsem exclusivemapping 변경 보호
dirtyPG_Dirty·PAGECACHE_TAG_DIRTYwrite 대상 빠른 검색
writebackPG_Writeback·Writeback tagI/O 완료 대기
private datapage private + PG_Privatefilesystem metadata callback 유도
reclaimLRU·release_folioclean folio 재사용

추가·제거·writeback에서 필요한 상태 표시와 serialization이다.


The Address Space Object
========================

The address space object is used to group and manage pages in the page
cache.  It can be used to keep track of the pages in a file (or anything
else) and also track the mapping of sections of the file into process
address spaces.

There are a number of distinct yet related services that an
address-space can provide.  These include communicating memory pressure,
page lookup by address, and keeping track of pages tagged as Dirty or
Writeback.

The first can be used independently to the others.  The VM can try to
release clean pages in order to reuse them.  To do this it can call
->release_folio on clean folios with the private
flag set.  Clean pages without PagePrivate and with no external references
will be released without notice being given to the address_space.

To achieve this functionality, pages need to be placed on an LRU with
lru_cache_add and mark_page_active needs to be called whenever the page
is used.

Pages are normally kept in a radix tree index by ->index.  This tree
maintains information about the PG_Dirty and PG_Writeback status of each
page, so that pages with either of these flags can be found quickly.

The Dirty tag is primarily used by mpage_writepages - the default
->writepages method.  It uses the tag to find dirty pages to
write back.  If mpage_writepages is not used (i.e. the address
provides its own ->writepages) , the PAGECACHE_TAG_DIRTY tag is almost
unused.  write_inode_now and sync_inode do use it (through
__sync_single_inode) to check if ->writepages has been successful in
writing out the whole address_space.

The Writeback tag is used by filemap*wait* and sync_page* functions, via
filemap_fdatawait_range, to wait for all writeback to complete.

An address_space handler may attach extra information to a page,
typically using the 'private' field in the 'struct page'.  If such
information is attached, the PG_Private flag should be set.  This will
cause various VM routines to make extra calls into the address_space
handler to deal with that data.

An address space acts as an intermediate between storage and
application.  Data is read into the address space a whole page at a
time, and provided to the application either by copying of the page, or
by memory-mapping the page.  Data is written into the address space by
the application, and then written-back to storage typically in whole
pages, however the address_space has finer control of write sizes.

The read process essentially only requires 'read_folio'.  The write
process is more complicated and uses write_begin/write_end or
dirty_folio to write data into the address_space, and
writepages to writeback data to storage.

Removing pages from an address_space requires holding the inode's i_rwsem
exclusively, while adding pages to the address_space requires holding the
inode's i_mapping->invalidate_lock exclusively.

When data is written to a page, the PG_Dirty flag should be set.  It
typically remains set until writepages asks for it to be written.  This
should clear PG_Dirty and set PG_Writeback.  It can be actually written
at any point after PG_Dirty is clear.  Once it is known to be safe,
PG_Writeback is cleared.

Writeback makes use of a writeback_control structure to direct the
operations.  This gives the writepages operation some
information about the nature of and reason for the writeback request,
and the constraints under which it is being done.  It is also used to
return information back to the caller about the result of a
writepages request.

Writeback error 보고

756-789

buffered I/O application은 `fsync`, `fdatasync`, `msync`, `sync_file_range` 같은 file synchronization call로 data가 backing store에 도달했는지 확인한다. writeback error는 다음 file sync request에서 보고되어야 한다. 한 request에서 보고한 뒤에는 새 writeback error가 생기지 않는 한 같은 file descriptor의 후속 request가 0을 반환해야 한다.

이상적으로는 실패한 write를 실제 수행한 file description에만 error를 보고해야 한다. 하지만 generic pagecache는 각 page를 dirty로 만든 file description을 추적하지 않으므로 이를 정확히 판별할 수 없다.

generic writeback error tracking은 error가 발생할 때 열려 있던 모든 file description의 `fsync`에 error를 보고한다. writer가 여러 개면 특정 descriptor의 모든 write가 성공했거나 write를 전혀 하지 않았어도 다음 fsync에서 모두 error를 받을 수 있다.

이 infrastructure를 쓰는 파일 시스템은 error 발생 시 `mapping_set_error`로 address_space에 기록한다. `file->fsync`에서 pagecache data를 writeback한 뒤 `file_check_and_advance_wb_err`를 호출해 `struct file`의 error cursor를 backing device error stream의 올바른 지점으로 전진시킨다.

Writeback error 전달
buffered write가 pagecache를 dirty로 만듦writeback 중 backing store error 발생mapping_set_error로 address_space에 기록열려 있던 file description들이 error stream 관찰fsync가 error 보고file_check_and_advance_wb_err로 cursor 전진

backing device error가 열린 file description의 다음 sync 결과로 전달되는 과정이다.

Writeback error 의미
상황결과
첫 sync 이후 관찰된 error해당 request에 error 반환
같은 descriptor의 다음 sync, 새 error 없음0 반환
error 당시 열린 여러 descriptor실제 write 여부와 무관하게 모두 다음 fsync에서 error 가능
정확한 writer 식별page별 dirty file description을 추적하지 않아 불가능

generic infrastructure가 제공하는 보장과 한계다.

Handling errors during writeback
--------------------------------

Most applications that do buffered I/O will periodically call a file
synchronization call (fsync, fdatasync, msync or sync_file_range) to
ensure that data written has made it to the backing store.  When there
is an error during writeback, they expect that error to be reported when
a file sync request is made.  After an error has been reported on one
request, subsequent requests on the same file descriptor should return
0, unless further writeback errors have occurred since the previous file
synchronization.

Ideally, the kernel would report errors only on file descriptions on
which writes were done that subsequently failed to be written back.  The
generic pagecache infrastructure does not track the file descriptions
that have dirtied each individual page however, so determining which
file descriptors should get back an error is not possible.

Instead, the generic writeback error tracking infrastructure in the
kernel settles for reporting errors to fsync on all file descriptions
that were open at the time that the error occurred.  In a situation with
multiple writers, all of them will get back an error on a subsequent
fsync, even if all of the writes done through that particular file
descriptor succeeded (or even if there were no writes on that file
descriptor at all).

Filesystems that wish to use this infrastructure should call
mapping_set_error to record the error in the address_space when it
occurs.  Then, after writing back data from the pagecache in their
file->fsync operation, they should call file_check_and_advance_wb_err to
ensure that the struct file's error cursor has advanced to the correct
point in the stream of errors emitted by the backing device(s).

Address space read·buffered write callback

790-927

`struct address_space_operations`는 VFS가 file mapping과 page cache를 조작하는 방법을 정의한다.

        struct address_space_operations {
                int (*read_folio)(struct file *, struct folio *);
                int (*writepages)(struct address_space *, struct writeback_control *);
                bool (*dirty_folio)(struct address_space *, struct folio *);
                void (*readahead)(struct readahead_control *);
                int (*write_begin)(const struct kiocb *, struct address_space *mapping,
                                   loff_t pos, unsigned len,
                                   struct page **pagep, void **fsdata);
                int (*write_end)(const struct kiocb *, struct address_space *mapping,
                                 loff_t pos, unsigned len, unsigned copied,
                                 struct folio *folio, void *fsdata);
                sector_t (*bmap)(struct address_space *, sector_t);
                void (*invalidate_folio) (struct folio *, size_t start, size_t len);
                bool (*release_folio)(struct folio *, gfp_t);
                void (*free_folio)(struct folio *);
                ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
                int (*migrate_folio)(struct mapping *, struct folio *dst,
                                struct folio *src, enum migrate_mode);
                int (*launder_folio) (struct folio *);

                bool (*is_partially_uptodate) (struct folio *, size_t from,
                                               size_t count);
                void (*is_dirty_writeback)(struct folio *, bool *, bool *);
                int (*error_remove_folio)(struct mapping *mapping, struct folio *);
                int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
                int (*swap_deactivate)(struct file *);
                int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
        };
address_space_operations read·write callback
callback역할핵심 계약
read_foliobacking store에서 folio 읽기locked folio를 완료 후 성공 여부와 무관하게 unlock
writepagesaddress_space의 dirty page 기록WB_SYNC_ALL range 또는 WB_SYNC_NONE nr_to_write 처리
dirty_foliofolio dirty 표시와 private data 갱신dirty flag와 i_pages search mark 설정
readahead연속 locked page의 선행 읽기sync page는 시도, async page에서 중단 가능
write_begin지정 offset·len의 buffered write 준비space 확보·부분 block preread·locked folio 반환
write_endcopy 뒤 write 완료folio unlock·refcount 감소·i_size 갱신

folio 적재, readahead와 buffered write의 앞·뒤 단계를 다룬다.

`read_folio`의 file 인자는 network filesystem 인증 정보를 제공하며 block filesystem에서는 대개 쓰지 않는다. kernel 자체 read처럼 열린 file이 없으면 NULL일 수 있다. large folio 미지원 mapping에서는 folio가 page 하나다. 성공 시 uptodate로 표시하고, page cache가 reference를 보유하므로 파일 시스템은 refcount를 바꿀 필요가 없다.

일반 read는 `->readahead()`를 사용하고 실패하거나 완료 대기가 필요할 때만 `->read_folio()`를 호출한다. read_folio 안에서 자체 readahead를 하면 안 된다. 지금 읽을 수 없으면 folio를 unlock하고 향후 성공 조건을 만든 뒤 `AOP_TRUNCATED_PAGE`를 반환한다. caller는 folio를 다시 lookup·lock해 재호출한다. 직접 호출보다 `read_mapping_folio()`를 쓰면 lock·wait·AOP_TRUNCATED_PAGE 처리를 맡길 수 있다.

`writepages`는 `WB_SYNC_ALL`이면 지정 range를 모두 기록하고 `WB_SYNC_NONE`이면 가능하면 `nr_to_write`만큼 기록한다. callback이 없으면 DIRTY tag page를 고르는 `mpage_writepages`를 사용한다.

`readahead`는 연속 locked page를 받는다. I/O를 시작한 page마다 refcount를 줄이고 보통 completion handler가 unlock한다. sync page 뒤 async page가 이어지며 `rac->ra->async_size`가 async 수다. sync는 모두 시도해야 하지만 async에 도달한 뒤 중단할 수 있다. 남은 page는 caller가 address_space에서 제거·unlock·put한다. 성공 I/O는 PageUptodate로 표시한다.

`write_begin`은 필요한 space를 할당하고 일부 basic block만 갱신한다면 나머지를 보존하도록 preread한다. caller가 쓸 locked pagecache folio를 `*foliop`로 반환하고 short write를 처리해야 한다. `fsdata`를 `write_end`에 전달할 수 있다. 성공은 0, 실패는 음수 error이며 실패 시 write_end는 호출되지 않는다. 성공한 write_begin 뒤에는 반드시 write_end를 호출하고, write_end는 실제 pagecache에 복사된 byte 수 또는 error를 반환한다.

Generic buffered write
offset·len으로 write_begin 호출space 확보와 부분 block prereadlocked pagecache folio 반환caller가 data copy, short write 가능write_end가 folio unlock·put·i_size 갱신복사 byte 수 또는 error 반환

write_begin과 write_end 사이의 책임 분리다.

struct address_space_operations
-------------------------------

This describes how the VFS can manipulate mapping of a file to page
cache in your filesystem.  The following members are defined:

.. code-block:: c

        struct address_space_operations {
                int (*read_folio)(struct file *, struct folio *);
                int (*writepages)(struct address_space *, struct writeback_control *);
                bool (*dirty_folio)(struct address_space *, struct folio *);
                void (*readahead)(struct readahead_control *);
                int (*write_begin)(const struct kiocb *, struct address_space *mapping,
                                   loff_t pos, unsigned len,
                                   struct page **pagep, void **fsdata);
                int (*write_end)(const struct kiocb *, struct address_space *mapping,
                                 loff_t pos, unsigned len, unsigned copied,
                                 struct folio *folio, void *fsdata);
                sector_t (*bmap)(struct address_space *, sector_t);
                void (*invalidate_folio) (struct folio *, size_t start, size_t len);
                bool (*release_folio)(struct folio *, gfp_t);
                void (*free_folio)(struct folio *);
                ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
                int (*migrate_folio)(struct mapping *, struct folio *dst,
                                struct folio *src, enum migrate_mode);
                int (*launder_folio) (struct folio *);

                bool (*is_partially_uptodate) (struct folio *, size_t from,
                                               size_t count);
                void (*is_dirty_writeback)(struct folio *, bool *, bool *);
                int (*error_remove_folio)(struct mapping *mapping, struct folio *);
                int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
                int (*swap_deactivate)(struct file *);
                int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
        };

``read_folio``
        Called by the page cache to read a folio from the backing store.
        The 'file' argument supplies authentication information to network
        filesystems, and is generally not used by block based filesystems.
        It may be NULL if the caller does not have an open file (eg if
        the kernel is performing a read for itself rather than on behalf
        of a userspace process with an open file).

        If the mapping does not support large folios, the folio will
        contain a single page.        The folio will be locked when read_folio
        is called.  If the read completes successfully, the folio should
        be marked uptodate.  The filesystem should unlock the folio
        once the read has completed, whether it was successful or not.
        The filesystem does not need to modify the refcount on the folio;
        the page cache holds a reference count and that will not be
        released until the folio is unlocked.

        Filesystems may implement ->read_folio() synchronously.
        In normal operation, folios are read through the ->readahead()
        method.  Only if this fails, or if the caller needs to wait for
        the read to complete will the page cache call ->read_folio().
        Filesystems should not attempt to perform their own readahead
        in the ->read_folio() operation.

        If the filesystem cannot perform the read at this time, it can
        unlock the folio, do whatever action it needs to ensure that the
        read will succeed in the future and return AOP_TRUNCATED_PAGE.
        In this case, the caller should look up the folio, lock it,
        and call ->read_folio again.

        Callers may invoke the ->read_folio() method directly, but using
        read_mapping_folio() will take care of locking, waiting for the
        read to complete and handle cases such as AOP_TRUNCATED_PAGE.

``writepages``
        called by the VM to write out pages associated with the
        address_space object.  If wbc->sync_mode is WB_SYNC_ALL, then
        the writeback_control will specify a range of pages that must be
        written out.  If it is WB_SYNC_NONE, then a nr_to_write is
        given and that many pages should be written if possible.  If no
        ->writepages is given, then mpage_writepages is used instead.
        This will choose pages from the address space that are tagged as
        DIRTY and will write them back.

``dirty_folio``
        called by the VM to mark a folio as dirty.  This is particularly
        needed if an address space attaches private data to a folio, and
        that data needs to be updated when a folio is dirtied.  This is
        called, for example, when a memory mapped page gets modified.
        If defined, it should set the folio dirty flag, and the
        PAGECACHE_TAG_DIRTY search mark in i_pages.

``readahead``
        Called by the VM to read pages associated with the address_space
        object.  The pages are consecutive in the page cache and are
        locked.  The implementation should decrement the page refcount
        after starting I/O on each page.  Usually the page will be
        unlocked by the I/O completion handler.  The set of pages are
        divided into some sync pages followed by some async pages,
        rac->ra->async_size gives the number of async pages.  The
        filesystem should attempt to read all sync pages but may decide
        to stop once it reaches the async pages.  If it does decide to
        stop attempting I/O, it can simply return.  The caller will
        remove the remaining pages from the address space, unlock them
        and decrement the page refcount.  Set PageUptodate if the I/O
        completes successfully.

``write_begin``
        Called by the generic buffered write code to ask the filesystem
        to prepare to write len bytes at the given offset in the file.
        The address_space should check that the write will be able to
        complete, by allocating space if necessary and doing any other
        internal housekeeping.  If the write will update parts of any
        basic-blocks on storage, then those blocks should be pre-read
        (if they haven't been read already) so that the updated blocks
        can be written out properly.

        The filesystem must return the locked pagecache folio for the
        specified offset, in ``*foliop``, for the caller to write into.

        It must be able to cope with short writes (where the length
        passed to write_begin is greater than the number of bytes copied
        into the folio).

        A void * may be returned in fsdata, which then gets passed into
        write_end.

        Returns 0 on success; < 0 on failure (which is the error code),
        in which case write_end is not called.

``write_end``
        After a successful write_begin, and data copy, write_end must be
        called.  len is the original len passed to write_begin, and
        copied is the amount that was able to be copied.

        The filesystem must take care of unlocking the folio,
        decrementing its refcount, and updating i_size.

        Returns < 0 on failure, otherwise the number of bytes (<=
        'copied') that were able to be copied into pagecache.

Mapping·folio 수명·direct I/O·swap callback

928-1034
address_space_operations 나머지 callback
callback역할중요 조건
bmaplogical block을 physical block number로 mappingFIBMAP와 stable swap-file mapping
invalidate_foliotruncate·hole punch·전체 invalidation 반영전체 folio면 private data 반드시 해제
release_folio해제 직전 private data 제거성공 시 private flag clear, 실패는 false
free_foliopage cache에서 보이지 않은 뒤 private data 정리reclaimer 호출 가능, block 금지
direct_IOpage cache를 우회한 storage↔application 전송generic read/write에서 호출
migrate_foliophysical memory compact·고장 장치 회피 이동private data와 reference를 새 folio로 이전
launder_foliofolio 해제 전 dirty data writeback전체 작업 동안 lock해 redirty 방지
is_partially_uptodatefolio보다 작은 block의 일부 최신 여부필요 block이 최신이면 전체 I/O 생략
is_dirty_writebackreclaim에서 복잡한 dirty/writeback 상태 제공NFS unstable folio 등 표현
error_remove_foliomemory failure에서 folio 제거보통 generic_error_remove_folio
swap_activateswap file 검증·extent 등록add_swap_extent 또는 iomap_swapfile_activate
swap_deactivate성공한 swap file의 swapoff정리 callback
swap_rwSWP_FS_OPS일 때 swap page I/Ofilesystem 경유 read/write

block mapping, invalidation, memory migration과 swap 준비를 다룬다.

`bmap`은 swap system이 파일 시스템을 거치지 않고 block address에 직접 I/O할 수 있도록 stable mapping을 제공한다. `invalidate_folio`에서 전체 folio 범위를 제거하면 private data 해제가 반드시 성공해야 한다.

`release_folio`는 두 경우에 사용된다. 첫째 VM이 active user가 없는 clean folio를 해제하려는 경우이며 성공하면 address_space에서 제거해 free한다. 둘째 `fadvise(POSIX_FADV_DONTNEED)` 또는 NFS·9p처럼 cache가 storage와 달라졌다고 판단한 파일 시스템이 `invalidate_inode_pages2()`를 호출한 경우다. 모든 folio invalidation을 보장하려면 release_folio가 그 요구를 충족해야 하며 private data를 아직 해제할 수 없으면 uptodate flag를 지우는 방법도 있다.

`is_dirty_writeback`은 일반 `folio_test_dirty`·`folio_test_writeback`으로 표현하기 어려운 filesystem state를 VM에 알려 reclaim stall 여부를 결정한다. `error_remove_folio`를 설정하면 lock이나 증가한 reference로 보호하지 않은 page가 사라질 수 있음을 처리해야 한다.

`swap_activate`는 최소 memory allocation으로 write할 수 있게 검증·준비하고 extent 수를 반환한다. `->swap_rw()`로 I/O할 경우 `SWP_FS_OPS`를 설정하며, 아니면 `sis->bdev` block device로 직접 제출한다.

Swap file activation
swap_activate에서 file 검증add_swap_extent 또는 iomap_swapfile_activatefilesystem I/O가 필요하면 SWP_FS_OPS 설정swap_rw 또는 sis->bdev로 page I/Oswapoff에서 swap_deactivate

file mapping을 swap subsystem이 사용할 수 있는 extent로 변환한다.

``bmap``
        called by the VFS to map a logical block offset within object to
        physical block number.  This method is used by the FIBMAP ioctl
        and for working with swap-files.  To be able to swap to a file,
        the file must have a stable mapping to a block device.  The swap
        system does not go through the filesystem but instead uses bmap
        to find out where the blocks in the file are and uses those
        addresses directly.

``invalidate_folio``
        If a folio has private data, then invalidate_folio will be
        called when part or all of the folio is to be removed from the
        address space.  This generally corresponds to either a
        truncation, punch hole or a complete invalidation of the address
        space (in the latter case 'offset' will always be 0 and 'length'
        will be folio_size()).  Any private data associated with the folio
        should be updated to reflect this truncation.  If offset is 0
        and length is folio_size(), then the private data should be
        released, because the folio must be able to be completely
        discarded.  This may be done by calling the ->release_folio
        function, but in this case the release MUST succeed.

``release_folio``
        release_folio is called on folios with private data to tell the
        filesystem that the folio is about to be freed.  ->release_folio
        should remove any private data from the folio and clear the
        private flag.  If release_folio() fails, it should return false.
        release_folio() is used in two distinct though related cases.
        The first is when the VM wants to free a clean folio with no
        active users.  If ->release_folio succeeds, the folio will be
        removed from the address_space and be freed.

        The second case is when a request has been made to invalidate
        some or all folios in an address_space.  This can happen
        through the fadvise(POSIX_FADV_DONTNEED) system call or by the
        filesystem explicitly requesting it as nfs and 9p do (when they
        believe the cache may be out of date with storage) by calling
        invalidate_inode_pages2().  If the filesystem makes such a call,
        and needs to be certain that all folios are invalidated, then
        its release_folio will need to ensure this.  Possibly it can
        clear the uptodate flag if it cannot free private data yet.

``free_folio``
        free_folio is called once the folio is no longer visible in the
        page cache in order to allow the cleanup of any private data.
        Since it may be called by the memory reclaimer, it should not
        assume that the original address_space mapping still exists, and
        it should not block.

``direct_IO``
        called by the generic read/write routines to perform direct_IO -
        that is IO requests which bypass the page cache and transfer
        data directly between the storage and the application's address
        space.

``migrate_folio``
        This is used to compact the physical memory usage.  If the VM
        wants to relocate a folio (maybe from a memory device that is
        signalling imminent failure) it will pass a new folio and an old
        folio to this function.  migrate_folio should transfer any private
        data across and update any references that it has to the folio.

``launder_folio``
        Called before freeing a folio - it writes back the dirty folio.
        To prevent redirtying the folio, it is kept locked during the
        whole operation.

``is_partially_uptodate``
        Called by the VM when reading a file through the pagecache when
        the underlying blocksize is smaller than the size of the folio.
        If the required block is up to date then the read can complete
        without needing I/O to bring the whole page up to date.

``is_dirty_writeback``
        Called by the VM when attempting to reclaim a folio.  The VM uses
        dirty and writeback information to determine if it needs to
        stall to allow flushers a chance to complete some IO.
        Ordinarily it can use folio_test_dirty and folio_test_writeback but
        some filesystems have more complex state (unstable folios in NFS
        prevent reclaim) or do not set those flags due to locking
        problems.  This callback allows a filesystem to indicate to the
        VM if a folio should be treated as dirty or writeback for the
        purposes of stalling.

``error_remove_folio``
        normally set to generic_error_remove_folio if truncation is ok
        for this address space.  Used for memory failure handling.
        Setting this implies you deal with pages going away under you,
        unless you have them locked or reference counts increased.

``swap_activate``

        Called to prepare the given file for swap.  It should perform
        any validation and preparation necessary to ensure that writes
        can be performed with minimal memory allocation.  It should call
        add_swap_extent(), or the helper iomap_swapfile_activate(), and
        return the number of extents added.  If IO should be submitted
        through ->swap_rw(), it should set SWP_FS_OPS, otherwise IO will
        be submitted directly to the block device ``sis->bdev``.

``swap_deactivate``
        Called during swapoff on files where swap_activate was
        successful.

``swap_rw``
        Called to read or write swap pages when SWP_FS_OPS is set.

Open file description과 file_operations

1035-1098

file object는 process가 연 file을 나타내며 POSIX 용어로 open file description이다. `struct file_operations`는 VFS가 열린 file을 조작하는 callback table이다. 별도 언급이 없으면 method는 lock 없이 호출된다.

        struct file_operations {
                struct module *owner;
                fop_flags_t fop_flags;
                loff_t (*llseek) (struct file *, loff_t, int);
                ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
                ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
                ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
                ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
                int (*iopoll)(struct kiocb *kiocb, struct io_comp_batch *,
                                unsigned int flags);
                int (*iterate_shared) (struct file *, struct dir_context *);
                __poll_t (*poll) (struct file *, struct poll_table_struct *);
                long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
                long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
                int (*mmap) (struct file *, struct vm_area_struct *);
                int (*open) (struct inode *, struct file *);
                int (*flush) (struct file *, fl_owner_t id);
                int (*release) (struct inode *, struct file *);
                int (*fsync) (struct file *, loff_t, loff_t, int datasync);
                int (*fasync) (int, struct file *, int);
                int (*lock) (struct file *, int, struct file_lock *);
                unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
                int (*check_flags)(int);
                int (*flock) (struct file *, int, struct file_lock *);
                ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
                ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
                void (*splice_eof)(struct file *file);
                int (*setlease)(struct file *, int, struct file_lease **, void **);
                long (*fallocate)(struct file *file, int mode, loff_t offset,
                                  loff_t len);
                void (*show_fdinfo)(struct seq_file *m, struct file *f);
        #ifndef CONFIG_MMU
                unsigned (*mmap_capabilities)(struct file *);
        #endif
                ssize_t (*copy_file_range)(struct file *, loff_t, struct file *,
                                loff_t, size_t, unsigned int);
                loff_t (*remap_file_range)(struct file *file_in, loff_t pos_in,
                                           struct file *file_out, loff_t pos_out,
                                           loff_t len, unsigned int remap_flags);
                int (*fadvise)(struct file *, loff_t, loff_t, int);
                int (*uring_cmd)(struct io_uring_cmd *ioucmd, unsigned int issue_flags);
                int (*uring_cmd_iopoll)(struct io_uring_cmd *, struct io_comp_batch *,
                                        unsigned int poll_flags);
                int (*mmap_prepare)(struct vm_area_desc *);
        };
file_operations 기능군
기능군member역할
소유·flagowner, fop_flagsmodule owner와 operation capability flag
position·기본 I/Ollseek, read, writeoffset 이동과 userspace buffer I/O
iterator·poll I/Oread_iter, write_iter, iopolliov_iter 기반 async I/O와 HIPRI completion poll
directory·eventiterate_shared, poll, fasyncdirectory iteration과 readiness·async notification
제어unlocked_ioctl, compat_ioctl, check_flagsnative·compat ioctl과 F_SETFL 검증
mappingmmap, mmap_prepare, get_unmapped_areafile-backed VMA 준비와 address 선택
수명·동기화open, flush, release, fsyncopen description 초기화·close·마지막 reference·sync
lock·leaselock, flock, setleasefcntl lock, BSD flock, lease
splicesplice_write, splice_read, splice_eofpipe↔file 전송과 EOF 알림
space·rangefallocate, copy_file_range, remap_file_range할당·copy·clone/dedupe
관찰·조언show_fdinfo, fadvisefdinfo 출력과 access pattern hint
io_uringuring_cmd, uring_cmd_iopollfilesystem·device command와 poll
no-MMUmmap_capabilitiesCONFIG_MMU가 없을 때 mmap capability

긴 callback table을 I/O 목적별로 묶어 본다.

The File Object
===============

A file object represents a file opened by a process.  This is also known
as an "open file description" in POSIX parlance.


struct file_operations
----------------------

This describes how the VFS can manipulate an open file.  As of kernel
4.18, the following members are defined:

.. code-block:: c

        struct file_operations {
                struct module *owner;
                fop_flags_t fop_flags;
                loff_t (*llseek) (struct file *, loff_t, int);
                ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
                ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
                ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
                ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
                int (*iopoll)(struct kiocb *kiocb, struct io_comp_batch *,
                                unsigned int flags);
                int (*iterate_shared) (struct file *, struct dir_context *);
                __poll_t (*poll) (struct file *, struct poll_table_struct *);
                long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
                long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
                int (*mmap) (struct file *, struct vm_area_struct *);
                int (*open) (struct inode *, struct file *);
                int (*flush) (struct file *, fl_owner_t id);
                int (*release) (struct inode *, struct file *);
                int (*fsync) (struct file *, loff_t, loff_t, int datasync);
                int (*fasync) (int, struct file *, int);
                int (*lock) (struct file *, int, struct file_lock *);
                unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
                int (*check_flags)(int);
                int (*flock) (struct file *, int, struct file_lock *);
                ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
                ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
                void (*splice_eof)(struct file *file);
                int (*setlease)(struct file *, int, struct file_lease **, void **);
                long (*fallocate)(struct file *file, int mode, loff_t offset,
                                  loff_t len);
                void (*show_fdinfo)(struct seq_file *m, struct file *f);
        #ifndef CONFIG_MMU
                unsigned (*mmap_capabilities)(struct file *);
        #endif
                ssize_t (*copy_file_range)(struct file *, loff_t, struct file *,
                                loff_t, size_t, unsigned int);
                loff_t (*remap_file_range)(struct file *file_in, loff_t pos_in,
                                           struct file *file_out, loff_t pos_out,
                                           loff_t len, unsigned int remap_flags);
                int (*fadvise)(struct file *, loff_t, loff_t, int);
                int (*uring_cmd)(struct io_uring_cmd *ioucmd, unsigned int issue_flags);
                int (*uring_cmd_iopoll)(struct io_uring_cmd *, struct io_comp_batch *,
                                        unsigned int poll_flags);
                int (*mmap_prepare)(struct vm_area_desc *);
        };

Again, all methods are called without any locks being held, unless
otherwise noted.

File operation 호출 의미

1099-1226
주요 file_operations callback
callback호출·역할특기 사항
llseekfile position index 이동VFS seek
read / writeread(2)·write(2) 계열userspace buffer
read_iter / write_iteriov_iter destination·source의 async 가능 I/Oiterator 기반
iopollAIO가 HIPRI iocb completion pollbatch completion
iterate_shareddirectory content 읽기shared iteration
pollselect(2)·poll(2)의 activity 확인·sleeppoll table 사용
unlocked_ioctl / compat_ioctlioctl(2), 64-bit kernel의 32-bit syscallcompat translation
mmap / mmap_preparemmap(2) mappingmmap은 deprecated, prepare가 private state·VMA callback 설정
openinode를 열어 새 struct file 초기화private_data 설정에 적합
flush / releaseclose 시 flush / 마지막 open-file reference 종료호출 시점이 다름
fsyncfsync(2)writeback error 절 참조
fasyncfcntl(2)의 async non-blocking modenotification 설정
lock / check_flags / flockfcntl lock·F_SETFL·flock(2)각 command 대응
get_unmapped_areammap address 선택VFS가 호출
splice_write / splice_readpipe→file / file→pipesplice(2)
setleasefile lock lease 설정·해제generic_setlease로 inode에 기록
fallocateblock preallocation 또는 hole punchVFS 공간 조작
copy_file_rangecopy_file_range(2)filesystem 최적화 가능
remap_file_rangeFICLONERANGE·FICLONE·FIDEDUPERANGEclone·dedupe와 alignment 처리
fadvisefadvise64() 가능 호출access pattern hint

system call과 VFS가 호출하는 open-file method의 대응이다.

`remap_file_range`는 source의 `pos_in`부터 `len` byte를 destination `pos_out`에 remap한다. `len == 0`은 source EOF까지를 뜻한다. 성공 시 remap byte 수, 시작 전 실패는 음수 error를 반환한다. `REMAP_FILE_DEDUP`이면 두 range 내용이 같을 때만 remap하고, `REMAP_FILE_CAN_SHORTEN`이면 alignment·EOF 등 이유로 요청 길이를 줄여도 caller가 허용한다.

file operation은 inode가 속한 실제 파일 시스템이 구현한다. device node를 열면 대부분의 파일 시스템은 VFS helper를 호출해 char 또는 block device driver 정보를 찾는다. helper가 filesystem file operation을 device driver operation으로 교체한 뒤 새 `open()`을 호출하므로, 파일 시스템의 device file open이 결국 driver의 open method에 도달한다.

Device node open dispatch
VFS가 device inode의 struct file 생성filesystem open/helper 호출char·block device driver 정보 탐색file_operations를 driver table로 교체device driver open() 호출

filesystem object에서 실제 device driver callback으로 전환되는 과정이다.

``llseek``
        called when the VFS needs to move the file position index

``read``
        called by read(2) and related system calls

``read_iter``
        possibly asynchronous read with iov_iter as destination

``write``
        called by write(2) and related system calls

``write_iter``
        possibly asynchronous write with iov_iter as source

``iopoll``
        called when aio wants to poll for completions on HIPRI iocbs

``iterate_shared``
        called when the VFS needs to read the directory contents

``poll``
        called by the VFS when a process wants to check if there is
        activity on this file and (optionally) go to sleep until there
        is activity.  Called by the select(2) and poll(2) system calls

``unlocked_ioctl``
        called by the ioctl(2) system call.

``compat_ioctl``
        called by the ioctl(2) system call when 32 bit system calls are
         used on 64 bit kernels.

``mmap``
        called by the mmap(2) system call. Deprecated in favour of
        ``mmap_prepare``.

``open``
        called by the VFS when an inode should be opened.  When the VFS
        opens a file, it creates a new "struct file".  It then calls the
        open method for the newly allocated file structure.  You might
        think that the open method really belongs in "struct
        inode_operations", and you may be right.  I think it's done the
        way it is because it makes filesystems simpler to implement.
        The open() method is a good place to initialize the
        "private_data" member in the file structure if you want to point
        to a device structure

``flush``
        called by the close(2) system call to flush a file

``release``
        called when the last reference to an open file is closed

``fsync``
        called by the fsync(2) system call.  Also see the section above
        entitled "Handling errors during writeback".

``fasync``
        called by the fcntl(2) system call when asynchronous
        (non-blocking) mode is enabled for a file

``lock``
        called by the fcntl(2) system call for F_GETLK, F_SETLK, and
        F_SETLKW commands

``get_unmapped_area``
        called by the mmap(2) system call

``check_flags``
        called by the fcntl(2) system call for F_SETFL command

``flock``
        called by the flock(2) system call

``splice_write``
        called by the VFS to splice data from a pipe to a file.  This
        method is used by the splice(2) system call

``splice_read``
        called by the VFS to splice data from file to a pipe.  This
        method is used by the splice(2) system call

``setlease``
        called by the VFS to set or release a file lock lease.  setlease
        implementations should call generic_setlease to record or remove
        the lease in the inode after setting it.

``fallocate``
        called by the VFS to preallocate blocks or punch a hole.

``copy_file_range``
        called by the copy_file_range(2) system call.

``remap_file_range``
        called by the ioctl(2) system call for FICLONERANGE and FICLONE
        and FIDEDUPERANGE commands to remap file ranges.  An
        implementation should remap len bytes at pos_in of the source
        file into the dest file at pos_out.  Implementations must handle
        callers passing in len == 0; this means "remap to the end of the
        source file".  The return value should the number of bytes
        remapped, or the usual negative error code if errors occurred
        before any bytes were remapped.  The remap_flags parameter
        accepts REMAP_FILE_* flags.  If REMAP_FILE_DEDUP is set then the
        implementation must only remap if the requested file ranges have
        identical contents.  If REMAP_FILE_CAN_SHORTEN is set, the caller is
        ok with the implementation shortening the request length to
        satisfy alignment or EOF requirements (or any other reason).

``fadvise``
        possibly called by the fadvise64() system call.

``mmap_prepare``
        Called by the mmap(2) system call. Allows a VFS to set up a
        file-backed memory mapping, most notably establishing relevant
        private state and VMA callbacks.

Note that the file operations are implemented by the specific
filesystem in which the inode resides.  When opening a device node
(character or block special) most filesystems will call special
support routines in the VFS which will locate the required device
driver information.  These support routines replace the filesystem file
operations with those for the device driver, and then proceed to call
the new open() method for the file.  This is how opening a device file
in the filesystem eventually ends up calling the device driver open()
method.

Dentry 검증·hash·수명 callback

1227-1360

dentry와 dcache는 VFS와 개별 파일 시스템 구현의 영역이며 device driver가 관여하지 않는다. `struct dentry_operations`는 기본 dentry operation을 파일 시스템이 override하는 table이다. 각 method는 optional이거나 VFS default가 있으므로 NULL일 수 있다.

        struct dentry_operations {
                int (*d_revalidate)(struct inode *, const struct qstr *,
                                    struct dentry *, unsigned int);
                int (*d_weak_revalidate)(struct dentry *, unsigned int);
                int (*d_hash)(const struct dentry *, struct qstr *);
                int (*d_compare)(const struct dentry *,
                                 unsigned int, const char *, const struct qstr *);
                int (*d_delete)(const struct dentry *);
                int (*d_init)(struct dentry *);
                void (*d_release)(struct dentry *);
                void (*d_iput)(struct dentry *, struct inode *);
                char *(*d_dname)(struct dentry *, char *, int);
                struct vfsmount *(*d_automount)(struct path *);
                int (*d_manage)(const struct path *, bool);
                struct dentry *(*d_real)(struct dentry *, enum d_real_type type);
                bool (*d_unalias_trylock)(const struct dentry *);
                void (*d_unalias_unlock)(const struct dentry *);
        };
dentry_operations 검증·수명 callback
callback역할규칙
d_revalidatedcache name lookup에서 dentry 재검증valid 양수, invalid 0 또는 음수 error
d_weak_revalidateparent lookup 없이 jump한 dentry의 inode 유효성 검증RCU-walk를 나온 뒤만 호출
d_hashname을 dcache hash table에 넣을 hash 계산첫 dentry는 parent
d_comparedentry name과 qstr 비교constant·idempotent, lock·write 회피
d_delete마지막 reference에서 cache 여부 결정1 즉시 삭제, 0 cache, NULL은 reachable cache
d_initdentry 할당 시 초기화optional
d_releasedentry 실제 deallocationresource 정리
d_iputdentry가 inode를 잃을 때override하면 직접 iput() 호출
d_dname필요할 때 pathname 생성pseudo filesystem에 유용, buffer 끝에 작성

name lookup 결과를 검증하고 cache entry의 수명을 제어한다.

local filesystem은 dcache entry가 항상 유효하므로 보통 `d_revalidate`를 NULL로 둔다. network filesystem은 server에서 client 모르게 바뀔 수 있어 재검증이 필요하다. `LOOKUP_RCU`인 rcu-walk에서는 block하거나 dentry에 저장하면 안 되고 `d_parent`·`d_inode`는 변경되거나 NULL이 될 수 있어 주의해야 한다. 처리할 수 없으면 `-ECHILD`로 ref-walk 재호출을 요청한다.

`d_weak_revalidate`는 `/`, `.`, `..`, procfs-style symlink, mountpoint traversal처럼 parent directory lookup으로 얻지 않은 jumped dentry에서 호출한다. 완전한 dentry 정확성보다 inode가 여전히 유효한지가 중요하며 return 의미는 d_revalidate와 같다.

`d_compare`는 rcu-walk에서 lock과 reference 없이 호출되는 까다로운 convention이다. 가능하면 lock을 잡거나 dentry에 쓰지 말고 `d_parent`, `d_inode`, `d_name` 같은 외부 pointer를 함부로 역참조하지 않는다. vfsmount와 RCU가 pinned이므로 dentry·inode·superblock·module은 사라지지 않고 `->d_sb`는 사용할 수 있다.

`d_dname`은 sockfs·pipefs 같은 pseudo filesystem이 path가 실제 필요할 때까지 생성을 늦추는 데 유용하다. real filesystem의 global dcache hash는 name hash가 invariant여야 하므로 보통 사용하지 않는다. lock이 없으므로 적절한 SMP safety 없이 dentry를 수정하면 안 된다. `d_path()` 규칙에 맞게 문자열을 buffer 끝에 놓고 첫 문자 pointer를 반환해야 하며 `dynamic_dname()` helper가 이를 처리한다.

Dentry RCU 재검증
dcache hit 또는 jumped dentryLOOKUP_RCU 여부 확인block·write 없이 revalidate 가능하면 결과 반환불가능하면 -ECHILDVFS가 ref-walk에서 callback 재호출

lockless pathwalk에서 처리할 수 없는 조건을 안전하게 넘긴다.

Directory Entry Cache (dcache)
==============================


struct dentry_operations
------------------------

This describes how a filesystem can overload the standard dentry
operations.  Dentries and the dcache are the domain of the VFS and the
individual filesystem implementations.  Device drivers have no business
here.  These methods may be set to NULL, as they are either optional or
the VFS uses a default.  As of kernel 2.6.22, the following members are
defined:

.. code-block:: c

        struct dentry_operations {
                int (*d_revalidate)(struct inode *, const struct qstr *,
                                    struct dentry *, unsigned int);
                int (*d_weak_revalidate)(struct dentry *, unsigned int);
                int (*d_hash)(const struct dentry *, struct qstr *);
                int (*d_compare)(const struct dentry *,
                                 unsigned int, const char *, const struct qstr *);
                int (*d_delete)(const struct dentry *);
                int (*d_init)(struct dentry *);
                void (*d_release)(struct dentry *);
                void (*d_iput)(struct dentry *, struct inode *);
                char *(*d_dname)(struct dentry *, char *, int);
                struct vfsmount *(*d_automount)(struct path *);
                int (*d_manage)(const struct path *, bool);
                struct dentry *(*d_real)(struct dentry *, enum d_real_type type);
                bool (*d_unalias_trylock)(const struct dentry *);
                void (*d_unalias_unlock)(const struct dentry *);
        };

``d_revalidate``
        called when the VFS needs to revalidate a dentry.  This is
        called whenever a name look-up finds a dentry in the dcache.
        Most local filesystems leave this as NULL, because all their
        dentries in the dcache are valid.  Network filesystems are
        different since things can change on the server without the
        client necessarily being aware of it.

        This function should return a positive value if the dentry is
        still valid, and zero or a negative error code if it isn't.

        d_revalidate may be called in rcu-walk mode (flags &
        LOOKUP_RCU).  If in rcu-walk mode, the filesystem must
        revalidate the dentry without blocking or storing to the dentry,
        d_parent and d_inode should not be used without care (because
        they can change and, in d_inode case, even become NULL under
        us).

        If a situation is encountered that rcu-walk cannot handle,
        return
        -ECHILD and it will be called again in ref-walk mode.

``d_weak_revalidate``
        called when the VFS needs to revalidate a "jumped" dentry.  This
        is called when a path-walk ends at dentry that was not acquired
        by doing a lookup in the parent directory.  This includes "/",
        "." and "..", as well as procfs-style symlinks and mountpoint
        traversal.

        In this case, we are less concerned with whether the dentry is
        still fully correct, but rather that the inode is still valid.
        As with d_revalidate, most local filesystems will set this to
        NULL since their dcache entries are always valid.

        This function has the same return code semantics as
        d_revalidate.

        d_weak_revalidate is only called after leaving rcu-walk mode.

``d_hash``
        called when the VFS adds a dentry to the hash table.  The first
        dentry passed to d_hash is the parent directory that the name is
        to be hashed into.

        Same locking and synchronisation rules as d_compare regarding
        what is safe to dereference etc.

``d_compare``
        called to compare a dentry name with a given name.  The first
        dentry is the parent of the dentry to be compared, the second is
        the child dentry.  len and name string are properties of the
        dentry to be compared.  qstr is the name to compare it with.

        Must be constant and idempotent, and should not take locks if
        possible, and should not or store into the dentry.  Should not
        dereference pointers outside the dentry without lots of care
        (eg.  d_parent, d_inode, d_name should not be used).

        However, our vfsmount is pinned, and RCU held, so the dentries
        and inodes won't disappear, neither will our sb or filesystem
        module.  ->d_sb may be used.

        It is a tricky calling convention because it needs to be called
        under "rcu-walk", ie. without any locks or references on things.

``d_delete``
        called when the last reference to a dentry is dropped and the
        dcache is deciding whether or not to cache it.  Return 1 to
        delete immediately, or 0 to cache the dentry.  Default is NULL
        which means to always cache a reachable dentry.  d_delete must
        be constant and idempotent.

``d_init``
        called when a dentry is allocated

``d_release``
        called when a dentry is really deallocated

``d_iput``
        called when a dentry loses its inode (just prior to its being
        deallocated).  The default when this is NULL is that the VFS
        calls iput().  If you define this method, you must call iput()
        yourself

``d_dname``
        called when the pathname of a dentry should be generated.
        Useful for some pseudo filesystems (sockfs, pipefs, ...) to
        delay pathname generation.  (Instead of doing it when dentry is
        created, it's done only when the path is needed.).  Real
        filesystems probably dont want to use it, because their dentries
        are present in global dcache hash, so their hash should be an
        invariant.  As no lock is held, d_dname() should not try to
        modify the dentry itself, unless appropriate SMP safety is used.
        CAUTION : d_path() logic is quite tricky.  The correct way to
        return for example "Hello" is to put it at the end of the
        buffer, and returns a pointer to the first char.
        dynamic_dname() helper function is provided to take care of
        this.

Dentry 이름 생성·automount·overlay·unalias

1361-1438

`d_dname` 예제는 pipe inode number를 `pipe:[%lu]` 형식으로 buffer에 기록하도록 `dynamic_dname()`을 호출한다. 원문 예제의 parameter 이름 차이도 코드 그대로 보존한다.

        static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
        {
                return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
                                dentry->d_inode->i_ino);
        }
dentry_operations 경로 전환 callback
callback역할반환·조건
d_automountautomount dentry traversal에서 새 vfsmount 생성NULL은 다른 주체가 완료, -EISDIR은 ordinary directory
d_managemountpoint 뒤로 가는 client transition 관리0 계속, -EISDIR mount 무시, 기타 error는 pathwalk 중단
d_realoverlay/union regular file의 underlying dentry 반환D_REAL_DATA 또는 D_REAL_METADATA
d_unalias_trylockd_splice_alias의 기존 attached alias 이동 전 lock 시도false면 __d_move 방지, -ESTALE
d_unalias_unlockunalias 이동 뒤 unlockd_unalias_trylock과 pair

automount, transit 관리, overlay real dentry와 alias 이동을 다룬다.

`d_automount`는 automount target directory와 상속 가능한 mount parameter를 줄 parent mount record가 든 path를 받는다. vfsmount를 반환하면 caller가 mountpoint에 붙이고 실패하면 expiration list에서 제거한다. `DCACHE_NEED_AUTOMOUNT`가 있는 dentry에서만 쓰이며 inode의 `S_AUTOMOUNT`를 보고 `__d_instantiate()`가 이 flag를 설정한다.

`d_manage`는 autofs가 daemon은 subtree를 만들러 통과시키면서 client는 mountpoint 뒤 탐색을 기다리게 하는 식의 전환 제어를 제공한다. `rcu_walk`이 true면 sleep할 수 없고 처리 불가 시 `-ECHILD`로 재호출을 요청한다. `-EISDIR`은 `d_automount`나 기존 mount를 무시하고 ordinary directory로 계속하라는 뜻이다. `DCACHE_MANAGE_TRANSIT`가 설정된 dentry에서만 사용한다.

`d_real`은 overlay 또는 union filesystem의 regular file이 감춘 underlying dentry 중 data 또는 metadata inode를 가진 것을 반환한다. non-regular file은 전달받은 dentry를 그대로 반환한다.

`d_unalias_trylock`은 `FS_RENAME_DOES_D_MOVE`만으로 막을 수 없는 `d_splice_alias()`의 directory alias 이동을 안정화한다. 전체 root path를 blocking operation 동안 고정해야 하는 9p 같은 경우에 필요하다. 성공한 trylock은 `__d_unalias()`의 `__d_move()` 뒤 `d_unalias_unlock`으로 해제한다.

Automount pathwalk 결과
DCACHE_NEED_AUTOMOUNT dentry traversald_manage가 transit 허용·대기·fallback 결정d_automount가 vfsmount 생성 시도vfsmount 반환이면 mountpoint에 attachNULL은 다른 주체의 mount 사용-EISDIR이면 ordinary directory로 계속

callback return이 pathwalk와 mount attachment를 어떻게 바꾸는지 보여 준다.

        Example :

.. code-block:: c

        static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
        {
                return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
                                dentry->d_inode->i_ino);
        }

``d_automount``
        called when an automount dentry is to be traversed (optional).
        This should create a new VFS mount record and return the record
        to the caller.  The caller is supplied with a path parameter
        giving the automount directory to describe the automount target
        and the parent VFS mount record to provide inheritable mount
        parameters.  NULL should be returned if someone else managed to
        make the automount first.  If the vfsmount creation failed, then
        an error code should be returned.  If -EISDIR is returned, then
        the directory will be treated as an ordinary directory and
        returned to pathwalk to continue walking.

        If a vfsmount is returned, the caller will attempt to mount it
        on the mountpoint and will remove the vfsmount from its
        expiration list in the case of failure.

        This function is only used if DCACHE_NEED_AUTOMOUNT is set on
        the dentry.  This is set by __d_instantiate() if S_AUTOMOUNT is
        set on the inode being added.

``d_manage``
        called to allow the filesystem to manage the transition from a
        dentry (optional).  This allows autofs, for example, to hold up
        clients waiting to explore behind a 'mountpoint' while letting
        the daemon go past and construct the subtree there.  0 should be
        returned to let the calling process continue.  -EISDIR can be
        returned to tell pathwalk to use this directory as an ordinary
        directory and to ignore anything mounted on it and not to check
        the automount flag.  Any other error code will abort pathwalk
        completely.

        If the 'rcu_walk' parameter is true, then the caller is doing a
        pathwalk in RCU-walk mode.  Sleeping is not permitted in this
        mode, and the caller can be asked to leave it and call again by
        returning -ECHILD.  -EISDIR may also be returned to tell
        pathwalk to ignore d_automount or any mounts.

        This function is only used if DCACHE_MANAGE_TRANSIT is set on
        the dentry being transited from.

``d_real``
        overlay/union type filesystems implement this method to return one
        of the underlying dentries of a regular file hidden by the overlay.

        The 'type' argument takes the values D_REAL_DATA or D_REAL_METADATA
        for returning the real underlying dentry that refers to the inode
        hosting the file's data or metadata respectively.

        For non-regular files, the 'dentry' argument is returned.

``d_unalias_trylock``
        if present, will be called by d_splice_alias() before moving a
        preexisting attached alias.  Returning false prevents __d_move(),
        making d_splice_alias() fail with -ESTALE.

        Rationale: setting FS_RENAME_DOES_D_MOVE will prevent d_move()
        and d_exchange() calls from the outside of filesystem methods;
        however, it does not guarantee that attached dentries won't
        be renamed or moved by d_splice_alias() finding a preexisting
        alias for a directory inode.  Normally we would not care;
        however, something that wants to stabilize the entire path to
        root over a blocking operation might need that.  See 9p for one
        (and hopefully only) example.

``d_unalias_unlock``
        should be paired with ``d_unalias_trylock``; that one is called after
        __d_move() call in __d_unalias().

Directory Entry Cache API

1439-1493

각 dentry는 parent dentry pointer와 child dentry hash list를 가진다. child dentry는 directory 안의 file과 같은 관계다. 파일 시스템은 다음 API로 dentry를 조작한다.

Dcache 조작 API
API동작후속 책임
dget기존 dentry handle을 열어 usage count 증가나중에 dput
dputusage count 감소0이면 d_delete 판단, cache면 LRU, 아니면 삭제
d_dropparent hash list에서 dentry unhash후속 dput에서 count 0이면 deallocate
d_deletedentry 삭제reference 없으면 negative dentry와 d_iput, 있으면 d_drop
d_addparent hash list에 추가 후 d_instantiatelookup 결과 연결
d_instantiateinode alias hash에 dentry 추가하고 d_inode 갱신inode NULL이면 negative dentry
d_lookupparent와 pathname component로 child 검색찾으면 refcount 증가, caller가 dput

reference, hash 연결과 inode alias 연결의 기본 helper다.

`dput()`으로 count가 0이 되고 dentry가 parent hash에 남아 있으면 `d_delete` method로 cache 여부를 묻는다. cache하지 않거나 이미 unhashed이면 삭제하고, cache하면 memory shortage 때 reclaim하도록 LRU에 넣는다.

`d_instantiate()`는 existing negative dentry에 새 inode를 연결할 때 흔히 사용하며 inode `i_count`가 설정되거나 증가해야 한다. NULL inode pointer는 negative dentry를 뜻한다. `d_lookup()`이 반환한 dentry reference는 사용 후 반드시 `dput()`해야 한다.

Dentry cache 수명
d_lookup 또는 d_add로 hashed dentry 획득dget으로 usage count 증가사용 완료 후 dputcount 0이면 d_delete policy 확인cache하면 LRU, 아니면 unhash·deallocate

lookup reference가 cache 또는 deallocation으로 끝나는 경로다.


Each dentry has a pointer to its parent dentry, as well as a hash list
of child dentries.  Child dentries are basically like files in a
directory.


Directory Entry Cache API
--------------------------

There are a number of functions defined which permit a filesystem to
manipulate dentries:

``dget``
        open a new handle for an existing dentry (this just increments
        the usage count)

``dput``
        close a handle for a dentry (decrements the usage count).  If
        the usage count drops to 0, and the dentry is still in its
        parent's hash, the "d_delete" method is called to check whether
        it should be cached.  If it should not be cached, or if the
        dentry is not hashed, it is deleted.  Otherwise cached dentries
        are put into an LRU list to be reclaimed on memory shortage.

``d_drop``
        this unhashes a dentry from its parents hash list.  A subsequent
        call to dput() will deallocate the dentry if its usage count
        drops to 0

``d_delete``
        delete a dentry.  If there are no other open references to the
        dentry then the dentry is turned into a negative dentry (the
        d_iput() method is called).  If there are other references, then
        d_drop() is called instead

``d_add``
        add a dentry to its parents hash list and then calls
        d_instantiate()

``d_instantiate``
        add a dentry to the alias hash list for the inode and updates
        the "d_inode" member.  The "i_count" member in the inode
        structure should be set/incremented.  If the inode pointer is
        NULL, the dentry is called a "negative dentry".  This function
        is commonly called when an inode is created for an existing
        negative dentry

``d_lookup``
        look up a dentry given its parent and path name component It
        looks up the child of that given name from the dcache hash
        table.  If it is found, the reference count is incremented and
        the dentry is returned.  The caller must use dput() to free the
        dentry when it finishes using it.

Mount option parse와 표시

1494-1534

mount와 remount에서 파일 시스템은 comma-separated mount option 문자열을 받는다. 각 항목은 값 없는 `option` 또는 값이 있는 `option=value` 형식이다. `<linux/parser.h>`는 이를 parse하는 API를 제공하며 기존 파일 시스템에 사용 예가 많다.

Mount option 형식과 표시 규칙
항목규칙
입력 형식comma-separated `option` 또는 `option=value`
parse helper`<linux/parser.h>` API
비기본 optionshow_options()에서 반드시 표시
기본과 다른 값show_options()에서 반드시 표시
기본으로 활성·기본값표시해도 됨
helper↔kernel 내부 optionfile descriptor 등은 표시 의무 예외
mount 시점만 영향journal 생성 제어 등은 표시 의무 예외

입력 parse와 /proc 출력이 재현 가능한 mount를 만들어야 한다.

mount option을 받는 파일 시스템은 현재 활성 option을 출력하도록 `show_options()`를 정의해야 한다. 기본이 아니거나 값이 기본과 다른 option은 반드시 보여야 한다. 기본 활성 option이나 기본값은 보여도 된다. mount helper와 kernel 사이에서만 쓰는 file descriptor 같은 option, journal 생성처럼 mount 순간에만 영향을 주는 option은 예외다.

이 규칙의 목적은 `/proc/mounts` 정보만으로 unmount 후 다시 mount하는 등 기존 mount를 정확히 재현할 수 있게 하는 것이다.

Mount option 재현성
mount helper가 option 문자열 전달filesystem parser가 option·value 해석활성 상태를 superblock에 저장show_options가 비기본 상태를 출력/proc/mounts 정보로 같은 mount 재현

입력된 설정이 /proc 정보로 다시 구성되는 계약이다.

Mount Options
=============


Parsing options
---------------

On mount and remount the filesystem is passed a string containing a
comma separated list of mount options.  The options can have either of
these forms:

  option
  option=value

The <linux/parser.h> header defines an API that helps parse these
options.  There are plenty of examples on how to use it in existing
filesystems.


Showing options
---------------

If a filesystem accepts mount options, it must define show_options() to
show all the currently active options.  The rules are:

  - options MUST be shown which are not default or their values differ
    from the default

  - options MAY be shown which are enabled by default or have their
    default value

Options used only internally between a mount helper and the kernel (such
as file descriptors), or which only have an effect during the mounting
(such as ones controlling the creation of a journal) are exempt from the
above rules.

The underlying reason for the above rules is to make sure, that a mount
can be accurately replicated (e.g. umounting and mounting again) based
on the information found in /proc/mounts.

추가 참고 자료

1535-1551

이 절의 일부 자료는 최신 kernel version을 반영하지 않을 수 있다. 그래도 Linux VFS의 설계 배경과 구현 흐름을 이해하는 역사적 참고 자료로 제공된다.

VFS 참고 자료
자료연도URL
Creating Linux virtual filesystems2002https://lwn.net/Articles/13325/
The Linux Virtual File-system Layer by Neil Brown1999http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
A tour of the Linux VFS by Michael K. Johnson1996https://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html
A small trail through the Linux kernel by Andries Brouwer2001https://www.win.tue.nl/~aeb/linux/vfs/trail.html

원문의 제목·연도·URL을 그대로 보존한다.

오래된 callback signature나 locking 전제는 현재 source와 반드시 대조해야 한다. 이 번역은 Linux v6.18.37의 해당 원문과 code block을 기준으로 하며 URL은 원문 그대로 유지한다.

Resources
=========

(Note some of these resources are not up-to-date with the latest kernel
 version.)

Creating Linux virtual filesystems. 2002
    <https://lwn.net/Articles/13325/>

The Linux Virtual File-system Layer by Neil Brown. 1999
    <http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html>

A tour of the Linux VFS by Michael K. Johnson. 1996
    <https://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html>

A small trail through the Linux kernel by Andries Brouwer. 2001
    <https://www.win.tue.nl/~aeb/linux/vfs/trail.html>