Back to home page

LXR

 
 

    


0001 #include <linux/export.h>
0002 #include <linux/sched.h>
0003 #include <linux/fs.h>
0004 #include <linux/path.h>
0005 #include <linux/slab.h>
0006 #include <linux/fs_struct.h>
0007 #include "internal.h"
0008 
0009 /*
0010  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
0011  * It can block.
0012  */
0013 void set_fs_root(struct fs_struct *fs, const struct path *path)
0014 {
0015     struct path old_root;
0016 
0017     path_get(path);
0018     spin_lock(&fs->lock);
0019     write_seqcount_begin(&fs->seq);
0020     old_root = fs->root;
0021     fs->root = *path;
0022     write_seqcount_end(&fs->seq);
0023     spin_unlock(&fs->lock);
0024     if (old_root.dentry)
0025         path_put(&old_root);
0026 }
0027 
0028 /*
0029  * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
0030  * It can block.
0031  */
0032 void set_fs_pwd(struct fs_struct *fs, const struct path *path)
0033 {
0034     struct path old_pwd;
0035 
0036     path_get(path);
0037     spin_lock(&fs->lock);
0038     write_seqcount_begin(&fs->seq);
0039     old_pwd = fs->pwd;
0040     fs->pwd = *path;
0041     write_seqcount_end(&fs->seq);
0042     spin_unlock(&fs->lock);
0043 
0044     if (old_pwd.dentry)
0045         path_put(&old_pwd);
0046 }
0047 
0048 static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
0049 {
0050     if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
0051         return 0;
0052     *p = *new;
0053     return 1;
0054 }
0055 
0056 void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
0057 {
0058     struct task_struct *g, *p;
0059     struct fs_struct *fs;
0060     int count = 0;
0061 
0062     read_lock(&tasklist_lock);
0063     do_each_thread(g, p) {
0064         task_lock(p);
0065         fs = p->fs;
0066         if (fs) {
0067             int hits = 0;
0068             spin_lock(&fs->lock);
0069             write_seqcount_begin(&fs->seq);
0070             hits += replace_path(&fs->root, old_root, new_root);
0071             hits += replace_path(&fs->pwd, old_root, new_root);
0072             write_seqcount_end(&fs->seq);
0073             while (hits--) {
0074                 count++;
0075                 path_get(new_root);
0076             }
0077             spin_unlock(&fs->lock);
0078         }
0079         task_unlock(p);
0080     } while_each_thread(g, p);
0081     read_unlock(&tasklist_lock);
0082     while (count--)
0083         path_put(old_root);
0084 }
0085 
0086 void free_fs_struct(struct fs_struct *fs)
0087 {
0088     path_put(&fs->root);
0089     path_put(&fs->pwd);
0090     kmem_cache_free(fs_cachep, fs);
0091 }
0092 
0093 void exit_fs(struct task_struct *tsk)
0094 {
0095     struct fs_struct *fs = tsk->fs;
0096 
0097     if (fs) {
0098         int kill;
0099         task_lock(tsk);
0100         spin_lock(&fs->lock);
0101         tsk->fs = NULL;
0102         kill = !--fs->users;
0103         spin_unlock(&fs->lock);
0104         task_unlock(tsk);
0105         if (kill)
0106             free_fs_struct(fs);
0107     }
0108 }
0109 
0110 struct fs_struct *copy_fs_struct(struct fs_struct *old)
0111 {
0112     struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
0113     /* We don't need to lock fs - think why ;-) */
0114     if (fs) {
0115         fs->users = 1;
0116         fs->in_exec = 0;
0117         spin_lock_init(&fs->lock);
0118         seqcount_init(&fs->seq);
0119         fs->umask = old->umask;
0120 
0121         spin_lock(&old->lock);
0122         fs->root = old->root;
0123         path_get(&fs->root);
0124         fs->pwd = old->pwd;
0125         path_get(&fs->pwd);
0126         spin_unlock(&old->lock);
0127     }
0128     return fs;
0129 }
0130 
0131 int unshare_fs_struct(void)
0132 {
0133     struct fs_struct *fs = current->fs;
0134     struct fs_struct *new_fs = copy_fs_struct(fs);
0135     int kill;
0136 
0137     if (!new_fs)
0138         return -ENOMEM;
0139 
0140     task_lock(current);
0141     spin_lock(&fs->lock);
0142     kill = !--fs->users;
0143     current->fs = new_fs;
0144     spin_unlock(&fs->lock);
0145     task_unlock(current);
0146 
0147     if (kill)
0148         free_fs_struct(fs);
0149 
0150     return 0;
0151 }
0152 EXPORT_SYMBOL_GPL(unshare_fs_struct);
0153 
0154 int current_umask(void)
0155 {
0156     return current->fs->umask;
0157 }
0158 EXPORT_SYMBOL(current_umask);
0159 
0160 /* to be mentioned only in INIT_TASK */
0161 struct fs_struct init_fs = {
0162     .users      = 1,
0163     .lock       = __SPIN_LOCK_UNLOCKED(init_fs.lock),
0164     .seq        = SEQCNT_ZERO(init_fs.seq),
0165     .umask      = 0022,
0166 };