fs_struct.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include <linux/export.h>
  2. #include <linux/sched.h>
  3. #include <linux/fs.h>
  4. #include <linux/path.h>
  5. #include <linux/slab.h>
  6. #include <linux/fs_struct.h>
  7. #include "internal.h"
  8. /*
  9. * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
  10. * It can block.
  11. */
  12. void set_fs_root(struct fs_struct *fs, const struct path *path)
  13. {
  14. struct path old_root;
  15. path_get(path);
  16. spin_lock(&fs->lock);
  17. write_seqcount_begin(&fs->seq);
  18. old_root = fs->root;
  19. fs->root = *path;
  20. write_seqcount_end(&fs->seq);
  21. spin_unlock(&fs->lock);
  22. if (old_root.dentry)
  23. path_put(&old_root);
  24. }
  25. /*
  26. * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
  27. * It can block.
  28. */
  29. void set_fs_pwd(struct fs_struct *fs, const struct path *path)
  30. {
  31. struct path old_pwd;
  32. path_get(path);
  33. spin_lock(&fs->lock);
  34. write_seqcount_begin(&fs->seq);
  35. old_pwd = fs->pwd;
  36. fs->pwd = *path;
  37. write_seqcount_end(&fs->seq);
  38. spin_unlock(&fs->lock);
  39. if (old_pwd.dentry)
  40. path_put(&old_pwd);
  41. }
  42. static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
  43. {
  44. if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
  45. return 0;
  46. *p = *new;
  47. return 1;
  48. }
  49. void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
  50. {
  51. struct task_struct *g, *p;
  52. struct fs_struct *fs;
  53. int count = 0;
  54. read_lock(&tasklist_lock);
  55. do_each_thread(g, p) {
  56. task_lock(p);
  57. fs = p->fs;
  58. if (fs) {
  59. int hits = 0;
  60. spin_lock(&fs->lock);
  61. write_seqcount_begin(&fs->seq);
  62. hits += replace_path(&fs->root, old_root, new_root);
  63. hits += replace_path(&fs->pwd, old_root, new_root);
  64. write_seqcount_end(&fs->seq);
  65. while (hits--) {
  66. count++;
  67. path_get(new_root);
  68. }
  69. spin_unlock(&fs->lock);
  70. }
  71. task_unlock(p);
  72. } while_each_thread(g, p);
  73. read_unlock(&tasklist_lock);
  74. while (count--)
  75. path_put(old_root);
  76. }
  77. void free_fs_struct(struct fs_struct *fs)
  78. {
  79. path_put(&fs->root);
  80. path_put(&fs->pwd);
  81. kmem_cache_free(fs_cachep, fs);
  82. }
  83. void exit_fs(struct task_struct *tsk)
  84. {
  85. struct fs_struct *fs = tsk->fs;
  86. if (fs) {
  87. int kill;
  88. task_lock(tsk);
  89. spin_lock(&fs->lock);
  90. tsk->fs = NULL;
  91. kill = !--fs->users;
  92. spin_unlock(&fs->lock);
  93. task_unlock(tsk);
  94. if (kill)
  95. free_fs_struct(fs);
  96. }
  97. }
  98. struct fs_struct *copy_fs_struct(struct fs_struct *old)
  99. {
  100. struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
  101. /* We don't need to lock fs - think why ;-) */
  102. if (fs) {
  103. fs->users = 1;
  104. fs->in_exec = 0;
  105. spin_lock_init(&fs->lock);
  106. seqcount_init(&fs->seq);
  107. fs->umask = old->umask;
  108. spin_lock(&old->lock);
  109. fs->root = old->root;
  110. path_get(&fs->root);
  111. fs->pwd = old->pwd;
  112. path_get(&fs->pwd);
  113. spin_unlock(&old->lock);
  114. }
  115. return fs;
  116. }
  117. int unshare_fs_struct(void)
  118. {
  119. struct fs_struct *fs = current->fs;
  120. struct fs_struct *new_fs = copy_fs_struct(fs);
  121. int kill;
  122. if (!new_fs)
  123. return -ENOMEM;
  124. task_lock(current);
  125. spin_lock(&fs->lock);
  126. kill = !--fs->users;
  127. current->fs = new_fs;
  128. spin_unlock(&fs->lock);
  129. task_unlock(current);
  130. if (kill)
  131. free_fs_struct(fs);
  132. return 0;
  133. }
  134. EXPORT_SYMBOL_GPL(unshare_fs_struct);
  135. int current_umask(void)
  136. {
  137. return current->fs->umask;
  138. }
  139. EXPORT_SYMBOL(current_umask);
  140. /* to be mentioned only in INIT_TASK */
  141. struct fs_struct init_fs = {
  142. .users = 1,
  143. .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
  144. .seq = SEQCNT_ZERO(init_fs.seq),
  145. .umask = 0022,
  146. };