files.rst 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. .. SPDX-License-Identifier: GPL-2.0
  2. ===================================
  3. File management in the Linux kernel
  4. ===================================
  5. This document describes how locking for files (struct file)
  6. and file descriptor table (struct files) works.
  7. Up until 2.6.12, the file descriptor table has been protected
  8. with a lock (files->file_lock) and reference count (files->count).
  9. ->file_lock protected accesses to all the file related fields
  10. of the table. ->count was used for sharing the file descriptor
  11. table between tasks cloned with CLONE_FILES flag. Typically
  12. this would be the case for posix threads. As with the common
  13. refcounting model in the kernel, the last task doing
  14. a put_files_struct() frees the file descriptor (fd) table.
  15. The files (struct file) themselves are protected using
  16. reference count (->f_count).
  17. In the new lock-free model of file descriptor management,
  18. the reference counting is similar, but the locking is
  19. based on RCU. The file descriptor table contains multiple
  20. elements - the fd sets (open_fds and close_on_exec, the
  21. array of file pointers, the sizes of the sets and the array
  22. etc.). In order for the updates to appear atomic to
  23. a lock-free reader, all the elements of the file descriptor
  24. table are in a separate structure - struct fdtable.
  25. files_struct contains a pointer to struct fdtable through
  26. which the actual fd table is accessed. Initially the
  27. fdtable is embedded in files_struct itself. On a subsequent
  28. expansion of fdtable, a new fdtable structure is allocated
  29. and files->fdtab points to the new structure. The fdtable
  30. structure is freed with RCU and lock-free readers either
  31. see the old fdtable or the new fdtable making the update
  32. appear atomic. Here are the locking rules for
  33. the fdtable structure -
  34. 1. All references to the fdtable must be done through
  35. the files_fdtable() macro::
  36. struct fdtable *fdt;
  37. rcu_read_lock();
  38. fdt = files_fdtable(files);
  39. ....
  40. if (n <= fdt->max_fds)
  41. ....
  42. ...
  43. rcu_read_unlock();
  44. files_fdtable() uses rcu_dereference() macro which takes care of
  45. the memory barrier requirements for lock-free dereference.
  46. The fdtable pointer must be read within the read-side
  47. critical section.
  48. 2. Reading of the fdtable as described above must be protected
  49. by rcu_read_lock()/rcu_read_unlock().
  50. 3. For any update to the fd table, files->file_lock must
  51. be held.
  52. 4. To look up the file structure given an fd, a reader
  53. must use either fcheck() or fcheck_files() APIs. These
  54. take care of barrier requirements due to lock-free lookup.
  55. An example::
  56. struct file *file;
  57. rcu_read_lock();
  58. file = fcheck(fd);
  59. if (file) {
  60. ...
  61. }
  62. ....
  63. rcu_read_unlock();
  64. 5. Handling of the file structures is special. Since the look-up
  65. of the fd (fget()/fget_light()) are lock-free, it is possible
  66. that look-up may race with the last put() operation on the
  67. file structure. This is avoided using atomic_long_inc_not_zero()
  68. on ->f_count::
  69. rcu_read_lock();
  70. file = fcheck_files(files, fd);
  71. if (file) {
  72. if (atomic_long_inc_not_zero(&file->f_count))
  73. *fput_needed = 1;
  74. else
  75. /* Didn't get the reference, someone's freed */
  76. file = NULL;
  77. }
  78. rcu_read_unlock();
  79. ....
  80. return file;
  81. atomic_long_inc_not_zero() detects if refcounts is already zero or
  82. goes to zero during increment. If it does, we fail
  83. fget()/fget_light().
  84. 6. Since both fdtable and file structures can be looked up
  85. lock-free, they must be installed using rcu_assign_pointer()
  86. API. If they are looked up lock-free, rcu_dereference()
  87. must be used. However it is advisable to use files_fdtable()
  88. and fcheck()/fcheck_files() which take care of these issues.
  89. 7. While updating, the fdtable pointer must be looked up while
  90. holding files->file_lock. If ->file_lock is dropped, then
  91. another thread expand the files thereby creating a new
  92. fdtable and making the earlier fdtable pointer stale.
  93. For example::
  94. spin_lock(&files->file_lock);
  95. fd = locate_fd(files, file, start);
  96. if (fd >= 0) {
  97. /* locate_fd() may have expanded fdtable, load the ptr */
  98. fdt = files_fdtable(files);
  99. __set_open_fd(fd, fdt);
  100. __clear_close_on_exec(fd, fdt);
  101. spin_unlock(&files->file_lock);
  102. .....
  103. Since locate_fd() can drop ->file_lock (and reacquire ->file_lock),
  104. the fdtable pointer (fdt) must be loaded after locate_fd().