OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [namespace.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/fs/namespace.c
3
 *
4
 * (C) Copyright Al Viro 2000, 2001
5
 *      Released under GPL v2.
6
 *
7
 * Based on code from fs/super.c, copyright Linus Torvalds and others.
8
 * Heavily rewritten.
9
 */
10
 
11
#include <linux/config.h>
12
#include <linux/slab.h>
13
#include <linux/smp_lock.h>
14
#include <linux/init.h>
15
#include <linux/quotaops.h>
16
#include <linux/acct.h>
17
#include <linux/module.h>
18
 
19
#include <asm/uaccess.h>
20
 
21
#include <linux/seq_file.h>
22
#include <linux/namespace.h>
23
 
24
struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
25
int do_remount_sb(struct super_block *sb, int flags, void * data);
26
void kill_super(struct super_block *sb);
27
extern int __init init_rootfs(void);
28
 
29
static struct list_head *mount_hashtable;
30
static int hash_mask, hash_bits;
31
static kmem_cache_t *mnt_cache;
32
 
33
static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
34
{
35
        unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
36
        tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
37
        tmp = tmp + (tmp >> hash_bits);
38
        return tmp & hash_mask;
39
}
40
 
41
struct vfsmount *alloc_vfsmnt(char *name)
42
{
43
        struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
44
        if (mnt) {
45
                memset(mnt, 0, sizeof(struct vfsmount));
46
                atomic_set(&mnt->mnt_count,1);
47
                INIT_LIST_HEAD(&mnt->mnt_hash);
48
                INIT_LIST_HEAD(&mnt->mnt_child);
49
                INIT_LIST_HEAD(&mnt->mnt_mounts);
50
                INIT_LIST_HEAD(&mnt->mnt_list);
51
                if (name) {
52
                        int size = strlen(name)+1;
53
                        char * newname = kmalloc(size, GFP_KERNEL);
54
                        if (newname) {
55
                                memcpy(newname, name, size);
56
                                mnt->mnt_devname = newname;
57
                        }
58
                }
59
        }
60
        return mnt;
61
}
62
 
63
void free_vfsmnt(struct vfsmount *mnt)
64
{
65
        if (mnt->mnt_devname)
66
                kfree(mnt->mnt_devname);
67
        kmem_cache_free(mnt_cache, mnt);
68
}
69
 
70
struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
71
{
72
        struct list_head * head = mount_hashtable + hash(mnt, dentry);
73
        struct list_head * tmp = head;
74
        struct vfsmount *p;
75
 
76
        for (;;) {
77
                tmp = tmp->next;
78
                p = NULL;
79
                if (tmp == head)
80
                        break;
81
                p = list_entry(tmp, struct vfsmount, mnt_hash);
82
                if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry)
83
                        break;
84
        }
85
        return p;
86
}
87
 
88
static int check_mnt(struct vfsmount *mnt)
89
{
90
        spin_lock(&dcache_lock);
91
        while (mnt->mnt_parent != mnt)
92
                mnt = mnt->mnt_parent;
93
        spin_unlock(&dcache_lock);
94
        return mnt == current->namespace->root;
95
}
96
 
97
static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
98
{
99
        old_nd->dentry = mnt->mnt_mountpoint;
100
        old_nd->mnt = mnt->mnt_parent;
101
        mnt->mnt_parent = mnt;
102
        mnt->mnt_mountpoint = mnt->mnt_root;
103
        list_del_init(&mnt->mnt_child);
104
        list_del_init(&mnt->mnt_hash);
105
        old_nd->dentry->d_mounted--;
106
}
107
 
108
static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
109
{
110
        mnt->mnt_parent = mntget(nd->mnt);
111
        mnt->mnt_mountpoint = dget(nd->dentry);
112
        list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
113
        list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
114
        nd->dentry->d_mounted++;
115
}
116
 
117
static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root)
118
{
119
        struct list_head *next = p->mnt_mounts.next;
120
        if (next == &p->mnt_mounts) {
121
                while (1) {
122
                        if (p == root)
123
                                return NULL;
124
                        next = p->mnt_child.next;
125
                        if (next != &p->mnt_parent->mnt_mounts)
126
                                break;
127
                        p = p->mnt_parent;
128
                }
129
        }
130
        return list_entry(next, struct vfsmount, mnt_child);
131
}
132
 
