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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* -*- linux-c -*- --------------------------------------------------------- *
2
 *
3
 * linux/fs/autofs/inode.c
4
 *
5
 *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6
 *
7
 * This file is part of the Linux kernel and is made available under
8
 * the terms of the GNU General Public License, version 2, or at your
9
 * option, any later version, incorporated herein by reference.
10
 *
11
 * ------------------------------------------------------------------------- */
12
 
13
#include <linux/kernel.h>
14
#include <linux/slab.h>
15
#include <linux/file.h>
16
#include <linux/locks.h>
17
#include <asm/bitops.h>
18
#include "autofs_i.h"
19
#define __NO_VERSION__
20
#include <linux/module.h>
21
 
22
static void autofs_put_super(struct super_block *sb)
23
{
24
        struct autofs_sb_info *sbi = autofs_sbi(sb);
25
        unsigned int n;
26
 
27
        if ( !sbi->catatonic )
28
                autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
29
 
30
        autofs_hash_nuke(&sbi->dirhash);
31
        for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
32
                if ( test_bit(n, sbi->symlink_bitmap) )
33
                        kfree(sbi->symlink[n].data);
34
        }
35
 
36
        kfree(sb->u.generic_sbp);
37
 
38
        DPRINTK(("autofs: shutting down\n"));
39
}
40
 
41
static int autofs_statfs(struct super_block *sb, struct statfs *buf);
42
static void autofs_read_inode(struct inode *inode);
43
 
44
static struct super_operations autofs_sops = {
45
        read_inode:     autofs_read_inode,
46
        put_super:      autofs_put_super,
47
        statfs:         autofs_statfs,
48
};
49
 
50
static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
51
{
52
        char *this_char, *value;
53
 
54
        *uid = current->uid;
55
        *gid = current->gid;
56
        *pgrp = current->pgrp;
57
 
58
        *minproto = *maxproto = AUTOFS_PROTO_VERSION;
59
 
60
        *pipefd = -1;
61
 
62
        if ( !options ) return 1;
63
        for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
64
                if ((value = strchr(this_char,'=')) != NULL)
65
                        *value++ = 0;
66
                if (!strcmp(this_char,"fd")) {
67
                        if (!value || !*value)
68
                                return 1;
69
                        *pipefd = simple_strtoul(value,&value,0);
70
                        if (*value)
71
                                return 1;
72
                }
73
                else if (!strcmp(this_char,"uid")) {
74
                        if (!value || !*value)
75
                                return 1;
76
                        *uid = simple_strtoul(value,&value,0);
77
                        if (*value)
78
                                return 1;
79
                }
80
                else if (!strcmp(this_char,"gid")) {
81
                        if (!value || !*value)
82
                                return 1;
83
                        *gid = simple_strtoul(value,&value,0);
84
                        if (*value)
85
                                return 1;
86
                }
87
                else if (!strcmp(this_char,"pgrp")) {
88
                        if (!value || !*value)
89
                                return 1;
90
                        *pgrp = simple_strtoul(value,&value,0);
91
                        if (*value)
92
                                return 1;
93
                }
94
                else if (!strcmp(this_char,"minproto")) {
95
                        if (!value || !*value)
96
                                return 1;
97
                        *minproto = simple_strtoul(value,&value,0);
98
                        if (*value)
99
                                return 1;
100
                }
101
                else if (!strcmp(this_char,"maxproto")) {
102
                        if (!value || !*value)
103
                                return 1;
104
                        *maxproto = simple_strtoul(value,&value,0);
105
                        if (*value)
106
                                return 1;
107
                }
108
                else break;
109
        }
110
        return (*pipefd < 0);
111
}
112
 
113
struct super_block *autofs_read_super(struct super_block *s, void *data,
114
                                      int silent)
115
{
116
        struct inode * root_inode;
117
        struct dentry * root;
118
        struct file * pipe;
119
        int pipefd;
120
        struct autofs_sb_info *sbi;
121
        int minproto, maxproto;
122
 
123
        sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL);
124
        if ( !sbi )
125
                goto fail_unlock;
126
        DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
127
 
128
        s->u.generic_sbp = sbi;
129
        sbi->magic = AUTOFS_SBI_MAGIC;
