Blame view

fs/libfs.c 30.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
   *	fs/libfs.c
   *	Library for filesystems writers.
   */
ac13a829f   Fabian Frederick   fs/libfs.c: add g...
5
  #include <linux/blkdev.h>
630d9c472   Paul Gortmaker   fs: reduce the us...
6
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
  #include <linux/pagemap.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
8
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
  #include <linux/mount.h>
  #include <linux/vfs.h>
7bb46a673   npiggin@suse.de   fs: introduce new...
11
  #include <linux/quotaops.h>
7cf34c761   Ingo Molnar   [PATCH] sem2mutex...
12
  #include <linux/mutex.h>
87dc800be   Al Viro   new helper: kfree...
13
  #include <linux/namei.h>
2596110a3   Christoph Hellwig   exportfs: add new...
14
  #include <linux/exportfs.h>
d5aacad54   Al Viro   New helper - simp...
15
  #include <linux/writeback.h>
ff01bb483   Al Viro   fs: move code out...
16
  #include <linux/buffer_head.h> /* sync_mapping_buffers */
7cf34c761   Ingo Molnar   [PATCH] sem2mutex...
17

7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
18
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19

a4464dbc0   Al Viro   Make ->d_sb assig...
20
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
  int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
  		   struct kstat *stat)
  {
dea655c28   David Howells   VFS: fs library h...
24
  	struct inode *inode = d_inode(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  	generic_fillattr(inode, stat);
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
26
  	stat->blocks = inode->i_mapping->nrpages << (PAGE_SHIFT - 9);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
29
  EXPORT_SYMBOL(simple_getattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30

726c33422   David Howells   [PATCH] VFS: Perm...
31
  int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  {
726c33422   David Howells   [PATCH] VFS: Perm...
33
  	buf->f_type = dentry->d_sb->s_magic;
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
34
  	buf->f_bsize = PAGE_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
  	buf->f_namelen = NAME_MAX;
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
38
  EXPORT_SYMBOL(simple_statfs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
  
  /*
   * Retaining negative dentries for an in-memory filesystem just wastes
   * memory and lookup time: arrange for them to be deleted immediately.
   */
b26d4cd38   Al Viro   consolidate simpl...
44
  int always_delete_dentry(const struct dentry *dentry)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
  {
  	return 1;
  }
b26d4cd38   Al Viro   consolidate simpl...
48
49
50
51
52
53
  EXPORT_SYMBOL(always_delete_dentry);
  
  const struct dentry_operations simple_dentry_operations = {
  	.d_delete = always_delete_dentry,
  };
  EXPORT_SYMBOL(simple_dentry_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
  
  /*
   * Lookup the data. This is trivial - if the dentry didn't already
   * exist, we know it is negative.  Set d_op to delete negative dentries.
   */
00cd8dd3b   Al Viro   stop passing name...
59
  struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
  	if (dentry->d_name.len > NAME_MAX)
  		return ERR_PTR(-ENAMETOOLONG);
74931da7a   Al Viro   make simple_looku...
63
64
  	if (!dentry->d_sb->s_d_op)
  		d_set_d_op(dentry, &simple_dentry_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
  	d_add(dentry, NULL);
  	return NULL;
  }
12f388722   Al Viro   libfs: get export...
68
  EXPORT_SYMBOL(simple_lookup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  int dcache_dir_open(struct inode *inode, struct file *file)
  {
ba65dc5ef   Al Viro   much milder d_wal...
72
  	file->private_data = d_alloc_cursor(file->f_path.dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
  
  	return file->private_data ? 0 : -ENOMEM;
  }
12f388722   Al Viro   libfs: get export...
76
  EXPORT_SYMBOL(dcache_dir_open);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
  
  int dcache_dir_close(struct inode *inode, struct file *file)
  {
  	dput(file->private_data);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
83
  EXPORT_SYMBOL(dcache_dir_close);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

4f42c1b5b   Al Viro   libfs.c: new help...
85
86
87
88
89
  /* parent is locked at least shared */
  static struct dentry *next_positive(struct dentry *parent,
  				    struct list_head *from,
  				    int count)
  {
ebaaa80e8   Al Viro   lockless next_pos...
90
91
  	unsigned *seq = &parent->d_inode->i_dir_seq, n;
  	struct dentry *res;
4f42c1b5b   Al Viro   libfs.c: new help...
92
  	struct list_head *p;
ebaaa80e8   Al Viro   lockless next_pos...
93
94
95
96
97
98
99
100
101
  	bool skipped;
  	int i;
  
  retry:
  	i = count;
  	skipped = false;
  	n = smp_load_acquire(seq) & ~1;
  	res = NULL;
  	rcu_read_lock();
4f42c1b5b   Al Viro   libfs.c: new help...
102
103
  	for (p = from->next; p != &parent->d_subdirs; p = p->next) {
  		struct dentry *d = list_entry(p, struct dentry, d_child);
ebaaa80e8   Al Viro   lockless next_pos...
104
105
106
  		if (!simple_positive(d)) {
  			skipped = true;
  		} else if (!--i) {
4f42c1b5b   Al Viro   libfs.c: new help...
107
108
109
110
  			res = d;
  			break;
  		}
  	}
ebaaa80e8   Al Viro   lockless next_pos...
111
112
113
114
115
116
  	rcu_read_unlock();
  	if (skipped) {
  		smp_rmb();
  		if (unlikely(*seq != n))
  			goto retry;
  	}
4f42c1b5b   Al Viro   libfs.c: new help...
117
118
119
120
121
122
  	return res;
  }
  
  static void move_cursor(struct dentry *cursor, struct list_head *after)
  {
  	struct dentry *parent = cursor->d_parent;
ebaaa80e8   Al Viro   lockless next_pos...
123
  	unsigned n, *seq = &parent->d_inode->i_dir_seq;
4f42c1b5b   Al Viro   libfs.c: new help...
124
  	spin_lock(&parent->d_lock);
ebaaa80e8   Al Viro   lockless next_pos...
125
126
127
128
129
130
  	for (;;) {
  		n = *seq;
  		if (!(n & 1) && cmpxchg(seq, n, n + 1) == n)
  			break;
  		cpu_relax();
  	}
4f42c1b5b   Al Viro   libfs.c: new help...
131
132
133
134
135
  	__list_del(cursor->d_child.prev, cursor->d_child.next);
  	if (after)
  		list_add(&cursor->d_child, after);
  	else
  		list_add_tail(&cursor->d_child, &parent->d_subdirs);
ebaaa80e8   Al Viro   lockless next_pos...
136
  	smp_store_release(seq, n + 2);
4f42c1b5b   Al Viro   libfs.c: new help...
137
138
  	spin_unlock(&parent->d_lock);
  }
965c8e59c   Andrew Morton   lseek: the "whenc...
139
  loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  {
2fd6b7f50   Nick Piggin   fs: dcache scale ...
141
  	struct dentry *dentry = file->f_path.dentry;
965c8e59c   Andrew Morton   lseek: the "whenc...
142
  	switch (whence) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
145
146
147
148
  		case 1:
  			offset += file->f_pos;
  		case 0:
  			if (offset >= 0)
  				break;
  		default:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
152
153
  			return -EINVAL;
  	}
  	if (offset != file->f_pos) {
  		file->f_pos = offset;
  		if (file->f_pos >= 2) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  			struct dentry *cursor = file->private_data;
4f42c1b5b   Al Viro   libfs.c: new help...
155
  			struct dentry *to;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  			loff_t n = file->f_pos - 2;
274f5b041   Al Viro   dcache_{readdir,d...
157
  			inode_lock_shared(dentry->d_inode);
4f42c1b5b   Al Viro   libfs.c: new help...
158
159
  			to = next_positive(dentry, &dentry->d_subdirs, n);
  			move_cursor(cursor, to ? &to->d_child : NULL);
274f5b041   Al Viro   dcache_{readdir,d...
160
  			inode_unlock_shared(dentry->d_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
  	return offset;
  }
12f388722   Al Viro   libfs: get export...
165
  EXPORT_SYMBOL(dcache_dir_lseek);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
168
169
170
171
172
173
174
175
176
177
  
  /* Relationship between i_mode and the DT_xxx types */
  static inline unsigned char dt_type(struct inode *inode)
  {
  	return (inode->i_mode >> 12) & 15;
  }
  
  /*
   * Directory is locked and all positive dentries in it are safe, since
   * for ramfs-type trees they can't go away without unlink() or rmdir(),
   * both impossible due to the lock on directory.
   */
5f99f4e79   Al Viro   [readdir] switch ...
178
  int dcache_readdir(struct file *file, struct dir_context *ctx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  {
5f99f4e79   Al Viro   [readdir] switch ...
180
181
  	struct dentry *dentry = file->f_path.dentry;
  	struct dentry *cursor = file->private_data;
4f42c1b5b   Al Viro   libfs.c: new help...
182
183
184
  	struct list_head *p = &cursor->d_child;
  	struct dentry *next;
  	bool moved = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185

5f99f4e79   Al Viro   [readdir] switch ...
186
187
  	if (!dir_emit_dots(file, ctx))
  		return 0;
5f99f4e79   Al Viro   [readdir] switch ...
188

4f42c1b5b   Al Viro   libfs.c: new help...
189
190
191
  	if (ctx->pos == 2)
  		p = &dentry->d_subdirs;
  	while ((next = next_positive(dentry, p, 1)) != NULL) {
5f99f4e79   Al Viro   [readdir] switch ...
192
  		if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
dea655c28   David Howells   VFS: fs library h...
193
  			      d_inode(next)->i_ino, dt_type(d_inode(next))))
4f42c1b5b   Al Viro   libfs.c: new help...
194
195
196
  			break;
  		moved = true;
  		p = &next->d_child;
5f99f4e79   Al Viro   [readdir] switch ...
197
  		ctx->pos++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
  	}
4f42c1b5b   Al Viro   libfs.c: new help...
199
200
  	if (moved)
  		move_cursor(cursor, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
203
  EXPORT_SYMBOL(dcache_readdir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
208
  
  ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
  {
  	return -EISDIR;
  }
12f388722   Al Viro   libfs: get export...
209
  EXPORT_SYMBOL(generic_read_dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210

4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
211
  const struct file_operations simple_dir_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
214
215
  	.open		= dcache_dir_open,
  	.release	= dcache_dir_close,
  	.llseek		= dcache_dir_lseek,
  	.read		= generic_read_dir,
4e82901cd   Al Viro   dcache_{readdir,d...
216
  	.iterate_shared	= dcache_readdir,
1b061d924   Christoph Hellwig   rename the generi...
217
  	.fsync		= noop_fsync,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  };
12f388722   Al Viro   libfs: get export...
219
  EXPORT_SYMBOL(simple_dir_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220

92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
221
  const struct inode_operations simple_dir_inode_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
223
  	.lookup		= simple_lookup,
  };
12f388722   Al Viro   libfs: get export...
224
  EXPORT_SYMBOL(simple_dir_inode_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225

759b9775c   Hugh Dickins   [PATCH] shmem and...
226
227
228
  static const struct super_operations simple_super_operations = {
  	.statfs		= simple_statfs,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
  /*
   * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
   * will never be mountable)
   */
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
233
234
  struct dentry *mount_pseudo_xattr(struct file_system_type *fs_type, char *name,
  	const struct super_operations *ops, const struct xattr_handler **xattr,
c74a1cbb3   Al Viro   pass default dent...
235
  	const struct dentry_operations *dops, unsigned long magic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  {
9249e17fe   David Howells   VFS: Pass mount f...
237
  	struct super_block *s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
239
  	struct dentry *dentry;
  	struct inode *root;
26fe57502   Linus Torvalds   vfs: make it poss...
240
  	struct qstr d_name = QSTR_INIT(name, strlen(name));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241

9249e17fe   David Howells   VFS: Pass mount f...
242
  	s = sget(fs_type, NULL, set_anon_super, MS_NOUSER, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  	if (IS_ERR(s))
51139adac   Al Viro   convert get_sb_ps...
244
  		return ERR_CAST(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245

89a4eb4b6   Jeff Layton   vfs: make get_sb_...
246
  	s->s_maxbytes = MAX_LFS_FILESIZE;
3971e1a91   Alex Nixon   VFS: increase pse...
247
248
  	s->s_blocksize = PAGE_SIZE;
  	s->s_blocksize_bits = PAGE_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  	s->s_magic = magic;
759b9775c   Hugh Dickins   [PATCH] shmem and...
250
  	s->s_op = ops ? ops : &simple_super_operations;
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
251
  	s->s_xattr = xattr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
  	s->s_time_gran = 1;
  	root = new_inode(s);
  	if (!root)
  		goto Enomem;
1a1c9bb43   Jeff Layton   inode numbering: ...
256
257
258
259
260
261
  	/*
  	 * since this is the first inode, make it number 1. New inodes created
  	 * after this must take care not to collide with it (by passing
  	 * max_reserved of 1 to iunique).
  	 */
  	root->i_ino = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
078cd8279   Deepa Dinamani   fs: Replace CURRE...
263
  	root->i_atime = root->i_mtime = root->i_ctime = current_time(root);
a4464dbc0   Al Viro   Make ->d_sb assig...
264
  	dentry = __d_alloc(s, &d_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
  	if (!dentry) {
  		iput(root);
  		goto Enomem;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
  	d_instantiate(dentry, root);
  	s->s_root = dentry;
c74a1cbb3   Al Viro   pass default dent...
271
  	s->s_d_op = dops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  	s->s_flags |= MS_ACTIVE;
51139adac   Al Viro   convert get_sb_ps...
273
  	return dget(s->s_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
275
  
  Enomem:
6f5bbff9a   Al Viro   Convert obvious p...
276
  	deactivate_locked_super(s);
51139adac   Al Viro   convert get_sb_ps...
277
  	return ERR_PTR(-ENOMEM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  }
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
279
  EXPORT_SYMBOL(mount_pseudo_xattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280

20955e891   Stephen Boyd   libfs: add simple...
281
282
283
284
285
286
  int simple_open(struct inode *inode, struct file *file)
  {
  	if (inode->i_private)
  		file->private_data = inode->i_private;
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
287
  EXPORT_SYMBOL(simple_open);
20955e891   Stephen Boyd   libfs: add simple...
288

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
290
  int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
  {
dea655c28   David Howells   VFS: fs library h...
291
  	struct inode *inode = d_inode(old_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292

078cd8279   Deepa Dinamani   fs: Replace CURRE...
293
  	inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode);
d8c76e6f4   Dave Hansen   [PATCH] r/o bind ...
294
  	inc_nlink(inode);
7de9c6ee3   Al Viro   new helper: ihold()
295
  	ihold(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
299
  	dget(dentry);
  	d_instantiate(dentry, inode);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
300
  EXPORT_SYMBOL(simple_link);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
304
305
  int simple_empty(struct dentry *dentry)
  {
  	struct dentry *child;
  	int ret = 0;
2fd6b7f50   Nick Piggin   fs: dcache scale ...
306
  	spin_lock(&dentry->d_lock);
946e51f2b   Al Viro   move d_rcu from o...
307
  	list_for_each_entry(child, &dentry->d_subdirs, d_child) {
da5029563   Nick Piggin   fs: dcache scale ...
308
309
310
  		spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
  		if (simple_positive(child)) {
  			spin_unlock(&child->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  			goto out;
da5029563   Nick Piggin   fs: dcache scale ...
312
313
314
  		}
  		spin_unlock(&child->d_lock);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
  	ret = 1;
  out:
2fd6b7f50   Nick Piggin   fs: dcache scale ...
317
  	spin_unlock(&dentry->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
  	return ret;
  }
12f388722   Al Viro   libfs: get export...
320
  EXPORT_SYMBOL(simple_empty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
322
323
  
  int simple_unlink(struct inode *dir, struct dentry *dentry)
  {
dea655c28   David Howells   VFS: fs library h...
324
  	struct inode *inode = d_inode(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325

078cd8279   Deepa Dinamani   fs: Replace CURRE...
326
  	inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode);
9a53c3a78   Dave Hansen   [PATCH] r/o bind ...
327
  	drop_nlink(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
330
  	dput(dentry);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
331
  EXPORT_SYMBOL(simple_unlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
334
335
336
  
  int simple_rmdir(struct inode *dir, struct dentry *dentry)
  {
  	if (!simple_empty(dentry))
  		return -ENOTEMPTY;
dea655c28   David Howells   VFS: fs library h...
337
  	drop_nlink(d_inode(dentry));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  	simple_unlink(dir, dentry);
9a53c3a78   Dave Hansen   [PATCH] r/o bind ...
339
  	drop_nlink(dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
342
  EXPORT_SYMBOL(simple_rmdir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
344
  
  int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
e0e0be8a8   Miklos Szeredi   libfs: support RE...
345
346
  		  struct inode *new_dir, struct dentry *new_dentry,
  		  unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  {
dea655c28   David Howells   VFS: fs library h...
348
  	struct inode *inode = d_inode(old_dentry);
e36cb0b89   David Howells   VFS: (Scripted) C...
349
  	int they_are_dirs = d_is_dir(old_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350

e0e0be8a8   Miklos Szeredi   libfs: support RE...
351
352
  	if (flags & ~RENAME_NOREPLACE)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
  	if (!simple_empty(new_dentry))
  		return -ENOTEMPTY;
dea655c28   David Howells   VFS: fs library h...
355
  	if (d_really_is_positive(new_dentry)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  		simple_unlink(new_dir, new_dentry);
841590ce1   Al Viro   fix IN_DELETE_SEL...
357
  		if (they_are_dirs) {
dea655c28   David Howells   VFS: fs library h...
358
  			drop_nlink(d_inode(new_dentry));
9a53c3a78   Dave Hansen   [PATCH] r/o bind ...
359
  			drop_nlink(old_dir);
841590ce1   Al Viro   fix IN_DELETE_SEL...
360
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  	} else if (they_are_dirs) {
9a53c3a78   Dave Hansen   [PATCH] r/o bind ...
362
  		drop_nlink(old_dir);
d8c76e6f4   Dave Hansen   [PATCH] r/o bind ...
363
  		inc_nlink(new_dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
365
366
  	}
  
  	old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
078cd8279   Deepa Dinamani   fs: Replace CURRE...
367
  		new_dir->i_mtime = inode->i_ctime = current_time(old_dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
  
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
371
  EXPORT_SYMBOL(simple_rename);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372

7bb46a673   npiggin@suse.de   fs: introduce new...
373
  /**
eef2380c1   Christoph Hellwig   default to simple...
374
   * simple_setattr - setattr for simple filesystem
7bb46a673   npiggin@suse.de   fs: introduce new...
375
376
377
378
379
   * @dentry: dentry
   * @iattr: iattr structure
   *
   * Returns 0 on success, -error on failure.
   *
eef2380c1   Christoph Hellwig   default to simple...
380
381
382
383
384
385
   * simple_setattr is a simple ->setattr implementation without a proper
   * implementation of size changes.
   *
   * It can either be used for in-memory filesystems or special files
   * on simple regular filesystems.  Anything that needs to change on-disk
   * or wire state on size changes needs its own setattr method.
7bb46a673   npiggin@suse.de   fs: introduce new...
386
387
388
   */
  int simple_setattr(struct dentry *dentry, struct iattr *iattr)
  {
dea655c28   David Howells   VFS: fs library h...
389
  	struct inode *inode = d_inode(dentry);
7bb46a673   npiggin@suse.de   fs: introduce new...
390
  	int error;
31051c85b   Jan Kara   fs: Give dentry t...
391
  	error = setattr_prepare(dentry, iattr);
7bb46a673   npiggin@suse.de   fs: introduce new...
392
393
  	if (error)
  		return error;
2c27c65ed   Christoph Hellwig   check ATTR_SIZE c...
394
395
  	if (iattr->ia_valid & ATTR_SIZE)
  		truncate_setsize(inode, iattr->ia_size);
6a1a90ad1   Christoph Hellwig   rename generic_se...
396
  	setattr_copy(inode, iattr);
eef2380c1   Christoph Hellwig   default to simple...
397
398
  	mark_inode_dirty(inode);
  	return 0;
7bb46a673   npiggin@suse.de   fs: introduce new...
399
400
  }
  EXPORT_SYMBOL(simple_setattr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
  int simple_readpage(struct file *file, struct page *page)
  {
c0d92cbc5   Pekka J Enberg   [PATCH] libfs: re...
403
  	clear_highpage(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
405
  	flush_dcache_page(page);
  	SetPageUptodate(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
  	unlock_page(page);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
409
  EXPORT_SYMBOL(simple_readpage);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410

afddba49d   Nick Piggin   fs: introduce wri...
411
412
413
414
415
416
  int simple_write_begin(struct file *file, struct address_space *mapping,
  			loff_t pos, unsigned len, unsigned flags,
  			struct page **pagep, void **fsdata)
  {
  	struct page *page;
  	pgoff_t index;
afddba49d   Nick Piggin   fs: introduce wri...
417

09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
418
  	index = pos >> PAGE_SHIFT;
afddba49d   Nick Piggin   fs: introduce wri...
419

54566b2c1   Nick Piggin   fs: symlink write...
420
  	page = grab_cache_page_write_begin(mapping, index, flags);
afddba49d   Nick Piggin   fs: introduce wri...
421
422
423
424
  	if (!page)
  		return -ENOMEM;
  
  	*pagep = page;
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
425
426
  	if (!PageUptodate(page) && (len != PAGE_SIZE)) {
  		unsigned from = pos & (PAGE_SIZE - 1);
193cf4b99   Boaz Harrosh   libfs: Unexport a...
427

09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
428
  		zero_user_segments(page, 0, from, from + len, PAGE_SIZE);
193cf4b99   Boaz Harrosh   libfs: Unexport a...
429
430
  	}
  	return 0;
afddba49d   Nick Piggin   fs: introduce wri...
431
  }
12f388722   Al Viro   libfs: get export...
432
  EXPORT_SYMBOL(simple_write_begin);
afddba49d   Nick Piggin   fs: introduce wri...
433

ad2a722f1   Boaz Harrosh   libfs: Open code ...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
  /**
   * simple_write_end - .write_end helper for non-block-device FSes
   * @available: See .write_end of address_space_operations
   * @file: 		"
   * @mapping: 		"
   * @pos: 		"
   * @len: 		"
   * @copied: 		"
   * @page: 		"
   * @fsdata: 		"
   *
   * simple_write_end does the minimum needed for updating a page after writing is
   * done. It has the same API signature as the .write_end of
   * address_space_operations vector. So it can just be set onto .write_end for
   * FSes that don't need any other processing. i_mutex is assumed to be held.
   * Block based filesystems should use generic_write_end().
   * NOTE: Even though i_size might get updated by this function, mark_inode_dirty
   * is not called, so a filesystem that actually does store data in .write_inode
   * should extend on what's done here with a call to mark_inode_dirty() in the
   * case that i_size has changed.
04fff6416   Al Viro   simple_write_end(...
454
455
   *
   * Use *ONLY* with simple_readpage()
ad2a722f1   Boaz Harrosh   libfs: Open code ...
456
   */
afddba49d   Nick Piggin   fs: introduce wri...
457
458
459
460
  int simple_write_end(struct file *file, struct address_space *mapping,
  			loff_t pos, unsigned len, unsigned copied,
  			struct page *page, void *fsdata)
  {
ad2a722f1   Boaz Harrosh   libfs: Open code ...
461
462
  	struct inode *inode = page->mapping->host;
  	loff_t last_pos = pos + copied;
afddba49d   Nick Piggin   fs: introduce wri...
463
464
  
  	/* zero the stale part of the page if we did a short copy */
04fff6416   Al Viro   simple_write_end(...
465
466
467
  	if (!PageUptodate(page)) {
  		if (copied < len) {
  			unsigned from = pos & (PAGE_SIZE - 1);
afddba49d   Nick Piggin   fs: introduce wri...
468

04fff6416   Al Viro   simple_write_end(...
469
470
  			zero_user(page, from + copied, len - copied);
  		}
ad2a722f1   Boaz Harrosh   libfs: Open code ...
471
  		SetPageUptodate(page);
04fff6416   Al Viro   simple_write_end(...
472
  	}
ad2a722f1   Boaz Harrosh   libfs: Open code ...
473
474
475
476
477
478
  	/*
  	 * No need to use i_size_read() here, the i_size
  	 * cannot change under us because we hold the i_mutex.
  	 */
  	if (last_pos > inode->i_size)
  		i_size_write(inode, last_pos);
afddba49d   Nick Piggin   fs: introduce wri...
479

ad2a722f1   Boaz Harrosh   libfs: Open code ...
480
  	set_page_dirty(page);
afddba49d   Nick Piggin   fs: introduce wri...
481
  	unlock_page(page);
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
482
  	put_page(page);
afddba49d   Nick Piggin   fs: introduce wri...
483
484
485
  
  	return copied;
  }
12f388722   Al Viro   libfs: get export...
486
  EXPORT_SYMBOL(simple_write_end);
afddba49d   Nick Piggin   fs: introduce wri...
487

1a1c9bb43   Jeff Layton   inode numbering: ...
488
489
490
491
492
  /*
   * the inodes created here are not hashed. If you use iunique to generate
   * unique inode values later for this filesystem, then you must take care
   * to pass it an appropriate max_reserved value to avoid collisions.
   */
7d683a099   Roberto Sassu   wrong type for 'm...
493
494
  int simple_fill_super(struct super_block *s, unsigned long magic,
  		      struct tree_descr *files)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496
497
498
499
  	struct inode *inode;
  	struct dentry *root;
  	struct dentry *dentry;
  	int i;
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
500
501
  	s->s_blocksize = PAGE_SIZE;
  	s->s_blocksize_bits = PAGE_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
  	s->s_magic = magic;
759b9775c   Hugh Dickins   [PATCH] shmem and...
503
  	s->s_op = &simple_super_operations;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
506
507
508
  	s->s_time_gran = 1;
  
  	inode = new_inode(s);
  	if (!inode)
  		return -ENOMEM;
1a1c9bb43   Jeff Layton   inode numbering: ...
509
510
511
512
513
  	/*
  	 * because the root inode is 1, the files array must not contain an
  	 * entry at index 1
  	 */
  	inode->i_ino = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
  	inode->i_mode = S_IFDIR | 0755;
078cd8279   Deepa Dinamani   fs: Replace CURRE...
515
  	inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
517
  	inode->i_op = &simple_dir_inode_operations;
  	inode->i_fop = &simple_dir_operations;
bfe868486   Miklos Szeredi   filesystems: add ...
518
  	set_nlink(inode, 2);
48fde701a   Al Viro   switch open-coded...
519
520
  	root = d_make_root(inode);
  	if (!root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
524
  	for (i = 0; !files->name || files->name[0]; i++, files++) {
  		if (!files->name)
  			continue;
1a1c9bb43   Jeff Layton   inode numbering: ...
525
526
527
528
529
530
531
  
  		/* warn if it tries to conflict with the root inode */
  		if (unlikely(i == 1))
  			printk(KERN_WARNING "%s: %s passed in a files array"
  				"with an index of 1!
  ", __func__,
  				s->s_type->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
  		dentry = d_alloc_name(root, files->name);
  		if (!dentry)
  			goto out;
  		inode = new_inode(s);
32096ea1a   Konstantin Khlebnikov   vfs: fix dentry l...
536
537
  		if (!inode) {
  			dput(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
  			goto out;
32096ea1a   Konstantin Khlebnikov   vfs: fix dentry l...
539
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
  		inode->i_mode = S_IFREG | files->mode;
078cd8279   Deepa Dinamani   fs: Replace CURRE...
541
  		inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
544
545
546
547
548
549
  		inode->i_fop = files->ops;
  		inode->i_ino = i;
  		d_add(dentry, inode);
  	}
  	s->s_root = root;
  	return 0;
  out:
  	d_genocide(root);
640946f20   Al Viro   dentry leak in si...
550
  	shrink_dcache_parent(root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
552
553
  	dput(root);
  	return -ENOMEM;
  }
12f388722   Al Viro   libfs: get export...
554
  EXPORT_SYMBOL(simple_fill_super);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
  
  static DEFINE_SPINLOCK(pin_fs_lock);
1f5ce9e93   Trond Myklebust   VFS: Unexport do_...
557
  int simple_pin_fs(struct file_system_type *type, struct vfsmount **mount, int *count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
562
  {
  	struct vfsmount *mnt = NULL;
  	spin_lock(&pin_fs_lock);
  	if (unlikely(!*mount)) {
  		spin_unlock(&pin_fs_lock);
2452992aa   Al Viro   make simple_pin_f...
563
  		mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564
565
566
567
568
569
570
571
572
573
574
575
  		if (IS_ERR(mnt))
  			return PTR_ERR(mnt);
  		spin_lock(&pin_fs_lock);
  		if (!*mount)
  			*mount = mnt;
  	}
  	mntget(*mount);
  	++*count;
  	spin_unlock(&pin_fs_lock);
  	mntput(mnt);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
576
  EXPORT_SYMBOL(simple_pin_fs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
580
581
582
583
584
585
586
587
  
  void simple_release_fs(struct vfsmount **mount, int *count)
  {
  	struct vfsmount *mnt;
  	spin_lock(&pin_fs_lock);
  	mnt = *mount;
  	if (!--*count)
  		*mount = NULL;
  	spin_unlock(&pin_fs_lock);
  	mntput(mnt);
  }
12f388722   Al Viro   libfs: get export...
588
  EXPORT_SYMBOL(simple_release_fs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589

6d1029b56   Akinobu Mita   add kernel-doc fo...
590
591
592
593
594
595
596
597
598
599
600
601
602
603
  /**
   * simple_read_from_buffer - copy data from the buffer to user space
   * @to: the user space buffer to read to
   * @count: the maximum number of bytes to read
   * @ppos: the current position in the buffer
   * @from: the buffer to read from
   * @available: the size of the buffer
   *
   * The simple_read_from_buffer() function reads up to @count bytes from the
   * buffer @from at offset @ppos into the user space address starting at @to.
   *
   * On success, the number of bytes read is returned and the offset @ppos is
   * advanced by this number, or negative value is returned on error.
   **/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
605
606
607
  ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
  				const void *from, size_t available)
  {
  	loff_t pos = *ppos;
14be27460   Steven Rostedt   libfs: make simpl...
608
  	size_t ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
610
  	if (pos < 0)
  		return -EINVAL;
14be27460   Steven Rostedt   libfs: make simpl...
611
  	if (pos >= available || !count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
613
614
  		return 0;
  	if (count > available - pos)
  		count = available - pos;
14be27460   Steven Rostedt   libfs: make simpl...
615
616
  	ret = copy_to_user(to, from + pos, count);
  	if (ret == count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
  		return -EFAULT;
14be27460   Steven Rostedt   libfs: make simpl...
618
  	count -= ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
620
621
  	*ppos = pos + count;
  	return count;
  }
12f388722   Al Viro   libfs: get export...
622
  EXPORT_SYMBOL(simple_read_from_buffer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623

6d1029b56   Akinobu Mita   add kernel-doc fo...
624
  /**
6a727b43b   Jiri Slaby   FS / libfs: Imple...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
   * simple_write_to_buffer - copy data from user space to the buffer
   * @to: the buffer to write to
   * @available: the size of the buffer
   * @ppos: the current position in the buffer
   * @from: the user space buffer to read from
   * @count: the maximum number of bytes to read
   *
   * The simple_write_to_buffer() function reads up to @count bytes from the user
   * space address starting at @from into the buffer @to at offset @ppos.
   *
   * On success, the number of bytes written is returned and the offset @ppos is
   * advanced by this number, or negative value is returned on error.
   **/
  ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
  		const void __user *from, size_t count)
  {
  	loff_t pos = *ppos;
  	size_t res;
  
  	if (pos < 0)
  		return -EINVAL;
  	if (pos >= available || !count)
  		return 0;
  	if (count > available - pos)
  		count = available - pos;
  	res = copy_from_user(to + pos, from, count);
  	if (res == count)
  		return -EFAULT;
  	count -= res;
  	*ppos = pos + count;
  	return count;
  }
12f388722   Al Viro   libfs: get export...
657
  EXPORT_SYMBOL(simple_write_to_buffer);
6a727b43b   Jiri Slaby   FS / libfs: Imple...
658
659
  
  /**
6d1029b56   Akinobu Mita   add kernel-doc fo...
660
661
662
663
664
665
666
667
668
669
670
671
672
   * memory_read_from_buffer - copy data from the buffer
   * @to: the kernel space buffer to read to
   * @count: the maximum number of bytes to read
   * @ppos: the current position in the buffer
   * @from: the buffer to read from
   * @available: the size of the buffer
   *
   * The memory_read_from_buffer() function reads up to @count bytes from the
   * buffer @from at offset @ppos into the kernel space address starting at @to.
   *
   * On success, the number of bytes read is returned and the offset @ppos is
   * advanced by this number, or negative value is returned on error.
   **/
93b071139   Akinobu Mita   introduce memory_...
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
  				const void *from, size_t available)
  {
  	loff_t pos = *ppos;
  
  	if (pos < 0)
  		return -EINVAL;
  	if (pos >= available)
  		return 0;
  	if (count > available - pos)
  		count = available - pos;
  	memcpy(to, from + pos, count);
  	*ppos = pos + count;
  
  	return count;
  }
12f388722   Al Viro   libfs: get export...
689
  EXPORT_SYMBOL(memory_read_from_buffer);
93b071139   Akinobu Mita   introduce memory_...
690

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
693
694
695
696
  /*
   * Transaction based IO.
   * The file expects a single write which triggers the transaction, and then
   * possibly a read which collects the result - which is stored in a
   * file-local buffer.
   */
76791ab2d   Ingo Molnar   kmemtrace, fs: un...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
  
  void simple_transaction_set(struct file *file, size_t n)
  {
  	struct simple_transaction_argresp *ar = file->private_data;
  
  	BUG_ON(n > SIMPLE_TRANSACTION_LIMIT);
  
  	/*
  	 * The barrier ensures that ar->size will really remain zero until
  	 * ar->data is ready for reading.
  	 */
  	smp_mb();
  	ar->size = n;
  }
12f388722   Al Viro   libfs: get export...
711
  EXPORT_SYMBOL(simple_transaction_set);
76791ab2d   Ingo Molnar   kmemtrace, fs: un...
712

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  char *simple_transaction_get(struct file *file, const char __user *buf, size_t size)
  {
  	struct simple_transaction_argresp *ar;
  	static DEFINE_SPINLOCK(simple_transaction_lock);
  
  	if (size > SIMPLE_TRANSACTION_LIMIT - 1)
  		return ERR_PTR(-EFBIG);
  
  	ar = (struct simple_transaction_argresp *)get_zeroed_page(GFP_KERNEL);
  	if (!ar)
  		return ERR_PTR(-ENOMEM);
  
  	spin_lock(&simple_transaction_lock);
  
  	/* only one write allowed per open */
  	if (file->private_data) {
  		spin_unlock(&simple_transaction_lock);
  		free_page((unsigned long)ar);
  		return ERR_PTR(-EBUSY);
  	}
  
  	file->private_data = ar;
  
  	spin_unlock(&simple_transaction_lock);
  
  	if (copy_from_user(ar->data, buf, size))
  		return ERR_PTR(-EFAULT);
  
  	return ar->data;
  }
12f388722   Al Viro   libfs: get export...
743
  EXPORT_SYMBOL(simple_transaction_get);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
746
747
748
749
750
751
752
  
  ssize_t simple_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
  {
  	struct simple_transaction_argresp *ar = file->private_data;
  
  	if (!ar)
  		return 0;
  	return simple_read_from_buffer(buf, size, pos, ar->data, ar->size);
  }
12f388722   Al Viro   libfs: get export...
753
  EXPORT_SYMBOL(simple_transaction_read);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
757
758
759
  
  int simple_transaction_release(struct inode *inode, struct file *file)
  {
  	free_page((unsigned long)file->private_data);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
760
  EXPORT_SYMBOL(simple_transaction_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761

acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
762
763
764
  /* Simple attribute files */
  
  struct simple_attr {
8b88b0998   Christoph Hellwig   libfs: allow erro...
765
766
  	int (*get)(void *, u64 *);
  	int (*set)(void *, u64);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
767
768
769
770
771
  	char get_buf[24];	/* enough to store a u64 and "
  \0" */
  	char set_buf[24];
  	void *data;
  	const char *fmt;	/* format for read operation */
7cf34c761   Ingo Molnar   [PATCH] sem2mutex...
772
  	struct mutex mutex;	/* protects access to these buffers */
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
773
774
775
776
777
  };
  
  /* simple_attr_open is called by an actual attribute open file operation
   * to set the attribute specific access operations. */
  int simple_attr_open(struct inode *inode, struct file *file,
8b88b0998   Christoph Hellwig   libfs: allow erro...
778
  		     int (*get)(void *, u64 *), int (*set)(void *, u64),
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
779
780
781
782
783
784
785
786
787
788
  		     const char *fmt)
  {
  	struct simple_attr *attr;
  
  	attr = kmalloc(sizeof(*attr), GFP_KERNEL);
  	if (!attr)
  		return -ENOMEM;
  
  	attr->get = get;
  	attr->set = set;
8e18e2941   Theodore Ts'o   [PATCH] inode_die...
789
  	attr->data = inode->i_private;
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
790
  	attr->fmt = fmt;
7cf34c761   Ingo Molnar   [PATCH] sem2mutex...
791
  	mutex_init(&attr->mutex);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
792
793
794
795
796
  
  	file->private_data = attr;
  
  	return nonseekable_open(inode, file);
  }
12f388722   Al Viro   libfs: get export...
797
  EXPORT_SYMBOL_GPL(simple_attr_open);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
798

74bedc4d5   Christoph Hellwig   libfs: rename sim...
799
  int simple_attr_release(struct inode *inode, struct file *file)
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
800
801
802
803
  {
  	kfree(file->private_data);
  	return 0;
  }
12f388722   Al Viro   libfs: get export...
804
  EXPORT_SYMBOL_GPL(simple_attr_release);	/* GPL-only?  This?  Really? */
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
805
806
807
808
809
810
811
812
813
814
815
816
817
  
  /* read from the buffer that is filled with the get function */
  ssize_t simple_attr_read(struct file *file, char __user *buf,
  			 size_t len, loff_t *ppos)
  {
  	struct simple_attr *attr;
  	size_t size;
  	ssize_t ret;
  
  	attr = file->private_data;
  
  	if (!attr->get)
  		return -EACCES;
9261303ab   Christoph Hellwig   libfs: make simpl...
818
819
820
  	ret = mutex_lock_interruptible(&attr->mutex);
  	if (ret)
  		return ret;
8b88b0998   Christoph Hellwig   libfs: allow erro...
821
  	if (*ppos) {		/* continued read */
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
822
  		size = strlen(attr->get_buf);
8b88b0998   Christoph Hellwig   libfs: allow erro...
823
824
825
826
827
  	} else {		/* first read */
  		u64 val;
  		ret = attr->get(attr->data, &val);
  		if (ret)
  			goto out;
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
828
  		size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
8b88b0998   Christoph Hellwig   libfs: allow erro...
829
830
  				 attr->fmt, (unsigned long long)val);
  	}
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
831
832
  
  	ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
8b88b0998   Christoph Hellwig   libfs: allow erro...
833
  out:
7cf34c761   Ingo Molnar   [PATCH] sem2mutex...
834
  	mutex_unlock(&attr->mutex);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
835
836
  	return ret;
  }
12f388722   Al Viro   libfs: get export...
837
  EXPORT_SYMBOL_GPL(simple_attr_read);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
838
839
840
841
842
843
844
845
846
847
848
  
  /* interpret the buffer as a number to call the set function with */
  ssize_t simple_attr_write(struct file *file, const char __user *buf,
  			  size_t len, loff_t *ppos)
  {
  	struct simple_attr *attr;
  	u64 val;
  	size_t size;
  	ssize_t ret;
  
  	attr = file->private_data;
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
849
850
  	if (!attr->set)
  		return -EACCES;
9261303ab   Christoph Hellwig   libfs: make simpl...
851
852
853
  	ret = mutex_lock_interruptible(&attr->mutex);
  	if (ret)
  		return ret;
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
854
855
856
857
  	ret = -EFAULT;
  	size = min(sizeof(attr->set_buf) - 1, len);
  	if (copy_from_user(attr->set_buf, buf, size))
  		goto out;
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
858
  	attr->set_buf[size] = '\0';
f7b88631a   Akinobu Mita   fs/libfs.c: fix s...
859
  	val = simple_strtoll(attr->set_buf, NULL, 0);
05cc0cee6   Wu Fengguang   libfs: return err...
860
861
862
  	ret = attr->set(attr->data, val);
  	if (ret == 0)
  		ret = len; /* on success, claim we got the whole input */
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
863
  out:
7cf34c761   Ingo Molnar   [PATCH] sem2mutex...
864
  	mutex_unlock(&attr->mutex);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
865
866
  	return ret;
  }
12f388722   Al Viro   libfs: get export...
867
  EXPORT_SYMBOL_GPL(simple_attr_write);
acaefc25d   Arnd Bergmann   [PATCH] libfs: ad...
868

2596110a3   Christoph Hellwig   exportfs: add new...
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
  /**
   * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
   * @sb:		filesystem to do the file handle conversion on
   * @fid:	file handle to convert
   * @fh_len:	length of the file handle in bytes
   * @fh_type:	type of file handle
   * @get_inode:	filesystem callback to retrieve inode
   *
   * This function decodes @fid as long as it has one of the well-known
   * Linux filehandle types and calls @get_inode on it to retrieve the
   * inode for the object specified in the file handle.
   */
  struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
  		int fh_len, int fh_type, struct inode *(*get_inode)
  			(struct super_block *sb, u64 ino, u32 gen))
  {
  	struct inode *inode = NULL;
  
  	if (fh_len < 2)
  		return NULL;
  
  	switch (fh_type) {
  	case FILEID_INO32_GEN:
  	case FILEID_INO32_GEN_PARENT:
  		inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
  		break;
  	}
4ea3ada29   Christoph Hellwig   [PATCH] new helpe...
896
  	return d_obtain_alias(inode);
2596110a3   Christoph Hellwig   exportfs: add new...
897
898
899
900
  }
  EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
  
  /**
ca1868309   Yanchuan Nian   vfs: fix kerneldo...
901
   * generic_fh_to_parent - generic helper for the fh_to_parent export operation
2596110a3   Christoph Hellwig   exportfs: add new...
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
   * @sb:		filesystem to do the file handle conversion on
   * @fid:	file handle to convert
   * @fh_len:	length of the file handle in bytes
   * @fh_type:	type of file handle
   * @get_inode:	filesystem callback to retrieve inode
   *
   * This function decodes @fid as long as it has one of the well-known
   * Linux filehandle types and calls @get_inode on it to retrieve the
   * inode for the _parent_ object specified in the file handle if it
   * is specified in the file handle, or NULL otherwise.
   */
  struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
  		int fh_len, int fh_type, struct inode *(*get_inode)
  			(struct super_block *sb, u64 ino, u32 gen))
  {
  	struct inode *inode = NULL;
  
  	if (fh_len <= 2)
  		return NULL;
  
  	switch (fh_type) {
  	case FILEID_INO32_GEN_PARENT:
  		inode = get_inode(sb, fid->i32.parent_ino,
  				  (fh_len > 3 ? fid->i32.parent_gen : 0));
  		break;
  	}
4ea3ada29   Christoph Hellwig   [PATCH] new helpe...
928
  	return d_obtain_alias(inode);
2596110a3   Christoph Hellwig   exportfs: add new...
929
930
  }
  EXPORT_SYMBOL_GPL(generic_fh_to_parent);
1b061d924   Christoph Hellwig   rename the generi...
931
  /**
ac13a829f   Fabian Frederick   fs/libfs.c: add g...
932
933
   * __generic_file_fsync - generic fsync implementation for simple filesystems
   *
1b061d924   Christoph Hellwig   rename the generi...
934
   * @file:	file to synchronize
ac13a829f   Fabian Frederick   fs/libfs.c: add g...
935
936
   * @start:	start offset in bytes
   * @end:	end offset in bytes (inclusive)
1b061d924   Christoph Hellwig   rename the generi...
937
938
939
940
941
942
   * @datasync:	only synchronize essential metadata if true
   *
   * This is a generic implementation of the fsync method for simple
   * filesystems which track all non-inode metadata in the buffers list
   * hanging off the address_space structure.
   */
ac13a829f   Fabian Frederick   fs/libfs.c: add g...
943
944
  int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
  				 int datasync)
d5aacad54   Al Viro   New helper - simp...
945
  {
7ea808591   Christoph Hellwig   drop unused dentr...
946
  	struct inode *inode = file->f_mapping->host;
d5aacad54   Al Viro   New helper - simp...
947
948
  	int err;
  	int ret;
02c24a821   Josef Bacik   fs: push i_mutex ...
949
950
951
  	err = filemap_write_and_wait_range(inode->i_mapping, start, end);
  	if (err)
  		return err;
5955102c9   Al Viro   wrappers for ->i_...
952
  	inode_lock(inode);
d5aacad54   Al Viro   New helper - simp...
953
  	ret = sync_mapping_buffers(inode->i_mapping);
0ae45f63d   Theodore Ts'o   vfs: add support ...
954
  	if (!(inode->i_state & I_DIRTY_ALL))
02c24a821   Josef Bacik   fs: push i_mutex ...
955
  		goto out;
d5aacad54   Al Viro   New helper - simp...
956
  	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
02c24a821   Josef Bacik   fs: push i_mutex ...
957
  		goto out;
d5aacad54   Al Viro   New helper - simp...
958

c37650161   Christoph Hellwig   fs: add sync_inod...
959
  	err = sync_inode_metadata(inode, 1);
d5aacad54   Al Viro   New helper - simp...
960
961
  	if (ret == 0)
  		ret = err;
ac13a829f   Fabian Frederick   fs/libfs.c: add g...
962

02c24a821   Josef Bacik   fs: push i_mutex ...
963
  out:
5955102c9   Al Viro   wrappers for ->i_...
964
  	inode_unlock(inode);
d5aacad54   Al Viro   New helper - simp...
965
966
  	return ret;
  }
ac13a829f   Fabian Frederick   fs/libfs.c: add g...
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
  EXPORT_SYMBOL(__generic_file_fsync);
  
  /**
   * generic_file_fsync - generic fsync implementation for simple filesystems
   *			with flush
   * @file:	file to synchronize
   * @start:	start offset in bytes
   * @end:	end offset in bytes (inclusive)
   * @datasync:	only synchronize essential metadata if true
   *
   */
  
  int generic_file_fsync(struct file *file, loff_t start, loff_t end,
  		       int datasync)
  {
  	struct inode *inode = file->f_mapping->host;
  	int err;
  
  	err = __generic_file_fsync(file, start, end, datasync);
  	if (err)
  		return err;
  	return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
  }
1b061d924   Christoph Hellwig   rename the generi...
990
  EXPORT_SYMBOL(generic_file_fsync);
30ca22c70   Patrick J. LoPresti   ext3/ext4: Factor...
991
992
993
994
995
996
997
998
999
1000
1001
1002
  /**
   * generic_check_addressable - Check addressability of file system
   * @blocksize_bits:	log of file system block size
   * @num_blocks:		number of blocks in file system
   *
   * Determine whether a file system with @num_blocks blocks (and a
   * block size of 2**@blocksize_bits) is addressable by the sector_t
   * and page cache of the system.  Return 0 if so and -EFBIG otherwise.
   */
  int generic_check_addressable(unsigned blocksize_bits, u64 num_blocks)
  {
  	u64 last_fs_block = num_blocks - 1;
a33f13efe   Joel Becker   libfs: Fix shift ...
1003
  	u64 last_fs_page =
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
1004
  		last_fs_block >> (PAGE_SHIFT - blocksize_bits);
30ca22c70   Patrick J. LoPresti   ext3/ext4: Factor...
1005
1006
1007
  
  	if (unlikely(num_blocks == 0))
  		return 0;
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
1008
  	if ((blocksize_bits < 9) || (blocksize_bits > PAGE_SHIFT))
30ca22c70   Patrick J. LoPresti   ext3/ext4: Factor...
1009
  		return -EINVAL;
a33f13efe   Joel Becker   libfs: Fix shift ...
1010
1011
  	if ((last_fs_block > (sector_t)(~0ULL) >> (blocksize_bits - 9)) ||
  	    (last_fs_page > (pgoff_t)(~0ULL))) {
30ca22c70   Patrick J. LoPresti   ext3/ext4: Factor...
1012
1013
1014
1015
1016
  		return -EFBIG;
  	}
  	return 0;
  }
  EXPORT_SYMBOL(generic_check_addressable);
1b061d924   Christoph Hellwig   rename the generi...
1017
1018
1019
  /*
   * No-op implementation of ->fsync for in-memory filesystems.
   */
02c24a821   Josef Bacik   fs: push i_mutex ...
1020
  int noop_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1b061d924   Christoph Hellwig   rename the generi...
1021
1022
1023
  {
  	return 0;
  }
1b061d924   Christoph Hellwig   rename the generi...
1024
  EXPORT_SYMBOL(noop_fsync);
87dc800be   Al Viro   new helper: kfree...
1025

fceef393a   Al Viro   switch ->get_link...
1026
1027
  /* Because kfree isn't assignment-compatible with void(void*) ;-/ */
  void kfree_link(void *p)
87dc800be   Al Viro   new helper: kfree...
1028
  {
fceef393a   Al Viro   switch ->get_link...
1029
  	kfree(p);
87dc800be   Al Viro   new helper: kfree...
1030
  }
fceef393a   Al Viro   switch ->get_link...
1031
  EXPORT_SYMBOL(kfree_link);
6987843ff   Al Viro   take anon inode a...
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
  
  /*
   * nop .set_page_dirty method so that people can use .page_mkwrite on
   * anon inodes.
   */
  static int anon_set_page_dirty(struct page *page)
  {
  	return 0;
  };
  
  /*
   * A single inode exists for all anon_inode files. Contrary to pipes,
   * anon_inode inodes have no associated per-instance data, so we need
   * only allocate one of them.
   */
  struct inode *alloc_anon_inode(struct super_block *s)
  {
  	static const struct address_space_operations anon_aops = {
  		.set_page_dirty = anon_set_page_dirty,
  	};
  	struct inode *inode = new_inode_pseudo(s);
  
  	if (!inode)
  		return ERR_PTR(-ENOMEM);
  
  	inode->i_ino = get_next_ino();
  	inode->i_mapping->a_ops = &anon_aops;
  
  	/*
  	 * Mark the inode dirty from the very beginning,
  	 * that way it will never be moved to the dirty
  	 * list because mark_inode_dirty() will think
  	 * that it already _is_ on the dirty list.
  	 */
  	inode->i_state = I_DIRTY;
  	inode->i_mode = S_IRUSR | S_IWUSR;
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
  	inode->i_flags |= S_PRIVATE;
078cd8279   Deepa Dinamani   fs: Replace CURRE...
1071
  	inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
6987843ff   Al Viro   take anon inode a...
1072
1073
1074
  	return inode;
  }
  EXPORT_SYMBOL(alloc_anon_inode);
1c994a090   Jeff Layton   locks: consolidat...
1075
1076
1077
1078
1079
1080
  
  /**
   * simple_nosetlease - generic helper for prohibiting leases
   * @filp: file pointer
   * @arg: type of lease to obtain
   * @flp: new lease supplied for insertion
e6f5c7893   Jeff Layton   locks: plumb a "p...
1081
   * @priv: private data for lm_setup operation
1c994a090   Jeff Layton   locks: consolidat...
1082
1083
1084
1085
1086
   *
   * Generic helper for filesystems that do not wish to allow leases to be set.
   * All arguments are ignored and it just returns -EINVAL.
   */
  int
e6f5c7893   Jeff Layton   locks: plumb a "p...
1087
1088
  simple_nosetlease(struct file *filp, long arg, struct file_lock **flp,
  		  void **priv)
1c994a090   Jeff Layton   locks: consolidat...
1089
1090
1091
1092
  {
  	return -EINVAL;
  }
  EXPORT_SYMBOL(simple_nosetlease);
61ba64fc0   Al Viro   libfs: simple_fol...
1093

6b2553918   Al Viro   replace ->follow_...
1094
  const char *simple_get_link(struct dentry *dentry, struct inode *inode,
fceef393a   Al Viro   switch ->get_link...
1095
  			    struct delayed_call *done)
61ba64fc0   Al Viro   libfs: simple_fol...
1096
  {
6b2553918   Al Viro   replace ->follow_...
1097
  	return inode->i_link;
61ba64fc0   Al Viro   libfs: simple_fol...
1098
  }
6b2553918   Al Viro   replace ->follow_...
1099
  EXPORT_SYMBOL(simple_get_link);
61ba64fc0   Al Viro   libfs: simple_fol...
1100
1101
  
  const struct inode_operations simple_symlink_inode_operations = {
6b2553918   Al Viro   replace ->follow_...
1102
  	.get_link = simple_get_link,
61ba64fc0   Al Viro   libfs: simple_fol...
1103
1104
  };
  EXPORT_SYMBOL(simple_symlink_inode_operations);
fbabfd0f4   Eric W. Biederman   fs: Add helper fu...
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
  
  /*
   * Operations for a permanently empty directory.
   */
  static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
  {
  	return ERR_PTR(-ENOENT);
  }
  
  static int empty_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
  				 struct kstat *stat)
  {
  	struct inode *inode = d_inode(dentry);
  	generic_fillattr(inode, stat);
  	return 0;
  }
  
  static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
  {
  	return -EPERM;
  }
fbabfd0f4   Eric W. Biederman   fs: Add helper fu...
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
  static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size)
  {
  	return -EOPNOTSUPP;
  }
  
  static const struct inode_operations empty_dir_inode_operations = {
  	.lookup		= empty_dir_lookup,
  	.permission	= generic_permission,
  	.setattr	= empty_dir_setattr,
  	.getattr	= empty_dir_getattr,
fbabfd0f4   Eric W. Biederman   fs: Add helper fu...
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
  	.listxattr	= empty_dir_listxattr,
  };
  
  static loff_t empty_dir_llseek(struct file *file, loff_t offset, int whence)
  {
  	/* An empty directory has two entries . and .. at offsets 0 and 1 */
  	return generic_file_llseek_size(file, offset, whence, 2, 2);
  }
  
  static int empty_dir_readdir(struct file *file, struct dir_context *ctx)
  {
  	dir_emit_dots(file, ctx);
  	return 0;
  }
  
  static const struct file_operations empty_dir_operations = {
  	.llseek		= empty_dir_llseek,
  	.read		= generic_read_dir,
c51da20c4   Al Viro   more trivial ->it...
1154
  	.iterate_shared	= empty_dir_readdir,
fbabfd0f4   Eric W. Biederman   fs: Add helper fu...
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  	.fsync		= noop_fsync,
  };
  
  
  void make_empty_dir_inode(struct inode *inode)
  {
  	set_nlink(inode, 2);
  	inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  	inode->i_uid = GLOBAL_ROOT_UID;
  	inode->i_gid = GLOBAL_ROOT_GID;
  	inode->i_rdev = 0;
4b75de861   Eric W. Biederman   fs: Set the size ...
1166
  	inode->i_size = 0;
fbabfd0f4   Eric W. Biederman   fs: Add helper fu...
1167
1168
1169
1170
  	inode->i_blkbits = PAGE_SHIFT;
  	inode->i_blocks = 0;
  
  	inode->i_op = &empty_dir_inode_operations;
f5c244383   Andreas Gruenbacher   libfs: Use IOP_XA...
1171
  	inode->i_opflags &= ~IOP_XATTR;
fbabfd0f4   Eric W. Biederman   fs: Add helper fu...
1172
1173
1174
1175
1176
1177
1178
1179
  	inode->i_fop = &empty_dir_operations;
  }
  
  bool is_empty_dir_inode(struct inode *inode)
  {
  	return (inode->i_fop == &empty_dir_operations) &&
  		(inode->i_op == &empty_dir_inode_operations);
  }