133
static struct vfsmount *
134
clone_mnt(struct vfsmount *old, struct dentry *root)
135
{
136
        struct super_block *sb = old->mnt_sb;
137
        struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
138
 
139
        if (mnt) {
140
                mnt->mnt_flags = old->mnt_flags;
141
                atomic_inc(&sb->s_active);
142
                mnt->mnt_sb = sb;
143
                mnt->mnt_root = dget(root);
144
                mnt->mnt_mountpoint = mnt->mnt_root;
145
                mnt->mnt_parent = mnt;
146
        }
147
        return mnt;
148
}
149
 
150
void __mntput(struct vfsmount *mnt)
151
{
152
        struct super_block *sb = mnt->mnt_sb;
153
        dput(mnt->mnt_root);
154
        free_vfsmnt(mnt);
155
        kill_super(sb);
156
}
157
 
158
/* iterator */
159
static void *m_start(struct seq_file *m, loff_t *pos)
160
{
161
        struct namespace *n = m->private;
162
        struct list_head *p;
163
        loff_t l = *pos;
164
 
165
        down_read(&n->sem);
166
        list_for_each(p, &n->list)
167
                if (!l--)
168
                        return list_entry(p, struct vfsmount, mnt_list);
169
        return NULL;
170
}
171
 
172
static void *m_next(struct seq_file *m, void *v, loff_t *pos)
173
{
174
        struct namespace *n = m->private;
175
        struct list_head *p = ((struct vfsmount *)v)->mnt_list.next;
176
        (*pos)++;
177
        return p==&n->list ? NULL : list_entry(p, struct vfsmount, mnt_list);
178
}
179
 
180
static void m_stop(struct seq_file *m, void *v)
181
{
182
        struct namespace *n = m->private;
183
        up_read(&n->sem);
184
}
185
 
186
static inline void mangle(struct seq_file *m, const char *s)
187
{
188
        seq_escape(m, s, " \t\n\\");
189
}
190
 
191
static int show_vfsmnt(struct seq_file *m, void *v)
192
{
193
        struct vfsmount *mnt = v;
194
        int err = 0;
195
        static struct proc_fs_info {
196
                int flag;
197
                char *str;
198
        } fs_info[] = {
199
                { MS_SYNCHRONOUS, ",sync" },
200
                { MS_MANDLOCK, ",mand" },
201
                { MS_NOATIME, ",noatime" },
202
                { MS_NODIRATIME, ",nodiratime" },
203
                { 0, NULL }
204
        };
205
        static struct proc_fs_info mnt_info[] = {
206
                { MNT_NOSUID, ",nosuid" },
207
                { MNT_NODEV, ",nodev" },
208
                { MNT_NOEXEC, ",noexec" },
209
                { 0, NULL }
210
        };
211
        struct proc_fs_info *fs_infop;
212
        char *path_buf, *path;
213
 
214
        path_buf = (char *) __get_free_page(GFP_KERNEL);
215
        if (!path_buf)
216
                return -ENOMEM;
217
        path = d_path(mnt->mnt_root, mnt, path_buf, PAGE_SIZE);
218
        if (IS_ERR(path)) {
219
                free_page((unsigned long) path_buf);
220
                return PTR_ERR(path);
221
        }
222
 
223
        mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
224
        seq_putc(m, ' ');
225
        mangle(m, path);
226
        free_page((unsigned long) path_buf);
227
        seq_putc(m, ' ');
228
        mangle(m, mnt->mnt_sb->s_type->name);
229
        seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
230
        for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
231
                if (mnt->mnt_sb->s_flags & fs_infop->flag)
232
                        seq_puts(m, fs_infop->str);
233
        }
234
        for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
235
                if (mnt->mnt_flags & fs_infop->flag)
236
                        seq_puts(m, fs_infop->str);
237
        }
238
        if (mnt->mnt_sb->s_op->show_options)
239
                err = mnt->mnt_sb->s_op->show_options(m, mnt);
240
        seq_puts(m, " 0 0\n");
241
        return err;
242
}
243
 
244
struct seq_operations mounts_op = {
245
        start:  m_start,
246
        next:   m_next,
247
        stop:   m_stop,
248
        show:   show_vfsmnt
249
};
250
 
251
/*
252
 * Doesn't take quota and stuff into account. IOW, in some cases it will
253
 * give false negatives. The main reason why it's here is that we need
254
 * a non-destructive way to look for easily umountable filesystems.
255
 */
256
int may_umount(struct vfsmount *mnt)
257
{
258
        if (atomic_read(&mnt->mnt_count) > 2)
259
                return -EBUSY;
260
        return 0;
261
}
262
 