130
        sbi->catatonic = 0;
131
        sbi->exp_timeout = 0;
132
        sbi->oz_pgrp = current->pgrp;
133
        autofs_initialize_hash(&sbi->dirhash);
134
        sbi->queues = NULL;
135
        memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
136
        sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
137
        s->s_blocksize = 1024;
138
        s->s_blocksize_bits = 10;
139
        s->s_magic = AUTOFS_SUPER_MAGIC;
140
        s->s_op = &autofs_sops;
141
 
142
        root_inode = iget(s, AUTOFS_ROOT_INO);
143
        root = d_alloc_root(root_inode);
144
        pipe = NULL;
145
 
146
        if (!root)
147
                goto fail_iput;
148
 
149
        /* Can this call block?  - WTF cares? s is locked. */
150
        if ( parse_options(data,&pipefd,&root_inode->i_uid,&root_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
151
                printk("autofs: called with bogus options\n");
152
                goto fail_dput;
153
        }
154
 
155
        /* Couldn't this be tested earlier? */
156
        if ( minproto > AUTOFS_PROTO_VERSION ||
157
             maxproto < AUTOFS_PROTO_VERSION ) {
158
                printk("autofs: kernel does not match daemon version\n");
159
                goto fail_dput;
160
        }
161
 
162
        DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
163
        pipe = fget(pipefd);
164
 
165
        if ( !pipe ) {
166
                printk("autofs: could not open pipe file descriptor\n");
167
                goto fail_dput;
168
        }
169
        if ( !pipe->f_op || !pipe->f_op->write )
170
                goto fail_fput;
171
        sbi->pipe = pipe;
172
 
173
        /*
174
         * Success! Install the root dentry now to indicate completion.
175
         */
176
        s->s_root = root;
177
        return s;
178
 
179
fail_fput:
180
        printk("autofs: pipe file descriptor does not contain proper ops\n");
181
        fput(pipe);
182
fail_dput:
183
        dput(root);
184
        goto fail_free;
185
fail_iput:
186
        printk("autofs: get root dentry failed\n");
187
        iput(root_inode);
188
fail_free:
189
        kfree(sbi);
190
fail_unlock:
191
        return NULL;
192
}
193
 
194
static int autofs_statfs(struct super_block *sb, struct statfs *buf)
195
{
196
        buf->f_type = AUTOFS_SUPER_MAGIC;
197
        buf->f_bsize = 1024;
198
        buf->f_namelen = NAME_MAX;
199
        return 0;
200
}
201
 
202
static void autofs_read_inode(struct inode *inode)
203
{
204
        ino_t ino = inode->i_ino;
205
        unsigned int n;
206
        struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
207
 
208
        /* Initialize to the default case (stub directory) */
209
 
210
        inode->i_op = &autofs_dir_inode_operations;
211
        inode->i_fop = &dcache_dir_ops;
212
        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
213
        inode->i_nlink = 2;
214
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
215
        inode->i_blocks = 0;
216
        inode->i_blksize = 1024;
217
 
218
        if ( ino == AUTOFS_ROOT_INO ) {
219
                inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
220
                inode->i_op = &autofs_root_inode_operations;
221
                inode->i_fop = &autofs_root_operations;
222
                inode->i_uid = inode->i_gid = 0; /* Changed in read_super */
223
                return;
224
        }
225
 
226
        inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
227
        inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
228
 
229
        if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) {
230
                /* Symlink inode - should be in symlink list */
231
                struct autofs_symlink *sl;
232
 
233
                n = ino - AUTOFS_FIRST_SYMLINK;
234
                if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
235
                        printk("autofs: Looking for bad symlink inode %u\n", (unsigned int) ino);
236
                        return;
237
                }
238
 
239
                inode->i_op = &autofs_symlink_inode_operations;
240
                sl = &sbi->symlink[n];
241
                inode->u.generic_ip = sl;
242
                inode->i_mode = S_IFLNK | S_IRWXUGO;
243
                inode->i_mtime = inode->i_ctime = sl->mtime;
244
                inode->i_size = sl->len;
245
                inode->i_nlink = 1;
246
        }
247
}

powered by: WebSVN 2.1.0

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