added a lot of printk output to ease writing of emulator
[linux-2.4.21-pre4.git] / fs / autofs4 / inode.c
1 /* -*- 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 ino_lnkfree(struct autofs_info *ino)
23 {
24         if (ino->u.symlink) {
25                 kfree(ino->u.symlink);
26                 ino->u.symlink = NULL;
27         }
28 }
29
30 struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
31                                      struct autofs_sb_info *sbi, mode_t mode)
32 {
33         int reinit = 1;
34
35         if (ino == NULL) {
36                 reinit = 0;
37                 ino = kmalloc(sizeof(*ino), GFP_KERNEL);
38         }
39
40         if (ino == NULL)
41                 return NULL;
42
43         ino->flags = 0;
44         ino->mode = mode;
45         ino->inode = NULL;
46         ino->dentry = NULL;
47         ino->size = 0;
48
49         ino->last_used = jiffies;
50
51         ino->sbi = sbi;
52
53         if (reinit && ino->free)
54                 (ino->free)(ino);
55
56         memset(&ino->u, 0, sizeof(ino->u));
57
58         ino->free = NULL;
59
60         if (S_ISLNK(mode))
61                 ino->free = ino_lnkfree;
62
63         return ino;
64 }
65
66 void autofs4_free_ino(struct autofs_info *ino)
67 {
68         if (ino->dentry) {
69                 ino->dentry->d_fsdata = NULL;
70                 if (ino->dentry->d_inode)
71                         dput(ino->dentry);
72                 ino->dentry = NULL;
73         }
74         if (ino->free)
75                 (ino->free)(ino);
76         kfree(ino);
77 }
78
79 static void autofs4_put_super(struct super_block *sb)
80 {
81         struct autofs_sb_info *sbi = autofs4_sbi(sb);
82
83         sb->u.generic_sbp = NULL;
84
85         if ( !sbi->catatonic )
86                 autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
87
88         kfree(sbi);
89
90         DPRINTK(("autofs: shutting down\n"));
91 }
92
93 static int autofs4_statfs(struct super_block *sb, struct statfs *buf);
94
95 static struct super_operations autofs4_sops = {
96         put_super:      autofs4_put_super,
97         statfs:         autofs4_statfs,
98 };
99
100 static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
101                          pid_t *pgrp, int *minproto, int *maxproto)
102 {
103         char *this_char, *value;
104         
105         *uid = current->uid;
106         *gid = current->gid;
107         *pgrp = current->pgrp;
108
109         *minproto = AUTOFS_MIN_PROTO_VERSION;
110         *maxproto = AUTOFS_MAX_PROTO_VERSION;
111
112         *pipefd = -1;
113
114         if ( !options ) return 1;
115         for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
116                 if ((value = strchr(this_char,'=')) != NULL)
117                         *value++ = 0;
118                 if (!strcmp(this_char,"fd")) {
119                         if (!value || !*value)
120                                 return 1;
121                         *pipefd = simple_strtoul(value,&value,0);
122                         if (*value)
123                                 return 1;
124                 }
125                 else if (!strcmp(this_char,"uid")) {
126                         if (!value || !*value)
127                                 return 1;
128                         *uid = simple_strtoul(value,&value,0);
129                         if (*value)
130                                 return 1;
131                 }
132                 else if (!strcmp(this_char,"gid")) {
133                         if (!value || !*value)
134                                 return 1;
135                         *gid = simple_strtoul(value,&value,0);
136                         if (*value)
137                                 return 1;
138                 }
139                 else if (!strcmp(this_char,"pgrp")) {
140                         if (!value || !*value)
141                                 return 1;
142                         *pgrp = simple_strtoul(value,&value,0);
143                         if (*value)
144                                 return 1;
145                 }
146                 else if (!strcmp(this_char,"minproto")) {
147                         if (!value || !*value)
148                                 return 1;
149                         *minproto = simple_strtoul(value,&value,0);
150                         if (*value)
151                                 return 1;
152                 }
153                 else if (!strcmp(this_char,"maxproto")) {
154                         if (!value || !*value)
155                                 return 1;
156                         *maxproto = simple_strtoul(value,&value,0);
157                         if (*value)
158                                 return 1;
159                 }
160                 else break;
161         }
162         return (*pipefd < 0);
163 }
164
165 static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
166 {
167         struct autofs_info *ino;
168
169         ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755);
170         if (!ino)
171                 return NULL;
172
173         return ino;
174 }
175
176 struct super_block *autofs4_read_super(struct super_block *s, void *data,
177                                       int silent)
178 {
179         struct inode * root_inode;
180         struct dentry * root;
181         struct file * pipe;
182         int pipefd;
183         struct autofs_sb_info *sbi;
184         int minproto, maxproto;
185
186         sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
187         if ( !sbi )
188                 goto fail_unlock;
189         DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
190
191         memset(sbi, 0, sizeof(*sbi));
192
193         s->u.generic_sbp = sbi;
194         sbi->magic = AUTOFS_SBI_MAGIC;
195         sbi->catatonic = 0;
196         sbi->exp_timeout = 0;
197         sbi->oz_pgrp = current->pgrp;
198         sbi->sb = s;
199         sbi->version = 0;
200         sbi->queues = NULL;
201         s->s_blocksize = 1024;
202         s->s_blocksize_bits = 10;
203         s->s_magic = AUTOFS_SUPER_MAGIC;
204         s->s_op = &autofs4_sops;
205
206         /*
207          * Get the root inode and dentry, but defer checking for errors.
208          */
209         root_inode = autofs4_get_inode(s, autofs4_mkroot(sbi));
210         root_inode->i_op = &autofs4_root_inode_operations;
211         root_inode->i_fop = &autofs4_root_operations;
212         root = d_alloc_root(root_inode);
213         pipe = NULL;
214
215         if (!root)
216                 goto fail_iput;
217
218         /* Can this call block? */
219         if (parse_options(data, &pipefd,
220                           &root_inode->i_uid, &root_inode->i_gid,
221                           &sbi->oz_pgrp,
222                           &minproto, &maxproto)) {
223                 printk("autofs: called with bogus options\n");
224                 goto fail_dput;
225         }
226
227         /* Couldn't this be tested earlier? */
228         if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
229             minproto > AUTOFS_MAX_PROTO_VERSION) {
230                 printk("autofs: kernel does not match daemon version "
231                        "daemon (%d, %d) kernel (%d, %d)\n",
232                         minproto, maxproto,
233                         AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
234                 goto fail_dput;
235         }
236
237         sbi->version = maxproto > AUTOFS_MAX_PROTO_VERSION ? AUTOFS_MAX_PROTO_VERSION : maxproto;
238
239         DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
240         pipe = fget(pipefd);
241         
242         if ( !pipe ) {
243                 printk("autofs: could not open pipe file descriptor\n");
244                 goto fail_dput;
245         }
246         if ( !pipe->f_op || !pipe->f_op->write )
247                 goto fail_fput;
248         sbi->pipe = pipe;
249
250         /*
251          * Success! Install the root dentry now to indicate completion.
252          */
253         s->s_root = root;
254         return s;
255         
256         /*
257          * Failure ... clean up.
258          */
259 fail_fput:
260         printk("autofs: pipe file descriptor does not contain proper ops\n");
261         /*
262          * fput() can block, so we clear the super block first.
263          */
264         fput(pipe);
265         /* fall through */
266 fail_dput:
267         /*
268          * dput() can block, so we clear the super block first.
269          */
270         dput(root);
271         goto fail_free;
272 fail_iput:
273         printk("autofs: get root dentry failed\n");
274         /*
275          * iput() can block, so we clear the super block first.
276          */
277         iput(root_inode);
278 fail_free:
279         kfree(sbi);
280 fail_unlock:
281         return NULL;
282 }
283
284 static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
285 {
286         buf->f_type = AUTOFS_SUPER_MAGIC;
287         buf->f_bsize = 1024;
288         buf->f_namelen = NAME_MAX;
289         return 0;
290 }
291
292 struct inode *autofs4_get_inode(struct super_block *sb,
293                                 struct autofs_info *inf)
294 {
295         struct inode *inode = new_inode(sb);
296
297         if (inode == NULL)
298                 return NULL;
299
300         inf->inode = inode;
301         inode->i_mode = inf->mode;
302         if (sb->s_root) {
303                 inode->i_uid = sb->s_root->d_inode->i_uid;
304                 inode->i_gid = sb->s_root->d_inode->i_gid;
305         } else {
306                 inode->i_uid = 0;
307                 inode->i_gid = 0;
308         }
309         inode->i_blksize = PAGE_CACHE_SIZE;
310         inode->i_blocks = 0;
311         inode->i_rdev = 0;
312         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
313
314         if (S_ISDIR(inf->mode)) {
315                 inode->i_nlink = 2;
316                 inode->i_op = &autofs4_dir_inode_operations;
317                 inode->i_fop = &dcache_dir_ops;
318         } else if (S_ISLNK(inf->mode)) {
319                 inode->i_size = inf->size;
320                 inode->i_op = &autofs4_symlink_inode_operations;
321         }
322
323         return inode;
324 }