263
void umount_tree(struct vfsmount *mnt)
264
{
265
        struct vfsmount *p;
266
        LIST_HEAD(kill);
267
 
268
        for (p = mnt; p; p = next_mnt(p, mnt)) {
269
                list_del(&p->mnt_list);
270
                list_add(&p->mnt_list, &kill);
271
        }
272
 
273
        while (!list_empty(&kill)) {
274
                mnt = list_entry(kill.next, struct vfsmount, mnt_list);
275
                list_del_init(&mnt->mnt_list);
276
                if (mnt->mnt_parent == mnt) {
277
                        spin_unlock(&dcache_lock);
278
                } else {
279
                        struct nameidata old_nd;
280
                        detach_mnt(mnt, &old_nd);
281
                        spin_unlock(&dcache_lock);
282
                        path_release(&old_nd);
283
                }
284
                mntput(mnt);
285
                spin_lock(&dcache_lock);
286
        }
287
}
288
 
289
static int do_umount(struct vfsmount *mnt, int flags)
290
{
291
        struct super_block * sb = mnt->mnt_sb;
292
        int retval = 0;
293
 
294
        /*
295
         * If we may have to abort operations to get out of this
296
         * mount, and they will themselves hold resources we must
297
         * allow the fs to do things. In the Unix tradition of
298
         * 'Gee thats tricky lets do it in userspace' the umount_begin
299
         * might fail to complete on the first run through as other tasks
300
         * must return, and the like. Thats for the mount program to worry
301
         * about for the moment.
302
         */
303
 
304
        lock_kernel();
305
        if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
306
                sb->s_op->umount_begin(sb);
307
        unlock_kernel();
308
 
309
        /*
310
         * No sense to grab the lock for this test, but test itself looks
311
         * somewhat bogus. Suggestions for better replacement?
312
         * Ho-hum... In principle, we might treat that as umount + switch
313
         * to rootfs. GC would eventually take care of the old vfsmount.
314
         * Actually it makes sense, especially if rootfs would contain a
315
         * /reboot - static binary that would close all descriptors and
316
         * call reboot(9). Then init(8) could umount root and exec /reboot.
317
         */
318
        if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
319
                /*
320
                 * Special case for "unmounting" root ...
321
                 * we just try to remount it readonly.
322
                 */
323
                down_write(&sb->s_umount);
324
                if (!(sb->s_flags & MS_RDONLY)) {
325
                        lock_kernel();
326
                        retval = do_remount_sb(sb, MS_RDONLY, 0);
327
                        unlock_kernel();
328
                }
329
                up_write(&sb->s_umount);
330
                return retval;
331
        }
332
 
333
        down_write(&current->namespace->sem);
334
        spin_lock(&dcache_lock);
335
 
336
        if (atomic_read(&sb->s_active) == 1) {
337
                /* last instance - try to be smart */
338
                spin_unlock(&dcache_lock);
339
                lock_kernel();
340
                DQUOT_OFF(sb);
341
                acct_auto_close(sb->s_dev);
342
                unlock_kernel();
343
                spin_lock(&dcache_lock);
344
        }
345
        retval = -EBUSY;
346
        if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
347
                if (!list_empty(&mnt->mnt_list))
348
                        umount_tree(mnt);
349
                retval = 0;
350
        }
351
        spin_unlock(&dcache_lock);
352
        up_write(&current->namespace->sem);
353
        return retval;
354
}
355
 
356
/*
357
 * Now umount can handle mount points as well as block devices.
358
 * This is important for filesystems which use unnamed block devices.
359
 *
360
 * We now support a flag for forced unmount like the other 'big iron'
361
 * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
362
 */
363
 
364
asmlinkage long sys_umount(char * name, int flags)
365
{
366
        struct nameidata nd;
367
        int retval;
368
 
369
        retval = __user_walk(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd);
370
        if (retval)
371
                goto out;
372
        retval = -EINVAL;
373
        if (nd.dentry != nd.mnt->mnt_root)
374
                goto dput_and_out;
375
        if (!check_mnt(nd.mnt))
376
                goto dput_and_out;
377
 
378
        retval = -EPERM;
379
        if (!capable(CAP_SYS_ADMIN))
380
                goto dput_and_out;
381
 
382
        retval = do_umount(nd.mnt, flags);
383
dput_and_out:
384
        path_release(&nd);
385
out:
386
        return retval;
387
}
388
 
