LCOV - code coverage report
Current view: top level - fs - fs_struct.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 31 66 47.0 %
Date: 2014-02-18 Functions: 6 8 75.0 %
Branches: 6 31 19.4 %

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

Generated by: LCOV version 1.9