Blame view

fs/openpromfs/inode.c 9.63 KB
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
1
  /* inode.c: /proc/openprom handling routines
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
   *
   * Copyright (C) 1996-1999 Jakub Jelinek  (jakub@redhat.com)
   * Copyright (C) 1998      Eddie C. Dost  (ecd@skynet.be)
   */
  
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/string.h>
  #include <linux/fs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
  #include <linux/init.h>
  #include <linux/slab.h>
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
13
  #include <linux/seq_file.h>
e18fa700c   Jeff Garzik   Move several *_SU...
14
  #include <linux/magic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
17
  
  #include <asm/openprom.h>
  #include <asm/oplib.h>
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
18
  #include <asm/prom.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  #include <asm/uaccess.h>
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
20
  static DEFINE_MUTEX(op_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
22
  #define OPENPROM_ROOT_INO	0
a04ee1463   Jan Engelhardt   [PATCH] openpromf...
23

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  enum op_inode_type {
  	op_inode_node,
  	op_inode_prop,
  };
  
  union op_inode_data {
  	struct device_node	*node;
  	struct property		*prop;
  };
  
  struct op_inode_info {
  	struct inode		vfs_inode;
  	enum op_inode_type	type;
  	union op_inode_data	u;
  };
b88a27edc   David Howells   iget: stop OPENPR...
39
  static struct inode *openprom_iget(struct super_block *sb, ino_t ino);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
40
  static inline struct op_inode_info *OP_I(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
42
  	return container_of(inode, struct op_inode_info, vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  }
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
44
  static int is_string(unsigned char *p, int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
46
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
48
49
  	for (i = 0; i < len; i++) {
  		unsigned char val = p[i];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
51
52
53
  		if ((i && !val) ||
  		    (val >= ' ' && val <= '~'))
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
55
56
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
58
59
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
61
62
63
64
65
  static int property_show(struct seq_file *f, void *v)
  {
  	struct property *prop = f->private;
  	void *pval;
  	int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
67
68
  	len = prop->length;
  	pval = prop->value;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
70
71
72
  	if (is_string(pval, len)) {
  		while (len > 0) {
  			int n = strlen(pval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
74
  			seq_printf(f, "%s", (char *) pval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
76
77
78
  			/* Skip over the NULL byte too.  */
  			pval += n + 1;
  			len -= n + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
80
81
  			if (len > 0)
  				seq_printf(f, " + ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  		}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
83
84
85
86
87
88
89
90
91
92
93
  	} else {
  		if (len & 3) {
  			while (len) {
  				len--;
  				if (len)
  					seq_printf(f, "%02x.",
  						   *(unsigned char *) pval);
  				else
  					seq_printf(f, "%02x",
  						   *(unsigned char *) pval);
  				pval++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
  			}
  		} else {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
96
97
98
99
100
101
102
103
104
105
  			while (len >= 4) {
  				len -= 4;
  
  				if (len)
  					seq_printf(f, "%08x.",
  						   *(unsigned int *) pval);
  				else
  					seq_printf(f, "%08x",
  						   *(unsigned int *) pval);
  				pval += 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
  		}
  	}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
109
110
111
112
  	seq_printf(f, "
  ");
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  }
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
114
  static void *property_start(struct seq_file *f, loff_t *pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  	if (*pos == 0)
  		return pos;
  	return NULL;
  }
  
  static void *property_next(struct seq_file *f, void *v, loff_t *pos)
  {
  	(*pos)++;
  	return NULL;
  }
  
  static void property_stop(struct seq_file *f, void *v)
  {
  	/* Nothing to do */
  }
872e2be7c   Jan Engelhardt   [SPARC]: Constify...
131
  static const struct seq_operations property_op = {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  	.start		= property_start,
  	.next		= property_next,
  	.stop		= property_stop,
  	.show		= property_show
  };
  
  static int property_open(struct inode *inode, struct file *file)
  {
  	struct op_inode_info *oi = OP_I(inode);
  	int ret;
  
  	BUG_ON(oi->type != op_inode_prop);
  
  	ret = seq_open(file, &property_op);
  	if (!ret) {
  		struct seq_file *m = file->private_data;
  		m->private = oi->u.prop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  	}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
150
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  }
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
152
  static const struct file_operations openpromfs_prop_ops = {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
153
154
155
156
  	.open		= property_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= seq_release,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  };
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
158
  static int openpromfs_readdir(struct file *, void *, filldir_t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
160
  static const struct file_operations openprom_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
  	.read		= generic_read_dir,
  	.readdir	= openpromfs_readdir,
3222a3e55   Christoph Hellwig   [PATCH] fix ->lls...
163
  	.llseek		= generic_file_llseek,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
  };
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
165
  static struct dentry *openpromfs_lookup(struct inode *, struct dentry *, struct nameidata *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
167
  static const struct inode_operations openprom_inode_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  	.lookup		= openpromfs_lookup,
  };
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
170
  static struct dentry *openpromfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
172
173
174
175
176
  	struct op_inode_info *ent_oi, *oi = OP_I(dir);
  	struct device_node *dp, *child;
  	struct property *prop;
  	enum op_inode_type ent_type;
  	union op_inode_data ent_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  	const char *name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
  	struct inode *inode;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
179
180
  	unsigned int ino;
  	int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  	
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
182
183
184
  	BUG_ON(oi->type != op_inode_node);
  
  	dp = oi->u.node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
  	name = dentry->d_name.name;
  	len = dentry->d_name.len;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
187
188
189
190
191
192
193
194
195
196
197
198
199
  
  	mutex_lock(&op_mutex);
  
  	child = dp->child;
  	while (child) {
  		int n = strlen(child->path_component_name);
  
  		if (len == n &&
  		    !strncmp(child->path_component_name, name, len)) {
  			ent_type = op_inode_node;
  			ent_data.node = child;
  			ino = child->unique_id;
  			goto found;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  		}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
201
  		child = child->sibling;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  	}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
203
204
205
206
207
208
209
210
211
212
  
  	prop = dp->properties;
  	while (prop) {
  		int n = strlen(prop->name);
  
  		if (len == n && !strncmp(prop->name, name, len)) {
  			ent_type = op_inode_prop;
  			ent_data.prop = prop;
  			ino = prop->unique_id;
  			goto found;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  		}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
214
215
  
  		prop = prop->next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
  	}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
217
218
219
220
221
  
  	mutex_unlock(&op_mutex);
  	return ERR_PTR(-ENOENT);
  
  found:
b88a27edc   David Howells   iget: stop OPENPR...
222
  	inode = openprom_iget(dir->i_sb, ino);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
223
  	mutex_unlock(&op_mutex);
b88a27edc   David Howells   iget: stop OPENPR...
224
225
  	if (IS_ERR(inode))
  		return ERR_CAST(inode);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
226
227
228
229
230
231
  	ent_oi = OP_I(inode);
  	ent_oi->type = ent_type;
  	ent_oi->u = ent_data;
  
  	switch (ent_type) {
  	case op_inode_node:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
  		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
233
  		inode->i_op = &openprom_inode_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  		inode->i_fop = &openprom_operations;
bfe868486   Miklos Szeredi   filesystems: add ...
235
  		set_nlink(inode, 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  		break;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
237
238
239
  	case op_inode_prop:
  		if (!strcmp(dp->name, "options") && (len == 17) &&
  		    !strncmp (name, "security-password", 17))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  			inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
241
  		else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
  			inode->i_mode = S_IFREG | S_IRUGO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  		inode->i_fop = &openpromfs_prop_ops;
bfe868486   Miklos Szeredi   filesystems: add ...
244
  		set_nlink(inode, 1);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
245
  		inode->i_size = ent_oi->u.prop->length;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
250
251
252
253
  	d_add(dentry, inode);
  	return NULL;
  }
  
  static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
  {
80a067801   Josef Sipek   [PATCH] struct pa...
254
  	struct inode *inode = filp->f_path.dentry->d_inode;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
255
256
257
258
  	struct op_inode_info *oi = OP_I(inode);
  	struct device_node *dp = oi->u.node;
  	struct device_node *child;
  	struct property *prop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  	unsigned int ino;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
260
261
262
  	int i;
  
  	mutex_lock(&op_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
264
265
266
267
  	
  	ino = inode->i_ino;
  	i = filp->f_pos;
  	switch (i) {
  	case 0:
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
268
269
  		if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
271
272
273
  		i++;
  		filp->f_pos++;
  		/* fall thru */
  	case 1:
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
274
275
276
277
  		if (filldir(dirent, "..", 2, i,
  			    (dp->parent == NULL ?
  			     OPENPROM_ROOT_INO :
  			     dp->parent->unique_id), DT_DIR) < 0) 
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
279
280
281
282
283
  			goto out;
  		i++;
  		filp->f_pos++;
  		/* fall thru */
  	default:
  		i -= 2;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
284
285
286
287
288
  
  		/* First, the children nodes as directories.  */
  		child = dp->child;
  		while (i && child) {
  			child = child->sibling;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
290
  			i--;
  		}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
291
292
293
294
295
  		while (child) {
  			if (filldir(dirent,
  				    child->path_component_name,
  				    strlen(child->path_component_name),
  				    filp->f_pos, child->unique_id, DT_DIR) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
  				goto out;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
297

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  			filp->f_pos++;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
299
  			child = child->sibling;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  		}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
301
302
303
304
305
306
307
308
309
310
  
  		/* Next, the properties as files.  */
  		prop = dp->properties;
  		while (i && prop) {
  			prop = prop->next;
  			i--;
  		}
  		while (prop) {
  			if (filldir(dirent, prop->name, strlen(prop->name),
  				    filp->f_pos, prop->unique_id, DT_REG) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  				goto out;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
312

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  			filp->f_pos++;
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
314
  			prop = prop->next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
  		}
  	}
  out:
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
318
  	mutex_unlock(&op_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319
320
  	return 0;
  }
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
321
  static struct kmem_cache *op_inode_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
323
  static struct inode *openprom_alloc_inode(struct super_block *sb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
325
  	struct op_inode_info *oi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326

e94b17660   Christoph Lameter   [PATCH] slab: rem...
327
  	oi = kmem_cache_alloc(op_inode_cachep, GFP_KERNEL);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
328
329
  	if (!oi)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330

3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
331
  	return &oi->vfs_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
333
  static void openprom_i_callback(struct rcu_head *head)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
  {
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
335
  	struct inode *inode = container_of(head, struct inode, i_rcu);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
336
  	kmem_cache_free(op_inode_cachep, OP_I(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
338
339
340
341
  static void openprom_destroy_inode(struct inode *inode)
  {
  	call_rcu(&inode->i_rcu, openprom_i_callback);
  }
b88a27edc   David Howells   iget: stop OPENPR...
342
  static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
  {
b88a27edc   David Howells   iget: stop OPENPR...
344
345
346
347
348
349
350
351
352
353
354
355
356
  	struct inode *inode;
  
  	inode = iget_locked(sb, ino);
  	if (!inode)
  		return ERR_PTR(-ENOMEM);
  	if (inode->i_state & I_NEW) {
  		inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  		if (inode->i_ino == OPENPROM_ROOT_INO) {
  			inode->i_op = &openprom_inode_operations;
  			inode->i_fop = &openprom_operations;
  			inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  		}
  		unlock_new_inode(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
  	}
b88a27edc   David Howells   iget: stop OPENPR...
358
  	return inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
360
361
362
363
364
365
  }
  
  static int openprom_remount(struct super_block *sb, int *flags, char *data)
  {
  	*flags |= MS_NOATIME;
  	return 0;
  }
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
366
  static const struct super_operations openprom_sops = {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
367
368
  	.alloc_inode	= openprom_alloc_inode,
  	.destroy_inode	= openprom_destroy_inode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
371
372
373
374
  	.statfs		= simple_statfs,
  	.remount_fs	= openprom_remount,
  };
  
  static int openprom_fill_super(struct super_block *s, void *data, int silent)
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
375
376
  	struct inode *root_inode;
  	struct op_inode_info *oi;
b88a27edc   David Howells   iget: stop OPENPR...
377
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
382
383
384
  
  	s->s_flags |= MS_NOATIME;
  	s->s_blocksize = 1024;
  	s->s_blocksize_bits = 10;
  	s->s_magic = OPENPROM_SUPER_MAGIC;
  	s->s_op = &openprom_sops;
  	s->s_time_gran = 1;
b88a27edc   David Howells   iget: stop OPENPR...
385
386
387
  	root_inode = openprom_iget(s, OPENPROM_ROOT_INO);
  	if (IS_ERR(root_inode)) {
  		ret = PTR_ERR(root_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  		goto out_no_root;
b88a27edc   David Howells   iget: stop OPENPR...
389
  	}
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
390
391
392
393
  
  	oi = OP_I(root_inode);
  	oi->type = op_inode_node;
  	oi->u.node = of_find_node_by_path("/");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
395
  	s->s_root = d_alloc_root(root_inode);
  	if (!s->s_root)
b88a27edc   David Howells   iget: stop OPENPR...
396
  		goto out_no_root_dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  	return 0;
b88a27edc   David Howells   iget: stop OPENPR...
398
399
400
  out_no_root_dentry:
  	iput(root_inode);
  	ret = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
  out_no_root:
  	printk("openprom_fill_super: get root inode failed
  ");
b88a27edc   David Howells   iget: stop OPENPR...
404
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  }
fc14f2fef   Al Viro   convert get_sb_si...
406
407
  static struct dentry *openprom_mount(struct file_system_type *fs_type,
  	int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  {
0e1548256   Meelis Roos   sparc: fix openpr...
409
  	return mount_single(fs_type, flags, data, openprom_fill_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
413
414
  }
  
  static struct file_system_type openprom_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "openpromfs",
fc14f2fef   Al Viro   convert get_sb_si...
415
  	.mount		= openprom_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
  	.kill_sb	= kill_anon_super,
  };
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
418
  static void op_inode_init_once(void *data)
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
419
420
  {
  	struct op_inode_info *oi = (struct op_inode_info *) data;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
421
  	inode_init_once(&oi->vfs_inode);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
422
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
  static int __init init_openprom_fs(void)
  {
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
425
426
427
428
429
430
431
  	int err;
  
  	op_inode_cachep = kmem_cache_create("op_inode_cache",
  					    sizeof(struct op_inode_info),
  					    0,
  					    (SLAB_RECLAIM_ACCOUNT |
  					     SLAB_MEM_SPREAD),
20c2df83d   Paul Mundt   mm: Remove slab d...
432
  					    op_inode_init_once);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
433
434
435
436
437
438
439
440
  	if (!op_inode_cachep)
  		return -ENOMEM;
  
  	err = register_filesystem(&openprom_fs_type);
  	if (err)
  		kmem_cache_destroy(op_inode_cachep);
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
444
  }
  
  static void __exit exit_openprom_fs(void)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  	unregister_filesystem(&openprom_fs_type);
3d824a46b   David S. Miller   [OPENPROMFS]: Rew...
446
  	kmem_cache_destroy(op_inode_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
450
451
  }
  
  module_init(init_openprom_fs)
  module_exit(exit_openprom_fs)
  MODULE_LICENSE("GPL");