389
/*
390
 *      The 2.0 compatible umount. No flags.
391
 */
392
 
393
asmlinkage long sys_oldumount(char * name)
394
{
395
        return sys_umount(name,0);
396
}
397
 
398
static int mount_is_safe(struct nameidata *nd)
399
{
400
        if (capable(CAP_SYS_ADMIN))
401
                return 0;
402
        return -EPERM;
403
#ifdef notyet
404
        if (S_ISLNK(nd->dentry->d_inode->i_mode))
405
                return -EPERM;
406
        if (nd->dentry->d_inode->i_mode & S_ISVTX) {
407
                if (current->uid != nd->dentry->d_inode->i_uid)
408
                        return -EPERM;
409
        }
410
        if (permission(nd->dentry->d_inode, MAY_WRITE))
411
                return -EPERM;
412
        return 0;
413
#endif
414
}
415
 
416
static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
417
{
418
        struct vfsmount *p, *next, *q, *res;
419
        struct nameidata nd;
420
 
421
        p = mnt;
422
        res = nd.mnt = q = clone_mnt(p, dentry);
423
        if (!q)
424
                goto Enomem;
425
        q->mnt_parent = q;
426
        q->mnt_mountpoint = p->mnt_mountpoint;
427
 
428
        while ( (next = next_mnt(p, mnt)) != NULL) {
429
                while (p != next->mnt_parent) {
430
                        p = p->mnt_parent;
431
                        q = q->mnt_parent;
432
                }
433
                p = next;
434
                nd.mnt = q;
435
                nd.dentry = p->mnt_mountpoint;
436
                q = clone_mnt(p, p->mnt_root);
437
                if (!q)
438
                        goto Enomem;
439
                spin_lock(&dcache_lock);
440
                list_add_tail(&q->mnt_list, &res->mnt_list);
441
                attach_mnt(q, &nd);
442
                spin_unlock(&dcache_lock);
443
        }
444
        return res;
445
Enomem:
446
        if (res) {
447
                spin_lock(&dcache_lock);
448
                umount_tree(res);
449
                spin_unlock(&dcache_lock);
450
        }
451
        return NULL;
452
}
453
 
454
static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
455
{
456
        int err;
457
        if (mnt->mnt_sb->s_flags & MS_NOUSER)
458
                return -EINVAL;
459
 
460
        if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
461
              S_ISDIR(mnt->mnt_root->d_inode->i_mode))
462
                return -ENOTDIR;
463
 
464
        err = -ENOENT;
465
        down(&nd->dentry->d_inode->i_zombie);
466
        if (IS_DEADDIR(nd->dentry->d_inode))
467
                goto out_unlock;
468
 
469
        spin_lock(&dcache_lock);
470
        if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) {
471
                struct list_head head;
472
                attach_mnt(mnt, nd);
473
                list_add_tail(&head, &mnt->mnt_list);
474
                list_splice(&head, current->namespace->list.prev);
475
                mntget(mnt);
476
                err = 0;
477
        }
478
        spin_unlock(&dcache_lock);
479
out_unlock:
480
        up(&nd->dentry->d_inode->i_zombie);
481
        return err;
482
}
483
 
484
/*
485
 * do loopback mount.
486
 */
487
static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
488
{
489
        struct nameidata old_nd;
490
        struct vfsmount *mnt = NULL;
491
        int err = mount_is_safe(nd);
492
        if (err)
493
                return err;
494
        if (!old_name || !*old_name)
495
                return -EINVAL;
496
        err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
497
        if (err)
498
                return err;
499
 
500
        down_write(&current->namespace->sem);
501
        err = -EINVAL;
502
        if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
503
                err = -ENOMEM;
504
                if (recurse)
505
                        mnt = copy_tree(old_nd.mnt, old_nd.dentry);
506
                else
507
                        mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
508
        }
509
 
510
        if (mnt) {
511
                err = graft_tree(mnt, nd);
512
                if (err) {
513
                        spin_lock(&dcache_lock);
514
                        umount_tree(mnt);
515
                        spin_unlock(&dcache_lock);
516
                } else
517
                        mntput(mnt);
518
        }
519
 
520
        up_write(&current->namespace->sem);
521
        path_release(&old_nd);
522
        return err;
523
}
524
 
525
/*
526
 * change filesystem flags. dir should be a physical root of filesystem.
527
 * If you've mounted a non-root directory somewhere and want to do remount
528
 * on it - tough luck.
529
 */
