Blame view

fs/autofs/inode.c 6.67 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /* -*- linux-c -*- --------------------------------------------------------- *
   *
   * linux/fs/autofs/inode.c
   *
   *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
   *
   * This file is part of the Linux kernel and is made available under
   * the terms of the GNU General Public License, version 2, or at your
   * option, any later version, incorporated herein by reference.
   *
   * ------------------------------------------------------------------------- */
  
  #include <linux/kernel.h>
  #include <linux/mm.h>
  #include <linux/slab.h>
  #include <linux/file.h>
  #include <linux/parser.h>
  #include <linux/bitops.h>
e18fa700c   Jeff Garzik   Move several *_SU...
19
  #include <linux/magic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
  #include "autofs_i.h"
  #include <linux/module.h>
0e7d73824   David Howells   [PATCH] autofs3: ...
22
  void autofs_kill_sb(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
  {
  	struct autofs_sb_info *sbi = autofs_sbi(sb);
  	unsigned int n;
ba8df43c0   Ian Kent   [PATCH] autofs4: ...
26
27
28
  	/*
  	 * In the event of a failure in get_sb_nodev the superblock
  	 * info is not present so nothing else has been setup, so
c949d4eb4   Jiri Kosina   [PATCH] autofs: f...
29
30
  	 * just call kill_anon_super when we are called from
  	 * deactivate_super.
ba8df43c0   Ian Kent   [PATCH] autofs4: ...
31
32
  	 */
  	if (!sbi)
c949d4eb4   Jiri Kosina   [PATCH] autofs: f...
33
  		goto out_kill_sb;
ba8df43c0   Ian Kent   [PATCH] autofs4: ...
34

d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
35
  	if (!sbi->catatonic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  		autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
37
  	put_pid(sbi->oz_pgrp);
f76baf936   Alexander Krizhanovsky   [PATCH] autofs: f...
38
  	autofs_hash_nuke(sbi);
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
39
40
  	for (n = 0; n < AUTOFS_MAX_SYMLINKS; n++) {
  		if (test_bit(n, sbi->symlink_bitmap))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
  			kfree(sbi->symlink[n].data);
  	}
  
  	kfree(sb->s_fs_info);
c949d4eb4   Jiri Kosina   [PATCH] autofs: f...
45
  out_kill_sb:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
  	DPRINTK(("autofs: shutting down
  "));
0e7d73824   David Howells   [PATCH] autofs3: ...
48
  	kill_anon_super(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
  }
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
50
  static const struct super_operations autofs_sops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  	.statfs		= simple_statfs,
979db7542   Miklos Szeredi   mount options: fi...
52
  	.show_options	= generic_show_options,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
55
  };
  
  enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
a447c0932   Steven Whitehouse   vfs: Use const fo...
56
  static const match_table_t autofs_tokens = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
63
64
  	{Opt_fd, "fd=%u"},
  	{Opt_uid, "uid=%u"},
  	{Opt_gid, "gid=%u"},
  	{Opt_pgrp, "pgrp=%u"},
  	{Opt_minproto, "minproto=%u"},
  	{Opt_maxproto, "maxproto=%u"},
  	{Opt_err, NULL}
  };
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
65
66
  static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
  		pid_t *pgrp, int *minproto, int *maxproto)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
70
  {
  	char *p;
  	substring_t args[MAX_OPT_ARGS];
  	int option;
73c646e4a   David Howells   CRED: Wrap task c...
71
72
  	*uid = current_uid();
  	*gid = current_gid();
a47afb0f9   Pavel Emelianov   pid namespaces: r...
73
  	*pgrp = task_pgrp_nr(current);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  
  	*minproto = *maxproto = AUTOFS_PROTO_VERSION;
  
  	*pipefd = -1;
  
  	if (!options)
  		return 1;
  
  	while ((p = strsep(&options, ",")) != NULL) {
  		int token;
  		if (!*p)
  			continue;
  
  		token = match_token(p, autofs_tokens, args);
  		switch (token) {
  		case Opt_fd:
  			if (match_int(&args[0], &option))
  				return 1;
  			*pipefd = option;
  			break;
  		case Opt_uid:
  			if (match_int(&args[0], &option))
  				return 1;
  			*uid = option;
  			break;
  		case Opt_gid:
  			if (match_int(&args[0], &option))
  				return 1;
  			*gid = option;
  			break;
  		case Opt_pgrp:
  			if (match_int(&args[0], &option))
  				return 1;
  			*pgrp = option;
  			break;
  		case Opt_minproto:
  			if (match_int(&args[0], &option))
  				return 1;
  			*minproto = option;
  			break;
  		case Opt_maxproto:
  			if (match_int(&args[0], &option))
  				return 1;
  			*maxproto = option;
  			break;
  		default:
  			return 1;
  		}
  	}
  	return (*pipefd < 0);
  }
  
  int autofs_fill_super(struct super_block *s, void *data, int silent)
  {
  	struct inode * root_inode;
  	struct dentry * root;
  	struct file * pipe;
  	int pipefd;
  	struct autofs_sb_info *sbi;
  	int minproto, maxproto;
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
134
  	pid_t pgid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135

979db7542   Miklos Szeredi   mount options: fi...
136
  	save_mount_options(s, data);
f8314dc60   Panagiotis Issaris   [PATCH] fs: Conve...
137
  	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
138
  	if (!sbi)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  		goto fail_unlock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
144
  	DPRINTK(("autofs: starting up, sbi = %p
  ",sbi));
  
  	s->s_fs_info = sbi;
  	sbi->magic = AUTOFS_SBI_MAGIC;
ba8df43c0   Ian Kent   [PATCH] autofs4: ...
145
146
  	sbi->pipe = NULL;
  	sbi->catatonic = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  	sbi->exp_timeout = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
150
151
152
153
154
155
156
  	autofs_initialize_hash(&sbi->dirhash);
  	sbi->queues = NULL;
  	memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
  	sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
  	s->s_blocksize = 1024;
  	s->s_blocksize_bits = 10;
  	s->s_magic = AUTOFS_SUPER_MAGIC;
  	s->s_op = &autofs_sops;
  	s->s_time_gran = 1;
f76baf936   Alexander Krizhanovsky   [PATCH] autofs: f...
157
  	sbi->sb = s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158

62328a023   David Howells   iget: stop autofs...
159
160
161
  	root_inode = autofs_iget(s, AUTOFS_ROOT_INO);
  	if (IS_ERR(root_inode))
  		goto fail_free;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
165
166
167
168
  	root = d_alloc_root(root_inode);
  	pipe = NULL;
  
  	if (!root)
  		goto fail_iput;
  
  	/* Can this call block?  - WTF cares? s is locked. */
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
169
  	if (parse_options(data, &pipefd, &root_inode->i_uid,
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
170
  				&root_inode->i_gid, &pgid, &minproto,
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
171
  				&maxproto)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
175
176
177
  		printk("autofs: called with bogus options
  ");
  		goto fail_dput;
  	}
  
  	/* Couldn't this be tested earlier? */
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
178
179
  	if (minproto > AUTOFS_PROTO_VERSION ||
  	     maxproto < AUTOFS_PROTO_VERSION) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
181
182
183
  		printk("autofs: kernel does not match daemon version
  ");
  		goto fail_dput;
  	}
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
184
185
186
187
188
189
190
191
192
  	DPRINTK(("autofs: pipe fd = %d, pgrp = %u
  ", pipefd, pgid));
  	sbi->oz_pgrp = find_get_pid(pgid);
  
  	if (!sbi->oz_pgrp) {
  		printk("autofs: could not find process group %d
  ", pgid);
  		goto fail_dput;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
  	pipe = fget(pipefd);
  	
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
195
  	if (!pipe) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
197
  		printk("autofs: could not open pipe file descriptor
  ");
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
198
  		goto fail_put_pid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
  	}
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
200

d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
201
  	if (!pipe->f_op || !pipe->f_op->write)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
  		goto fail_fput;
  	sbi->pipe = pipe;
ba8df43c0   Ian Kent   [PATCH] autofs4: ...
204
  	sbi->catatonic = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
207
208
209
210
211
212
213
214
215
  
  	/*
  	 * Success! Install the root dentry now to indicate completion.
  	 */
  	s->s_root = root;
  	return 0;
  
  fail_fput:
  	printk("autofs: pipe file descriptor does not contain proper ops
  ");
  	fput(pipe);
fa0334f19   Sukadev Bhattiprolu   Replace pid_t in ...
216
217
  fail_put_pid:
  	put_pid(sbi->oz_pgrp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
222
223
224
225
226
  fail_dput:
  	dput(root);
  	goto fail_free;
  fail_iput:
  	printk("autofs: get root dentry failed
  ");
  	iput(root_inode);
  fail_free:
  	kfree(sbi);
ba8df43c0   Ian Kent   [PATCH] autofs4: ...
227
  	s->s_fs_info = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
230
  fail_unlock:
  	return -EINVAL;
  }
62328a023   David Howells   iget: stop autofs...
231
  struct inode *autofs_iget(struct super_block *sb, unsigned long ino)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  	unsigned int n;
62328a023   David Howells   iget: stop autofs...
234
235
236
237
238
239
240
241
  	struct autofs_sb_info *sbi = autofs_sbi(sb);
  	struct inode *inode;
  
  	inode = iget_locked(sb, ino);
  	if (!inode)
  		return ERR_PTR(-ENOMEM);
  	if (!(inode->i_state & I_NEW))
  		return inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
245
246
247
248
249
  
  	/* Initialize to the default case (stub directory) */
  
  	inode->i_op = &simple_dir_inode_operations;
  	inode->i_fop = &simple_dir_operations;
  	inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  	inode->i_nlink = 2;
  	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250

d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
251
  	if (ino == AUTOFS_ROOT_INO) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
  		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
  		inode->i_op = &autofs_root_inode_operations;
  		inode->i_fop = &autofs_root_operations;
62328a023   David Howells   iget: stop autofs...
255
  		goto done;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
258
259
260
  	} 
  	
  	inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
  	inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
  	
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
261
  	if (ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
  		/* Symlink inode - should be in symlink list */
  		struct autofs_symlink *sl;
  
  		n = ino - AUTOFS_FIRST_SYMLINK;
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
266
  		if (n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
  			printk("autofs: Looking for bad symlink inode %u
  ", (unsigned int) ino);
62328a023   David Howells   iget: stop autofs...
269
  			goto done;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
271
272
273
  		}
  		
  		inode->i_op = &autofs_symlink_inode_operations;
  		sl = &sbi->symlink[n];
8e18e2941   Theodore Ts'o   [PATCH] inode_die...
274
  		inode->i_private = sl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
280
  		inode->i_mode = S_IFLNK | S_IRWXUGO;
  		inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = sl->mtime;
  		inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
  		inode->i_size = sl->len;
  		inode->i_nlink = 1;
  	}
62328a023   David Howells   iget: stop autofs...
281
282
283
284
  
  done:
  	unlock_new_inode(inode);
  	return inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
  }