530
 
531
static int do_remount(struct nameidata *nd,int flags,int mnt_flags,void *data)
532
{
533
        int err;
534
        struct super_block * sb = nd->mnt->mnt_sb;
535
 
536
        if (!capable(CAP_SYS_ADMIN))
537
                return -EPERM;
538
 
539
        if (!check_mnt(nd->mnt))
540
                return -EINVAL;
541
 
542
        if (nd->dentry != nd->mnt->mnt_root)
543
                return -EINVAL;
544
 
545
        down_write(&sb->s_umount);
546
        err = do_remount_sb(sb, flags, data);
547
        if (!err)
548
                nd->mnt->mnt_flags=mnt_flags;
549
        up_write(&sb->s_umount);
550
        return err;
551
}
552
 
553
static int do_move_mount(struct nameidata *nd, char *old_name)
554
{
555
        struct nameidata old_nd, parent_nd;
556
        struct vfsmount *p;
557
        int err = 0;
558
        if (!capable(CAP_SYS_ADMIN))
559
                return -EPERM;
560
        if (!old_name || !*old_name)
561
                return -EINVAL;
562
        err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
563
        if (err)
564
                return err;
565
 
566
        down_write(&current->namespace->sem);
567
        while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
568
                ;
569
        err = -EINVAL;
570
        if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
571
                goto out;
572
 
573
        err = -ENOENT;
574
        down(&nd->dentry->d_inode->i_zombie);
575
        if (IS_DEADDIR(nd->dentry->d_inode))
576
                goto out1;
577
 
578
        spin_lock(&dcache_lock);
579
        if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
580
                goto out2;
581
 
582
        err = -EINVAL;
583
        if (old_nd.dentry != old_nd.mnt->mnt_root)
584
                goto out2;
585
 
586
        if (old_nd.mnt == old_nd.mnt->mnt_parent)
587
                goto out2;
588
 
589
        if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
590
              S_ISDIR(old_nd.dentry->d_inode->i_mode))
591
                goto out2;
592
 
593
        err = -ELOOP;
594
        for (p = nd->mnt; p->mnt_parent!=p; p = p->mnt_parent)
595
                if (p == old_nd.mnt)
596
                        goto out2;
597
        err = 0;
598
 
599
        detach_mnt(old_nd.mnt, &parent_nd);
600
        attach_mnt(old_nd.mnt, nd);
601
out2:
602
        spin_unlock(&dcache_lock);
603
out1:
604
        up(&nd->dentry->d_inode->i_zombie);
605
out:
606
        up_write(&current->namespace->sem);
607
        if (!err)
608
                path_release(&parent_nd);
609
        path_release(&old_nd);
610
        return err;
611
}
612
 
613
static int do_add_mount(struct nameidata *nd, char *type, int flags,
614
                        int mnt_flags, char *name, void *data)
615
{
616
        struct vfsmount *mnt;
617
        int err;
618
 
619
        if (!type || !memchr(type, 0, PAGE_SIZE))
620
                return -EINVAL;
621
 
622
        /* we need capabilities... */
623
        if (!capable(CAP_SYS_ADMIN))
624
                return -EPERM;
625
 
626
        mnt = do_kern_mount(type, flags, name, data);
627
        err = PTR_ERR(mnt);
628
        if (IS_ERR(mnt))
629
                goto out;
630
 
631
        down_write(&current->namespace->sem);
632
        /* Something was mounted here while we slept */
633
        while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
634
                ;
635
        err = -EINVAL;
636
        if (!check_mnt(nd->mnt))
637
                goto unlock;
638
 
639
        /* Refuse the same filesystem on the same mount point */
640
        err = -EBUSY;
641
        if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
642
                goto unlock;
643
 
644
        mnt->mnt_flags = mnt_flags;
645
        err = graft_tree(mnt, nd);
646
unlock:
647
        up_write(&current->namespace->sem);
648
        mntput(mnt);
649
out:
650
        return err;
651
}
652
 
653
static int copy_mount_options (const void *data, unsigned long *where)
654
{
655
        int i;
656
        unsigned long page;
657
        unsigned long size;
658
 
659
        *where = 0;
660
        if (!data)
661
                return 0;
662
 
663
        if (!(page = __get_free_page(GFP_KERNEL)))
664
                return -ENOMEM;
665
 
666
        /* We only care that *some* data at the address the user
667
         * gave us is valid.  Just in case, we'll zero
668
         * the remainder of the page.
669
         */
670
        /* copy_from_user cannot cross TASK_SIZE ! */
671
        size = TASK_SIZE - (unsigned long)data;
672
        if (size > PAGE_SIZE)
673
                size = PAGE_SIZE;
674
 
675
        i = size - copy_from_user((void *)page, data, size);
676
        if (!i) {
677
                free_page(page);
678
                return -EFAULT;
679
        }
680
        if (i != PAGE_SIZE)
681
                memset((char *)page + i, 0, PAGE_SIZE - i);
682
        *where = page;
683
        return 0;
684
}
685
 
686
/*
687
 * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
688
 * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
689
 *
690
 * data is a (void *) that can point to any structure up to
691
 * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
692
 * information (or be NULL).
693
 *
694
 * Pre-0.97 versions of mount() didn't have a flags word.
695
 * When the flags word was introduced its top half was required
696
 * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
697
 * Therefore, if this magic number is present, it carries no information
698
 * and must be discarded.
699
 */
700
long do_mount(char * dev_name, char * dir_name, char *type_page,
701
                  unsigned long flags, void *data_page)
702
{
703
        struct nameidata nd;
704
        int retval = 0;
705
        int mnt_flags = 0;
706
 
707
        /* Discard magic */
708
        if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
709
                flags &= ~MS_MGC_MSK;
710
 
711
        /* Basic sanity checks */
712
 
713
        if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))
714
                return -EINVAL;
715
        if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
716
                return -EINVAL;
717
 
718
        if (data_page)
719
                ((char *)data_page)[PAGE_SIZE - 1] = 0;
720
 
721
        /* Separate the per-mountpoint flags */
722
        if (flags & MS_NOSUID)
723
                mnt_flags |= MNT_NOSUID;
724
        if (flags & MS_NODEV)
725
                mnt_flags |= MNT_NODEV;
726
        if (flags & MS_NOEXEC)
727
                mnt_flags |= MNT_NOEXEC;
728
        flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
729
 
730
        /* ... and get the mountpoint */
731
        retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
732
        if (retval)
733
                return retval;
734
 
735
        if (flags & MS_REMOUNT)
736
                retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
737
                                    data_page);
738
        else if (flags & MS_BIND)
739
                retval = do_loopback(&nd, dev_name, flags & MS_REC);
740
        else if (flags & MS_MOVE)
741
                retval = do_move_mount(&nd, dev_name);
742
        else
743
                retval = do_add_mount(&nd, type_page, flags, mnt_flags,
744
                                      dev_name, data_page);
745
        path_release(&nd);
746
        return retval;
747
}
748
 
749
int copy_namespace(int flags, struct task_struct *tsk)
750
{
751
        struct namespace *namespace = tsk->namespace;
752
        struct namespace *new_ns;
753
        struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
754
        struct fs_struct *fs = tsk->fs;
755
 
756
        if (!namespace)
757
                return 0;
758
 
759
        get_namespace(namespace);
760
 
761
        if (! (flags & CLONE_NEWNS))
762
                return 0;
763
 
764
        if (!capable(CAP_SYS_ADMIN)) {
765
                put_namespace(namespace);
766
                return -EPERM;
767
        }
768
 
769
        new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
770
        if (!new_ns)
771
                goto out;
772
 
773
        atomic_set(&new_ns->count, 1);
774
        init_rwsem(&new_ns->sem);
775
        new_ns->root = NULL;
776
        INIT_LIST_HEAD(&new_ns->list);
777
 
778
        down_write(&tsk->namespace->sem);
779
        /* First pass: copy the tree topology */
780
        new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
781
        spin_lock(&dcache_lock);
782
        list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
783
        spin_unlock(&dcache_lock);
784
 
785
        /* Second pass: switch the tsk->fs->* elements */
786
        if (fs) {
787
                struct vfsmount *p, *q;
788
                write_lock(&fs->lock);
789
 
790
                p = namespace->root;
791
                q = new_ns->root;
792
                while (p) {
793
                        if (p == fs->rootmnt) {
794
                                rootmnt = p;
795
                                fs->rootmnt = mntget(q);
796
                        }
797
                        if (p == fs->pwdmnt) {
798
                                pwdmnt = p;
799
                                fs->pwdmnt = mntget(q);
800
                        }
801
                        if (p == fs->altrootmnt) {
802
                                altrootmnt = p;
803
                                fs->altrootmnt = mntget(q);
804
                        }
805
                        p = next_mnt(p, namespace->root);
806
                        q = next_mnt(q, new_ns->root);
807
                }
808
                write_unlock(&fs->lock);
809
        }
810
        up_write(&tsk->namespace->sem);
811
 
812
        tsk->namespace = new_ns;
813
 
814
        if (rootmnt)
815
                mntput(rootmnt);
816
        if (pwdmnt)
817
                mntput(pwdmnt);
818
        if (altrootmnt)
819
                mntput(altrootmnt);
820
 
821
        put_namespace(namespace);
822
        return 0;
823
 
824
out:
825
        put_namespace(namespace);
826
        return -ENOMEM;
827
}
828
 
829
asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
830
                          unsigned long flags, void * data)
831
{
832
        int retval;
833
        unsigned long data_page;
834
        unsigned long type_page;
835
        unsigned long dev_page;
836
        char *dir_page;
837
 
838
        retval = copy_mount_options (type, &type_page);
839
        if (retval < 0)
840
                return retval;
841
 
842
        dir_page = getname(dir_name);
843
        retval = PTR_ERR(dir_page);
844
        if (IS_ERR(dir_page))
845
                goto out1;
846
 
847
        retval = copy_mount_options (dev_name, &dev_page);
848
        if (retval < 0)
849
                goto out2;
850
 
851
        retval = copy_mount_options (data, &data_page);
852
        if (retval < 0)
853
                goto out3;
854
 
855
        lock_kernel();
856
        retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
857
                          flags, (void*)data_page);
858
        unlock_kernel();
859
        free_page(data_page);
860
 
861
out3:
862
        free_page(dev_page);
863
out2:
864
        putname(dir_page);
865
out1:
866
        free_page(type_page);
867
        return retval;
868
}
869
 
870
static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
871
{
872
        struct task_struct *p;
873
        struct fs_struct *fs;
874
 
875
        read_lock(&tasklist_lock);
876
        for_each_task(p) {
877
                task_lock(p);
878
                fs = p->fs;
879
                if (fs) {
880
                        atomic_inc(&fs->count);
881
                        task_unlock(p);
882
                        if (fs->root==old_nd->dentry&&fs->rootmnt==old_nd->mnt)
883
                                set_fs_root(fs, new_nd->mnt, new_nd->dentry);
884
                        if (fs->pwd==old_nd->dentry&&fs->pwdmnt==old_nd->mnt)
885
                                set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
886
                        put_fs_struct(fs);
887
                } else
888
                        task_unlock(p);
889
        }
890
        read_unlock(&tasklist_lock);
891
}
892
 
893
/*
894
 * Moves the current root to put_root, and sets root/cwd of all processes
895
 * which had them on the old root to new_root.
896
 *
897
 * Note:
898
 *  - we don't move root/cwd if they are not at the root (reason: if something
899
 *    cared enough to change them, it's probably wrong to force them elsewhere)
900
 *  - it's okay to pick a root that isn't the root of a file system, e.g.
901
 *    /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
902
 *    though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
903
 *    first.
904
 */
905
 
906
asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
907
{
908
        struct vfsmount *tmp;
909
        struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
910
        int error;
911
 
912
        if (!capable(CAP_SYS_ADMIN))
913
                return -EPERM;
914
 
915
        lock_kernel();
916
 
917
        error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
918
        if (error)
919
                goto out0;
920
        error = -EINVAL;
921
        if (!check_mnt(new_nd.mnt))
922
                goto out1;
923
 
924
        error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
925
        if (error)
926
                goto out1;
927
 
928
        read_lock(&current->fs->lock);
929
        user_nd.mnt = mntget(current->fs->rootmnt);
930
        user_nd.dentry = dget(current->fs->root);
931
        read_unlock(&current->fs->lock);
932
        down_write(&current->namespace->sem);
933
        down(&old_nd.dentry->d_inode->i_zombie);
934
        error = -EINVAL;
935
        if (!check_mnt(user_nd.mnt))
936
                goto out2;
937
        error = -ENOENT;
938
        if (IS_DEADDIR(new_nd.dentry->d_inode))
939
                goto out2;
940
        if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
941
                goto out2;
942
        if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
943
                goto out2;
944
        error = -EBUSY;
945
        if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
946
                goto out2; /* loop */
947
        error = -EINVAL;
948
        if (user_nd.mnt->mnt_root != user_nd.dentry)
949
                goto out2;
950
        if (new_nd.mnt->mnt_root != new_nd.dentry)
951
                goto out2; /* not a mountpoint */
952
        tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
953
        spin_lock(&dcache_lock);
954
        if (tmp != new_nd.mnt) {
955
                for (;;) {
956
                        if (tmp->mnt_parent == tmp)
957
                                goto out3;
958
                        if (tmp->mnt_parent == new_nd.mnt)
959
                                break;
960
                        tmp = tmp->mnt_parent;
961
                }
962
                if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
963
                        goto out3;
964
        } else if (!is_subdir(old_nd.dentry, new_nd.dentry))
965
                goto out3;
966
        detach_mnt(new_nd.mnt, &parent_nd);
967
        detach_mnt(user_nd.mnt, &root_parent);
968
        attach_mnt(user_nd.mnt, &old_nd);
969
        attach_mnt(new_nd.mnt, &root_parent);
970
        spin_unlock(&dcache_lock);
971
        chroot_fs_refs(&user_nd, &new_nd);
972
        error = 0;
973
        path_release(&root_parent);
974
        path_release(&parent_nd);
975
out2:
976
        up(&old_nd.dentry->d_inode->i_zombie);
977
        up_write(&current->namespace->sem);
978
        path_release(&user_nd);
979
        path_release(&old_nd);
980
out1:
981
        path_release(&new_nd);
982
out0:
983
        unlock_kernel();
984
        return error;
985
out3:
986
        spin_unlock(&dcache_lock);
987
        goto out2;
988
}
989
 
990
static void __init init_mount_tree(void)
991
{
992
        struct vfsmount *mnt;
993
        struct namespace *namespace;
994
        struct task_struct *p;
995
 
996
        mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
997
        if (IS_ERR(mnt))
998
                panic("Can't create rootfs");
999
        namespace = kmalloc(sizeof(*namespace), GFP_KERNEL);
1000
        if (!namespace)
1001
                panic("Can't allocate initial namespace");
1002
        atomic_set(&namespace->count, 1);
1003
        INIT_LIST_HEAD(&namespace->list);
1004
        init_rwsem(&namespace->sem);
1005
        list_add(&mnt->mnt_list, &namespace->list);
1006
        namespace->root = mnt;
1007
 
1008
        init_task.namespace = namespace;
1009
        read_lock(&tasklist_lock);
1010
        for_each_task(p) {
1011
                get_namespace(namespace);
1012
                p->namespace = namespace;
1013
        }
1014
        read_unlock(&tasklist_lock);
1015
 
1016
        set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
1017
        set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
1018
}
1019
 
1020
void __init mnt_init(unsigned long mempages)
1021
{
1022
        struct list_head *d;
1023
        unsigned long order;
1024
        unsigned int nr_hash;
1025
        int i;
1026
 
1027
        mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
1028
                                        0, SLAB_HWCACHE_ALIGN, NULL, NULL);
1029
        if (!mnt_cache)
1030
                panic("Cannot create vfsmount cache");
1031
 
1032
        /* using single pointer list heads would save half of the hash table. */
1033
        order = 0;
1034
        mount_hashtable = (struct list_head *)
1035
                __get_free_pages(GFP_ATOMIC, order);
1036
 
1037
        if (!mount_hashtable)
1038
                panic("Failed to allocate mount hash table\n");
1039
 
1040
        /*
1041
         * Find the power-of-two list-heads that can fit into the allocation..
1042
         * We don't guarantee that "sizeof(struct list_head)" is necessarily
1043
         * a power-of-two.
1044
         */
1045
        nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct list_head);
1046
        hash_bits = 0;
1047
        do {
1048
                hash_bits++;
1049
        } while ((nr_hash >> hash_bits) != 0);
1050
        hash_bits--;
1051
 
1052
        /*
1053
         * Re-calculate the actual number of entries and the mask
1054
         * from the number of bits we can fit.
1055
         */
1056
        nr_hash = 1UL << hash_bits;
1057
        hash_mask = nr_hash-1;
1058
 
1059
        printk(KERN_INFO "Mount cache hash table entries: %d"
1060
                " (order: %ld, %ld bytes)\n",
1061
                nr_hash, order, (PAGE_SIZE << order));
1062
 
1063
        /* And initialize the newly allocated array */
1064
        d = mount_hashtable;
1065
        i = nr_hash;
1066
        do {
1067
                INIT_LIST_HEAD(d);
1068
                d++;
1069
                i--;
1070
        } while (i);
1071
        init_rootfs();
1072
        init_mount_tree();
1073
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.