Blame view

fs/9p/vfs_inode.c 33.8 KB
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1
2
3
  /*
   *  linux/fs/9p/vfs_inode.c
   *
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
4
   * This file contains vfs inode ops for the 9P2000 protocol.
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
5
6
7
8
9
   *
   *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
   *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
   *
   *  This program is free software; you can redistribute it and/or modify
42e8c509c   Eric Van Hensbergen   [PATCH] v9fs: upd...
10
11
   *  it under the terms of the GNU General Public License version 2
   *  as published by the Free Software Foundation.
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
12
13
14
15
16
17
18
19
20
21
22
23
24
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to:
   *  Free Software Foundation
   *  51 Franklin Street, Fifth Floor
   *  Boston, MA  02111-1301  USA
   *
   */
5d3851530   Joe Perches   9p: Reduce object...
25
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
26
27
28
29
30
31
32
  #include <linux/module.h>
  #include <linux/errno.h>
  #include <linux/fs.h>
  #include <linux/file.h>
  #include <linux/pagemap.h>
  #include <linux/stat.h>
  #include <linux/string.h>
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
33
34
35
  #include <linux/inet.h>
  #include <linux/namei.h>
  #include <linux/idr.h>
e8edc6e03   Alexey Dobriyan   Detach sched.h fr...
36
  #include <linux/sched.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
37
  #include <linux/slab.h>
ebf46264a   Aneesh Kumar K.V   fs/9p: Add suppor...
38
  #include <linux/xattr.h>
85ff872d3   Aneesh Kumar K.V   fs/9p: Implement ...
39
  #include <linux/posix_acl.h>
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
40
41
  #include <net/9p/9p.h>
  #include <net/9p/client.h>
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
42

2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
43
  #include "v9fs.h"
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
44
  #include "v9fs_vfs.h"
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
45
  #include "fid.h"
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
46
  #include "cache.h"
ebf46264a   Aneesh Kumar K.V   fs/9p: Add suppor...
47
  #include "xattr.h"
85ff872d3   Aneesh Kumar K.V   fs/9p: Implement ...
48
  #include "acl.h"
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
49

754661f14   Arjan van de Ven   [PATCH] mark stru...
50
  static const struct inode_operations v9fs_dir_inode_operations;
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
51
  static const struct inode_operations v9fs_dir_inode_operations_dotu;
754661f14   Arjan van de Ven   [PATCH] mark stru...
52
53
  static const struct inode_operations v9fs_file_inode_operations;
  static const struct inode_operations v9fs_symlink_inode_operations;
f5fc6145f   Aneesh Kumar K.V   fs/9p: Use mknod ...
54

2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
55
56
57
58
59
60
  /**
   * unixmode2p9mode - convert unix mode bits to plan 9
   * @v9ses: v9fs session information
   * @mode: mode to convert
   *
   */
3eda0de67   Al Viro   9p: propagate umo...
61
  static u32 unixmode2p9mode(struct v9fs_session_info *v9ses, umode_t mode)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
62
63
64
65
  {
  	int res;
  	res = mode & 0777;
  	if (S_ISDIR(mode))
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
66
  		res |= P9_DMDIR;
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
67
  	if (v9fs_proto_dotu(v9ses)) {
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
68
69
  		if (v9ses->nodev == 0) {
  			if (S_ISSOCK(mode))
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
70
  				res |= P9_DMSOCKET;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
71
  			if (S_ISFIFO(mode))
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
72
  				res |= P9_DMNAMEDPIPE;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
73
  			if (S_ISBLK(mode))
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
74
  				res |= P9_DMDEVICE;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
75
  			if (S_ISCHR(mode))
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
76
  				res |= P9_DMDEVICE;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
77
78
79
  		}
  
  		if ((mode & S_ISUID) == S_ISUID)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
80
  			res |= P9_DMSETUID;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
81
  		if ((mode & S_ISGID) == S_ISGID)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
82
  			res |= P9_DMSETGID;
d199d652c   Anthony Liguori   9p: add support f...
83
84
  		if ((mode & S_ISVTX) == S_ISVTX)
  			res |= P9_DMSETVTX;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
85
  	}
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
86
87
88
89
  	return res;
  }
  
  /**
df345c674   Aneesh Kumar K.V   fs/9p: v9fs_stat2...
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
   * p9mode2perm- convert plan9 mode bits to unix permission bits
   * @v9ses: v9fs session information
   * @stat: p9_wstat from which mode need to be derived
   *
   */
  static int p9mode2perm(struct v9fs_session_info *v9ses,
  		       struct p9_wstat *stat)
  {
  	int res;
  	int mode = stat->mode;
  
  	res = mode & S_IALLUGO;
  	if (v9fs_proto_dotu(v9ses)) {
  		if ((mode & P9_DMSETUID) == P9_DMSETUID)
  			res |= S_ISUID;
  
  		if ((mode & P9_DMSETGID) == P9_DMSETGID)
  			res |= S_ISGID;
  
  		if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
  			res |= S_ISVTX;
  	}
  	return res;
  }
  
  /**
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
116
117
   * p9mode2unixmode- convert plan9 mode bits to unix mode bits
   * @v9ses: v9fs session information
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
118
119
   * @stat: p9_wstat from which mode need to be derived
   * @rdev: major number, minor number in case of device files.
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
120
121
   *
   */
3eda0de67   Al Viro   9p: propagate umo...
122
123
  static umode_t p9mode2unixmode(struct v9fs_session_info *v9ses,
  			       struct p9_wstat *stat, dev_t *rdev)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
124
125
  {
  	int res;
3eda0de67   Al Viro   9p: propagate umo...
126
  	u32 mode = stat->mode;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
127

45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
128
  	*rdev = 0;
df345c674   Aneesh Kumar K.V   fs/9p: v9fs_stat2...
129
  	res = p9mode2perm(v9ses, stat);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
130

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
131
  	if ((mode & P9_DMDIR) == P9_DMDIR)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
132
  		res |= S_IFDIR;
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
133
  	else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
134
  		res |= S_IFLNK;
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
135
  	else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
136
137
  		 && (v9ses->nodev == 0))
  		res |= S_IFSOCK;
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
138
  	else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
139
140
  		 && (v9ses->nodev == 0))
  		res |= S_IFIFO;
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
141
  	else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  		 && (v9ses->nodev == 0)) {
  		char type = 0, ext[32];
  		int major = -1, minor = -1;
  
  		strncpy(ext, stat->extension, sizeof(ext));
  		sscanf(ext, "%c %u %u", &type, &major, &minor);
  		switch (type) {
  		case 'c':
  			res |= S_IFCHR;
  			break;
  		case 'b':
  			res |= S_IFBLK;
  			break;
  		default:
5d3851530   Joe Perches   9p: Reduce object...
156
157
158
  			p9_debug(P9_DEBUG_ERROR, "Unknown special type %c %s
  ",
  				 type, stat->extension);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
159
160
161
  		};
  		*rdev = MKDEV(major, minor);
  	} else
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
162
  		res |= S_IFREG;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
163
164
  	return res;
  }
ee443996a   Eric Van Hensbergen   9p: Documentation...
165
166
167
  /**
   * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
   * @uflags: flags to convert
2e4bef41a   Eric Van Hensbergen   9p: fix O_APPEND ...
168
   * @extended: if .u extensions are active
ee443996a   Eric Van Hensbergen   9p: Documentation...
169
   */
2e4bef41a   Eric Van Hensbergen   9p: fix O_APPEND ...
170
  int v9fs_uflags2omode(int uflags, int extended)
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
171
172
173
174
175
176
177
  {
  	int ret;
  
  	ret = 0;
  	switch (uflags&3) {
  	default:
  	case O_RDONLY:
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
178
  		ret = P9_OREAD;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
179
180
181
  		break;
  
  	case O_WRONLY:
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
182
  		ret = P9_OWRITE;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
183
184
185
  		break;
  
  	case O_RDWR:
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
186
  		ret = P9_ORDWR;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
187
188
  		break;
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
189
  	if (uflags & O_TRUNC)
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
190
  		ret |= P9_OTRUNC;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
191

2e4bef41a   Eric Van Hensbergen   9p: fix O_APPEND ...
192
193
194
195
196
197
198
  	if (extended) {
  		if (uflags & O_EXCL)
  			ret |= P9_OEXCL;
  
  		if (uflags & O_APPEND)
  			ret |= P9_OAPPEND;
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
199
200
201
  
  	return ret;
  }
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
202
  /**
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
203
   * v9fs_blank_wstat - helper function to setup a 9P stat structure
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
204
   * @wstat: structure to initialize
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
205
206
   *
   */
7a4439c40   M. Mohan Kumar   9p: Include fsync...
207
  void
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
208
  v9fs_blank_wstat(struct p9_wstat *wstat)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
209
  {
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  	wstat->type = ~0;
  	wstat->dev = ~0;
  	wstat->qid.type = ~0;
  	wstat->qid.version = ~0;
  	*((long long *)&wstat->qid.path) = ~0;
  	wstat->mode = ~0;
  	wstat->atime = ~0;
  	wstat->mtime = ~0;
  	wstat->length = ~0;
  	wstat->name = NULL;
  	wstat->uid = NULL;
  	wstat->gid = NULL;
  	wstat->muid = NULL;
  	wstat->n_uid = ~0;
  	wstat->n_gid = ~0;
  	wstat->n_muid = ~0;
  	wstat->extension = NULL;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
227
  }
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
228
229
  /**
   * v9fs_alloc_inode - helper function to allocate an inode
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
230
231
   *
   */
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
232
233
  struct inode *v9fs_alloc_inode(struct super_block *sb)
  {
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
234
235
236
237
  	struct v9fs_inode *v9inode;
  	v9inode = (struct v9fs_inode *)kmem_cache_alloc(v9fs_inode_cache,
  							GFP_KERNEL);
  	if (!v9inode)
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
238
  		return NULL;
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
239
240
  #ifdef CONFIG_9P_FSCACHE
  	v9inode->fscache = NULL;
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
241
242
  	spin_lock_init(&v9inode->fscache_lock);
  #endif
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
243
  	v9inode->writeback_fid = NULL;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
244
  	v9inode->cache_validity = 0;
5a7e0a8cf   Aneesh Kumar K.V   fs/9p: Fix race i...
245
  	mutex_init(&v9inode->v_mutex);
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
246
  	return &v9inode->vfs_inode;
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
247
248
249
250
251
252
  }
  
  /**
   * v9fs_destroy_inode - destroy an inode
   *
   */
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
253
  static void v9fs_i_callback(struct rcu_head *head)
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
254
  {
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
255
  	struct inode *inode = container_of(head, struct inode, i_rcu);
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
256
  	kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
257
  }
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
258
259
260
261
262
  
  void v9fs_destroy_inode(struct inode *inode)
  {
  	call_rcu(&inode->i_rcu, v9fs_i_callback);
  }
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
263

5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
264
  int v9fs_init_inode(struct v9fs_session_info *v9ses,
3eda0de67   Al Viro   9p: propagate umo...
265
  		    struct inode *inode, umode_t mode, dev_t rdev)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
266
  {
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
267
  	int err = 0;
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
268

217f206d6   Dmitry Monakhov   9p: replace inode...
269
  	inode_init_owner(inode, NULL, mode);
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
270
  	inode->i_blocks = 0;
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
271
  	inode->i_rdev = rdev;
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
272
273
274
275
276
277
278
279
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  	inode->i_mapping->a_ops = &v9fs_addr_operations;
  
  	switch (mode & S_IFMT) {
  	case S_IFIFO:
  	case S_IFBLK:
  	case S_IFCHR:
  	case S_IFSOCK:
4b43516ab   M. Mohan Kumar   9p: Implement TMKNOD
280
281
  		if (v9fs_proto_dotl(v9ses)) {
  			inode->i_op = &v9fs_file_inode_operations_dotl;
4b43516ab   M. Mohan Kumar   9p: Implement TMKNOD
282
283
  		} else if (v9fs_proto_dotu(v9ses)) {
  			inode->i_op = &v9fs_file_inode_operations;
4b43516ab   M. Mohan Kumar   9p: Implement TMKNOD
284
  		} else {
5d3851530   Joe Perches   9p: Reduce object...
285
286
287
  			p9_debug(P9_DEBUG_ERROR,
  				 "special files without extended mode
  ");
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
288
289
  			err = -EINVAL;
  			goto error;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
290
  		}
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
291
292
293
  		init_special_inode(inode, inode->i_mode, inode->i_rdev);
  		break;
  	case S_IFREG:
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
294
295
  		if (v9fs_proto_dotl(v9ses)) {
  			inode->i_op = &v9fs_file_inode_operations_dotl;
29236f4e1   Aneesh Kumar K.V   fs/9p: set the ca...
296
297
298
299
300
  			if (v9ses->cache)
  				inode->i_fop =
  					&v9fs_cached_file_operations_dotl;
  			else
  				inode->i_fop = &v9fs_file_operations_dotl;
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
301
302
  		} else {
  			inode->i_op = &v9fs_file_inode_operations;
29236f4e1   Aneesh Kumar K.V   fs/9p: set the ca...
303
304
305
306
  			if (v9ses->cache)
  				inode->i_fop = &v9fs_cached_file_operations;
  			else
  				inode->i_fop = &v9fs_file_operations;
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
307
  		}
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
308
309
  		break;
  	case S_IFLNK:
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
310
  		if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
5d3851530   Joe Perches   9p: Reduce object...
311
312
313
  			p9_debug(P9_DEBUG_ERROR,
  				 "extended modes used with legacy protocol
  ");
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
314
315
316
  			err = -EINVAL;
  			goto error;
  		}
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
317
318
319
320
321
  
  		if (v9fs_proto_dotl(v9ses))
  			inode->i_op = &v9fs_symlink_inode_operations_dotl;
  		else
  			inode->i_op = &v9fs_symlink_inode_operations;
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
322
323
324
  		break;
  	case S_IFDIR:
  		inc_nlink(inode);
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
325
326
327
328
  		if (v9fs_proto_dotl(v9ses))
  			inode->i_op = &v9fs_dir_inode_operations_dotl;
  		else if (v9fs_proto_dotu(v9ses))
  			inode->i_op = &v9fs_dir_inode_operations_dotu;
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
329
330
  		else
  			inode->i_op = &v9fs_dir_inode_operations;
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
331
332
333
334
335
  
  		if (v9fs_proto_dotl(v9ses))
  			inode->i_fop = &v9fs_dir_operations_dotl;
  		else
  			inode->i_fop = &v9fs_dir_operations;
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
336
337
  		break;
  	default:
609eac1c1   Linus Torvalds   Merge branch 'for...
338
339
  		p9_debug(P9_DEBUG_ERROR, "BAD mode 0x%hx S_IFMT 0x%x
  ",
5d3851530   Joe Perches   9p: Reduce object...
340
  			 mode, mode & S_IFMT);
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
341
342
  		err = -EINVAL;
  		goto error;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
343
  	}
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
344
345
  error:
  	return err;
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
346

5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
347
  }
2bb541157   Abhishek Kulkarni   9p: Fix possible ...
348

5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
349
350
351
352
353
354
  /**
   * v9fs_get_inode - helper function to setup an inode
   * @sb: superblock
   * @mode: mode to setup inode with
   *
   */
3eda0de67   Al Viro   9p: propagate umo...
355
  struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
356
357
358
359
  {
  	int err;
  	struct inode *inode;
  	struct v9fs_session_info *v9ses = sb->s_fs_info;
609eac1c1   Linus Torvalds   Merge branch 'for...
360
361
  	p9_debug(P9_DEBUG_VFS, "super block: %p mode: %ho
  ", sb, mode);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
362
363
364
  
  	inode = new_inode(sb);
  	if (!inode) {
5d3851530   Joe Perches   9p: Reduce object...
365
366
367
  		pr_warn("%s (%d): Problem allocating inode
  ",
  			__func__, task_pid_nr(current));
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
368
369
  		return ERR_PTR(-ENOMEM);
  	}
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
370
  	err = v9fs_init_inode(v9ses, inode, mode, rdev);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
371
372
373
374
375
  	if (err) {
  		iput(inode);
  		return ERR_PTR(err);
  	}
  	return inode;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
376
  }
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
377
  /*
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
378
379
380
381
  static struct v9fs_fid*
  v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
  {
  	int err;
736c4b857   Mika Kukkonen   [PATCH] Function ...
382
  	int nfid;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
383
384
385
386
387
  	struct v9fs_fid *ret;
  	struct v9fs_fcall *fcall;
  
  	nfid = v9fs_get_idpool(&v9ses->fidpool);
  	if (nfid < 0) {
0b8dd1776   Latchesar Ionkov   [PATCH] v9fs: fix...
388
389
  		eprintk(KERN_WARNING, "no free fids available
  ");
731805b49   Latchesar Ionkov   [PATCH] v9fs: fix...
390
  		return ERR_PTR(-ENOSPC);
0b8dd1776   Latchesar Ionkov   [PATCH] v9fs: fix...
391
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
392
393
394
395
  	err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name,
  		&fcall);
  
  	if (err < 0) {
41e5a6ac8   Latchesar Ionkov   [PATCH] v9fs: sig...
396
397
  		if (fcall && fcall->id == RWALK)
  			goto clunk_fid;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
398
399
400
  		PRINT_FCALL_ERROR("walk error", fcall);
  		v9fs_put_idpool(nfid, &v9ses->fidpool);
  		goto error;
0b8dd1776   Latchesar Ionkov   [PATCH] v9fs: fix...
401
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
402

3cf6429a2   Latchesar Ionkov   [PATCH] v9fs: new...
403
404
  	kfree(fcall);
  	fcall = NULL;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
405
406
407
408
409
  	ret = v9fs_fid_create(v9ses, nfid);
  	if (!ret) {
  		err = -ENOMEM;
  		goto clunk_fid;
  	}
0b8dd1776   Latchesar Ionkov   [PATCH] v9fs: fix...
410

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
411
412
413
414
  	err = v9fs_fid_insert(ret, dentry);
  	if (err < 0) {
  		v9fs_fid_destroy(ret);
  		goto clunk_fid;
0b8dd1776   Latchesar Ionkov   [PATCH] v9fs: fix...
415
  	}
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
416

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
417
  	return ret;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
418

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
419
420
  clunk_fid:
  	v9fs_t_clunk(v9ses, nfid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
421

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
422
423
424
425
  error:
  	kfree(fcall);
  	return ERR_PTR(err);
  }
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
426
  */
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
427

60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
428
429
430
431
432
433
  
  /**
   * v9fs_clear_inode - release an inode
   * @inode: inode to release
   *
   */
b57922d97   Al Viro   convert remaining...
434
  void v9fs_evict_inode(struct inode *inode)
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
435
  {
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
436
  	struct v9fs_inode *v9inode = V9FS_I(inode);
b57922d97   Al Viro   convert remaining...
437
438
  	truncate_inode_pages(inode->i_mapping, 0);
  	end_writeback(inode);
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
439
440
441
442
443
  	filemap_fdatawrite(inode->i_mapping);
  
  #ifdef CONFIG_9P_FSCACHE
  	v9fs_cache_inode_put_cookie(inode);
  #endif
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
444
445
446
447
  	/* clunk the fid stashed in writeback_fid */
  	if (v9inode->writeback_fid) {
  		p9_client_clunk(v9inode->writeback_fid);
  		v9inode->writeback_fid = NULL;
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
448
  	}
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
449
  }
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
450
451
452
  static int v9fs_test_inode(struct inode *inode, void *data)
  {
  	int umode;
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
453
  	dev_t rdev;
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
454
455
456
  	struct v9fs_inode *v9inode = V9FS_I(inode);
  	struct p9_wstat *st = (struct p9_wstat *)data;
  	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
457
  	umode = p9mode2unixmode(v9ses, st, &rdev);
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
458
459
460
461
462
463
464
465
466
467
468
469
470
  	/* don't match inode of different type */
  	if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
  		return 0;
  
  	/* compare qid details */
  	if (memcmp(&v9inode->qid.version,
  		   &st->qid.version, sizeof(v9inode->qid.version)))
  		return 0;
  
  	if (v9inode->qid.type != st->qid.type)
  		return 0;
  	return 1;
  }
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
471
472
473
474
  static int v9fs_test_new_inode(struct inode *inode, void *data)
  {
  	return 0;
  }
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
475
476
477
478
479
480
481
482
  static int v9fs_set_inode(struct inode *inode,  void *data)
  {
  	struct v9fs_inode *v9inode = V9FS_I(inode);
  	struct p9_wstat *st = (struct p9_wstat *)data;
  
  	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
  	return 0;
  }
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
483
484
  static struct inode *v9fs_qid_iget(struct super_block *sb,
  				   struct p9_qid *qid,
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
485
486
  				   struct p9_wstat *st,
  				   int new)
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
487
  {
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
488
  	dev_t rdev;
3eda0de67   Al Viro   9p: propagate umo...
489
490
  	int retval;
  	umode_t umode;
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
491
492
493
  	unsigned long i_ino;
  	struct inode *inode;
  	struct v9fs_session_info *v9ses = sb->s_fs_info;
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
494
495
496
497
498
499
  	int (*test)(struct inode *, void *);
  
  	if (new)
  		test = v9fs_test_new_inode;
  	else
  		test = v9fs_test_inode;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
500

5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
501
  	i_ino = v9fs_qid2ino(qid);
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
502
  	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
503
504
505
506
507
508
509
510
511
  	if (!inode)
  		return ERR_PTR(-ENOMEM);
  	if (!(inode->i_state & I_NEW))
  		return inode;
  	/*
  	 * initialize the inode with the stat info
  	 * FIXME!! we may need support for stale inodes
  	 * later.
  	 */
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
512
  	inode->i_ino = i_ino;
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
513
514
  	umode = p9mode2unixmode(v9ses, st, &rdev);
  	retval = v9fs_init_inode(v9ses, inode, umode, rdev);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
515
  	if (retval)
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
516
  		goto error;
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
517

5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
518
  	v9fs_stat2inode(st, inode, sb);
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
519
  #ifdef CONFIG_9P_FSCACHE
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
520
  	v9fs_cache_inode_get_cookie(inode);
60e78d2c9   Abhishek Kulkarni   9p: Add fscache s...
521
  #endif
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
522
523
  	unlock_new_inode(inode);
  	return inode;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
524
  error:
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
525
526
527
528
529
530
531
  	unlock_new_inode(inode);
  	iput(inode);
  	return ERR_PTR(retval);
  
  }
  
  struct inode *
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
532
  v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
533
  		    struct super_block *sb, int new)
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
534
535
536
537
538
539
540
  {
  	struct p9_wstat *st;
  	struct inode *inode = NULL;
  
  	st = p9_client_stat(fid);
  	if (IS_ERR(st))
  		return ERR_CAST(st);
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
541
  	inode = v9fs_qid_iget(sb, &st->qid, st, new);
02bc35672   Abhishek Kulkarni   9p: Fix possible ...
542
  	p9stat_free(st);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
543
  	kfree(st);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
544
  	return inode;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
545
546
547
  }
  
  /**
f88657ce3   Aneesh Kumar K.V   fs/9p: Add OS dep...
548
549
550
551
552
553
554
555
556
557
558
559
560
   * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
   * plan 9 AT flag.
   * @flags: flags to convert
   */
  static int v9fs_at_to_dotl_flags(int flags)
  {
  	int rflags = 0;
  	if (flags & AT_REMOVEDIR)
  		rflags |= P9_DOTL_AT_REMOVEDIR;
  	return rflags;
  }
  
  /**
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
561
   * v9fs_remove - helper function to remove files and directories
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
562
   * @dir: directory inode that is being deleted
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
563
   * @dentry:  dentry that is being deleted
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
564
   * @rmdir: removing a directory
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
565
566
   *
   */
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
567
  static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
568
  {
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
569
570
571
572
  	struct inode *inode;
  	int retval = -EOPNOTSUPP;
  	struct p9_fid *v9fid, *dfid;
  	struct v9fs_session_info *v9ses;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
573

5d3851530   Joe Perches   9p: Reduce object...
574
575
576
  	p9_debug(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x
  ",
  		 dir, dentry, flags);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
577

48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
578
579
580
581
582
  	v9ses = v9fs_inode2v9ses(dir);
  	inode = dentry->d_inode;
  	dfid = v9fs_fid_lookup(dentry->d_parent);
  	if (IS_ERR(dfid)) {
  		retval = PTR_ERR(dfid);
5d3851530   Joe Perches   9p: Reduce object...
583
584
  		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d
  ", retval);
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
585
586
587
  		return retval;
  	}
  	if (v9fs_proto_dotl(v9ses))
f88657ce3   Aneesh Kumar K.V   fs/9p: Add OS dep...
588
589
  		retval = p9_client_unlinkat(dfid, dentry->d_name.name,
  					    v9fs_at_to_dotl_flags(flags));
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
590
591
592
593
594
595
596
  	if (retval == -EOPNOTSUPP) {
  		/* Try the one based on path */
  		v9fid = v9fs_fid_clone(dentry);
  		if (IS_ERR(v9fid))
  			return PTR_ERR(v9fid);
  		retval = p9_client_remove(v9fid);
  	}
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
597
598
599
600
601
  	if (!retval) {
  		/*
  		 * directories on unlink should have zero
  		 * link count
  		 */
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
602
603
  		if (flags & AT_REMOVEDIR) {
  			clear_nlink(inode);
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
604
605
  			drop_nlink(dir);
  		} else
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
606
  			drop_nlink(inode);
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
607

48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
608
  		v9fs_invalidate_inode_attr(inode);
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
609
  		v9fs_invalidate_inode_attr(dir);
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
610
  	}
d994f4058   Aneesh Kumar K.V   9p: drop nlink re...
611
  	return retval;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
612
613
614
  }
  
  /**
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
615
   * v9fs_create - Create a file
ee443996a   Eric Van Hensbergen   9p: Documentation...
616
617
   * @v9ses: session information
   * @dir: directory that dentry is being created in
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
618
   * @dentry:  dentry that is being created
0e15597eb   Abhishek Kulkarni   9p: minor comment...
619
   * @extension: 9p2000.u extension string to support devices, etc.
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
620
621
   * @perm: create permissions
   * @mode: open mode
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
622
623
   *
   */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
624
625
626
  static struct p9_fid *
  v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
  		struct dentry *dentry, char *extension, u32 perm, u8 mode)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
627
  {
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
628
  	int err;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
629
630
  	char *name;
  	struct p9_fid *dfid, *ofid, *fid;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
631
  	struct inode *inode;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
632

5d3851530   Joe Perches   9p: Reduce object...
633
634
  	p9_debug(P9_DEBUG_VFS, "name %s
  ", dentry->d_name.name);
51a87c552   Eric Van Hensbergen   9p: rework client...
635

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
636
637
638
639
  	err = 0;
  	ofid = NULL;
  	fid = NULL;
  	name = (char *) dentry->d_name.name;
6d27e64d7   Venkateswararao Jujjuri   9p: Optimize TCRE...
640
  	dfid = v9fs_fid_lookup(dentry->d_parent);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
641
  	if (IS_ERR(dfid)) {
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
642
  		err = PTR_ERR(dfid);
5d3851530   Joe Perches   9p: Reduce object...
643
644
  		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d
  ", err);
6d27e64d7   Venkateswararao Jujjuri   9p: Optimize TCRE...
645
  		return ERR_PTR(err);
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
646
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
647

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
648
649
650
651
  	/* clone a fid to use for creation */
  	ofid = p9_client_walk(dfid, 0, NULL, 1);
  	if (IS_ERR(ofid)) {
  		err = PTR_ERR(ofid);
5d3851530   Joe Perches   9p: Reduce object...
652
653
  		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d
  ", err);
6d27e64d7   Venkateswararao Jujjuri   9p: Optimize TCRE...
654
  		return ERR_PTR(err);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
655
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
656

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
657
  	err = p9_client_fcreate(ofid, name, perm, mode, extension);
51a87c552   Eric Van Hensbergen   9p: rework client...
658
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
659
660
  		p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d
  ", err);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
661
  		goto error;
6d27e64d7   Venkateswararao Jujjuri   9p: Optimize TCRE...
662
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
663

b60547930   Aneesh Kumar K.V   fs/9p: We should ...
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
  	if (!(perm & P9_DMLINK)) {
  		/* now walk from the parent so we can get unopened fid */
  		fid = p9_client_walk(dfid, 1, &name, 1);
  		if (IS_ERR(fid)) {
  			err = PTR_ERR(fid);
  			p9_debug(P9_DEBUG_VFS,
  				   "p9_client_walk failed %d
  ", err);
  			fid = NULL;
  			goto error;
  		}
  		/*
  		 * instantiate inode and assign the unopened fid to the dentry
  		 */
  		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
  			p9_debug(P9_DEBUG_VFS,
  				   "inode creation failed %d
  ", err);
  			goto error;
  		}
  		err = v9fs_fid_add(dentry, fid);
  		if (err < 0)
  			goto error;
  		d_instantiate(dentry, inode);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
690
  	}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
691
  	return ofid;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
692
  error:
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
693
694
695
696
697
698
699
700
701
702
703
  	if (ofid)
  		p9_client_clunk(ofid);
  
  	if (fid)
  		p9_client_clunk(fid);
  
  	return ERR_PTR(err);
  }
  
  /**
   * v9fs_vfs_create - VFS hook to create files
ee443996a   Eric Van Hensbergen   9p: Documentation...
704
   * @dir: directory inode that is being created
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
705
706
707
708
709
   * @dentry:  dentry that is being deleted
   * @mode: create permissions
   * @nd: path information
   *
   */
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
710

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
711
  static int
4acdaf27e   Al Viro   switch ->create()...
712
  v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
713
714
715
716
717
  		struct nameidata *nd)
  {
  	int err;
  	u32 perm;
  	int flags;
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
718
719
  	struct file *filp;
  	struct v9fs_inode *v9inode;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
720
  	struct v9fs_session_info *v9ses;
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
721
  	struct p9_fid *fid, *inode_fid;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
722
723
724
725
726
  
  	err = 0;
  	fid = NULL;
  	v9ses = v9fs_inode2v9ses(dir);
  	perm = unixmode2p9mode(v9ses, mode);
dd7dd556e   Al Viro   no need to check ...
727
  	if (nd)
8a5e929dd   Al Viro   don't translitera...
728
  		flags = nd->intent.open.flags;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
729
730
731
732
  	else
  		flags = O_RDWR;
  
  	fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
733
734
  				v9fs_uflags2omode(flags,
  						v9fs_proto_dotu(v9ses)));
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
735
736
737
738
739
  	if (IS_ERR(fid)) {
  		err = PTR_ERR(fid);
  		fid = NULL;
  		goto error;
  	}
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
740
  	v9fs_invalidate_inode_attr(dir);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
741
  	/* if we are opening a file, assign the open fid to the file */
dd7dd556e   Al Viro   no need to check ...
742
  	if (nd) {
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
743
  		v9inode = V9FS_I(dentry->d_inode);
5a7e0a8cf   Aneesh Kumar K.V   fs/9p: Fix race i...
744
  		mutex_lock(&v9inode->v_mutex);
7add697a3   Aneesh Kumar K.V   fs/9p: Attach wri...
745
746
  		if (v9ses->cache && !v9inode->writeback_fid &&
  		    ((flags & O_ACCMODE) != O_RDONLY)) {
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
747
  			/*
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
748
  			 * clone a fid and add it to writeback_fid
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
749
750
751
752
753
754
755
756
  			 * we do it during open time instead of
  			 * page dirty time via write_begin/page_mkwrite
  			 * because we want write after unlink usecase
  			 * to work.
  			 */
  			inode_fid = v9fs_writeback_fid(dentry);
  			if (IS_ERR(inode_fid)) {
  				err = PTR_ERR(inode_fid);
5a7e0a8cf   Aneesh Kumar K.V   fs/9p: Fix race i...
757
  				mutex_unlock(&v9inode->v_mutex);
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
758
759
  				goto error;
  			}
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
760
  			v9inode->writeback_fid = (void *) inode_fid;
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
761
  		}
5a7e0a8cf   Aneesh Kumar K.V   fs/9p: Fix race i...
762
  		mutex_unlock(&v9inode->v_mutex);
877cb3d4d   Aneesh Kumar K.V   fs/9p: Use generi...
763
  		filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
764
  		if (IS_ERR(filp)) {
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
765
766
  			err = PTR_ERR(filp);
  			goto error;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
767
  		}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
768
  		filp->private_data = fid;
46848de02   Aneesh Kumar K.V   fs/9p: set fs cac...
769
770
771
772
  #ifdef CONFIG_9P_FSCACHE
  		if (v9ses->cache)
  			v9fs_cache_inode_set_cookie(dentry->d_inode, filp);
  #endif
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
773
774
  	} else
  		p9_client_clunk(fid);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
775
776
777
778
  
  	return 0;
  
  error:
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
779
780
  	if (fid)
  		p9_client_clunk(fid);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
781

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
782
  	return err;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
783
784
785
786
  }
  
  /**
   * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
ee443996a   Eric Van Hensbergen   9p: Documentation...
787
   * @dir:  inode that is being unlinked
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
788
789
790
791
   * @dentry: dentry that is being unlinked
   * @mode: mode for new directory
   *
   */
18bb1db3e   Al Viro   switch vfs_mkdir(...
792
  static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
793
  {
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
794
  	int err;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
795
  	u32 perm;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
796
  	struct p9_fid *fid;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
797
  	struct v9fs_session_info *v9ses;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
798

5d3851530   Joe Perches   9p: Reduce object...
799
800
  	p9_debug(P9_DEBUG_VFS, "name %s
  ", dentry->d_name.name);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
801
  	err = 0;
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
802
  	v9ses = v9fs_inode2v9ses(dir);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
803
  	perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
804
805
806
807
  	fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD);
  	if (IS_ERR(fid)) {
  		err = PTR_ERR(fid);
  		fid = NULL;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
808
  	} else {
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
809
  		inc_nlink(dir);
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
810
811
  		v9fs_invalidate_inode_attr(dir);
  	}
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
812

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
813
814
  	if (fid)
  		p9_client_clunk(fid);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
815

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
816
  	return err;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
817
818
819
820
821
822
823
824
825
  }
  
  /**
   * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
   * @dir:  inode that is being walked from
   * @dentry: dentry that is being walked to?
   * @nameidata: path data
   *
   */
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
826
  struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
827
828
  				      struct nameidata *nameidata)
  {
73f507171   Aneesh Kumar K.V   fs/9p: Always ask...
829
  	struct dentry *res;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
830
831
  	struct super_block *sb;
  	struct v9fs_session_info *v9ses;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
832
  	struct p9_fid *dfid, *fid;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
833
  	struct inode *inode;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
834
  	char *name;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
835
  	int result = 0;
5d3851530   Joe Perches   9p: Reduce object...
836
837
838
  	p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p
  ",
  		 dir, dentry->d_name.name, dentry, nameidata);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
839

11e9b49b7   Sripathi Kodi   9p: Creating file...
840
841
  	if (dentry->d_name.len > NAME_MAX)
  		return ERR_PTR(-ENAMETOOLONG);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
842
843
  	sb = dir->i_sb;
  	v9ses = v9fs_inode2v9ses(dir);
a534c8d15   Aneesh Kumar K.V   fs/9p: Prevent pa...
844
  	/* We can walk d_parent because we hold the dir->i_mutex */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
845
846
  	dfid = v9fs_fid_lookup(dentry->d_parent);
  	if (IS_ERR(dfid))
e231c2ee6   David Howells   Convert ERR_PTR(P...
847
  		return ERR_CAST(dfid);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
848
849
850
851
852
  
  	name = (char *) dentry->d_name.name;
  	fid = p9_client_walk(dfid, 1, &name, 1);
  	if (IS_ERR(fid)) {
  		result = PTR_ERR(fid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
853
  		if (result == -ENOENT) {
85e0df240   Aneesh Kumar K.V   fs/9p: Make sure ...
854
855
  			inode = NULL;
  			goto inst_out;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
856
  		}
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
857

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
858
  		return ERR_PTR(result);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
859
  	}
73f507171   Aneesh Kumar K.V   fs/9p: Always ask...
860
861
862
863
864
865
866
867
868
  	/*
  	 * Make sure we don't use a wrong inode due to parallel
  	 * unlink. For cached mode create calls request for new
  	 * inode. But with cache disabled, lookup should do this.
  	 */
  	if (v9ses->cache)
  		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
  	else
  		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
869
870
871
872
  	if (IS_ERR(inode)) {
  		result = PTR_ERR(inode);
  		inode = NULL;
  		goto error;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
873
  	}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
874
  	result = v9fs_fid_add(dentry, fid);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
875
  	if (result < 0)
9856af8b5   Aneesh Kumar K.V   fs/9p: Add missin...
876
  		goto error_iput;
85e0df240   Aneesh Kumar K.V   fs/9p: Make sure ...
877
  inst_out:
73f507171   Aneesh Kumar K.V   fs/9p: Always ask...
878
879
880
881
882
883
884
885
886
887
888
  	/*
  	 * If we had a rename on the server and a parallel lookup
  	 * for the new name, then make sure we instantiate with
  	 * the new name. ie look up for a/b, while on server somebody
  	 * moved b under k and client parallely did a lookup for
  	 * k/b.
  	 */
  	res = d_materialise_unique(dentry, inode);
  	if (!IS_ERR(res))
  		return res;
  	result = PTR_ERR(res);
9856af8b5   Aneesh Kumar K.V   fs/9p: Add missin...
889
890
  error_iput:
  	iput(inode);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
891
  error:
62aa528e0   Julien Brunel   9p: use an IS_ERR...
892
  	p9_client_clunk(fid);
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
893

2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
894
895
896
897
898
899
  	return ERR_PTR(result);
  }
  
  /**
   * v9fs_vfs_unlink - VFS unlink hook to delete an inode
   * @i:  inode that is being unlinked
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
900
   * @d: dentry that is being unlinked
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
901
902
   *
   */
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
903
  int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
904
905
906
907
908
909
910
  {
  	return v9fs_remove(i, d, 0);
  }
  
  /**
   * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
   * @i:  inode that is being unlinked
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
911
   * @d: dentry that is being unlinked
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
912
913
   *
   */
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
914
  int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
915
  {
48e370ff9   Aneesh Kumar K.V   fs/9p: add 9P2000...
916
  	return v9fs_remove(i, d, AT_REMOVEDIR);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
917
918
919
920
921
922
923
924
925
926
  }
  
  /**
   * v9fs_vfs_rename - VFS hook to rename an inode
   * @old_dir:  old dir inode
   * @old_dentry: old dentry
   * @new_dir: new dir inode
   * @new_dentry: new dentry
   *
   */
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
927
  int
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
928
929
930
  v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
  		struct inode *new_dir, struct dentry *new_dentry)
  {
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
931
  	int retval;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
932
  	struct inode *old_inode;
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
933
  	struct inode *new_inode;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
934
935
936
937
938
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *oldfid;
  	struct p9_fid *olddirfid;
  	struct p9_fid *newdirfid;
  	struct p9_wstat wstat;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
939

5d3851530   Joe Perches   9p: Reduce object...
940
941
  	p9_debug(P9_DEBUG_VFS, "
  ");
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
942
943
  	retval = 0;
  	old_inode = old_dentry->d_inode;
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
944
  	new_inode = new_dentry->d_inode;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
945
946
  	v9ses = v9fs_inode2v9ses(old_inode);
  	oldfid = v9fs_fid_lookup(old_dentry);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
947
  	if (IS_ERR(oldfid))
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
948
949
950
  		return PTR_ERR(oldfid);
  
  	olddirfid = v9fs_fid_clone(old_dentry->d_parent);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
951
  	if (IS_ERR(olddirfid)) {
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
952
  		retval = PTR_ERR(olddirfid);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
953
  		goto done;
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
954
955
956
  	}
  
  	newdirfid = v9fs_fid_clone(new_dentry->d_parent);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
957
  	if (IS_ERR(newdirfid)) {
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
958
  		retval = PTR_ERR(newdirfid);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
959
  		goto clunk_olddir;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
960
  	}
a534c8d15   Aneesh Kumar K.V   fs/9p: Prevent pa...
961
  	down_write(&v9ses->rename_sem);
4681dbdac   Sripathi Kodi   9p: add 9P2000.L ...
962
  	if (v9fs_proto_dotl(v9ses)) {
9e8fb38e7   Aneesh Kumar K.V   fs/9p: add 9P2000...
963
964
965
966
967
968
  		retval = p9_client_renameat(olddirfid, old_dentry->d_name.name,
  					    newdirfid, new_dentry->d_name.name);
  		if (retval == -EOPNOTSUPP)
  			retval = p9_client_rename(oldfid, newdirfid,
  						  new_dentry->d_name.name);
  		if (retval != -EOPNOTSUPP)
4681dbdac   Sripathi Kodi   9p: add 9P2000.L ...
969
970
  			goto clunk_newdir;
  	}
a534c8d15   Aneesh Kumar K.V   fs/9p: Prevent pa...
971
972
973
974
  	if (old_dentry->d_parent != new_dentry->d_parent) {
  		/*
  		 * 9P .u can only handle file rename in the same directory
  		 */
4681dbdac   Sripathi Kodi   9p: add 9P2000.L ...
975

5d3851530   Joe Perches   9p: Reduce object...
976
977
  		p9_debug(P9_DEBUG_ERROR, "old dir and new dir are different
  ");
621997cd3   Eric Van Hensbergen   [PATCH] 9p: fix r...
978
  		retval = -EXDEV;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
979
  		goto clunk_newdir;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
980
  	}
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
981
  	v9fs_blank_wstat(&wstat);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
982
  	wstat.muid = v9ses->uname;
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
983
  	wstat.name = (char *) new_dentry->d_name.name;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
984
  	retval = p9_client_wstat(oldfid, &wstat);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
985

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
986
  clunk_newdir:
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
987
988
989
990
991
992
993
994
995
996
997
998
  	if (!retval) {
  		if (new_inode) {
  			if (S_ISDIR(new_inode->i_mode))
  				clear_nlink(new_inode);
  			else
  				drop_nlink(new_inode);
  		}
  		if (S_ISDIR(old_inode->i_mode)) {
  			if (!new_inode)
  				inc_nlink(new_dir);
  			drop_nlink(old_dir);
  		}
3bc86de31   Aneesh Kumar K.V   fs/9p: mark inode...
999
  		v9fs_invalidate_inode_attr(old_inode);
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
1000
1001
  		v9fs_invalidate_inode_attr(old_dir);
  		v9fs_invalidate_inode_attr(new_dir);
3bc86de31   Aneesh Kumar K.V   fs/9p: mark inode...
1002

a534c8d15   Aneesh Kumar K.V   fs/9p: Prevent pa...
1003
1004
  		/* successful rename */
  		d_move(old_dentry, new_dentry);
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
1005
  	}
a534c8d15   Aneesh Kumar K.V   fs/9p: Prevent pa...
1006
  	up_write(&v9ses->rename_sem);
22150c4f0   Latchesar Ionkov   9p: v9fs_vfs_rena...
1007
  	p9_client_clunk(newdirfid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1008

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1009
  clunk_olddir:
22150c4f0   Latchesar Ionkov   9p: v9fs_vfs_rena...
1010
  	p9_client_clunk(olddirfid);
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1011

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1012
  done:
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1013
1014
1015
1016
  	return retval;
  }
  
  /**
943ffb587   Adrian Bunk   spelling: s/retre...
1017
   * v9fs_vfs_getattr - retrieve file metadata
ee443996a   Eric Van Hensbergen   9p: Documentation...
1018
1019
1020
   * @mnt: mount information
   * @dentry: file to get attributes on
   * @stat: metadata structure to populate
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1021
1022
1023
1024
1025
1026
1027
   *
   */
  
  static int
  v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
  		 struct kstat *stat)
  {
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1028
1029
1030
  	int err;
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *fid;
51a87c552   Eric Van Hensbergen   9p: rework client...
1031
  	struct p9_wstat *st;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1032

5d3851530   Joe Perches   9p: Reduce object...
1033
1034
  	p9_debug(P9_DEBUG_VFS, "dentry: %p
  ", dentry);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1035
  	err = -EPERM;
42869c8ad   Aneesh Kumar K.V   fs/9p: Add v9fs_d...
1036
  	v9ses = v9fs_dentry2v9ses(dentry);
a12119087   Aneesh Kumar K.V   fs/9p: Don't set ...
1037
1038
1039
1040
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
  		generic_fillattr(dentry->d_inode, stat);
  		return 0;
  	}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1041
1042
  	fid = v9fs_fid_lookup(dentry);
  	if (IS_ERR(fid))
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1043
  		return PTR_ERR(fid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1044

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1045
1046
1047
  	st = p9_client_stat(fid);
  	if (IS_ERR(st))
  		return PTR_ERR(st);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1048

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1049
  	v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
1050
  	generic_fillattr(dentry->d_inode, stat);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1051

62b2be591   Latchesar Ionkov   fs/9p, net/9p: me...
1052
  	p9stat_free(st);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1053
1054
  	kfree(st);
  	return 0;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
  }
  
  /**
   * v9fs_vfs_setattr - set file metadata
   * @dentry: file whose metadata to set
   * @iattr: metadata assignment structure
   *
   */
  
  static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
  {
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1066
1067
1068
1069
  	int retval;
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *fid;
  	struct p9_wstat wstat;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1070

5d3851530   Joe Perches   9p: Reduce object...
1071
1072
  	p9_debug(P9_DEBUG_VFS, "
  ");
059c138bc   Aneesh Kumar K.V   fs/9p: Use trunca...
1073
1074
1075
  	retval = inode_change_ok(dentry->d_inode, iattr);
  	if (retval)
  		return retval;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1076
  	retval = -EPERM;
42869c8ad   Aneesh Kumar K.V   fs/9p: Add v9fs_d...
1077
  	v9ses = v9fs_dentry2v9ses(dentry);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1078
  	fid = v9fs_fid_lookup(dentry);
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1079
1080
  	if(IS_ERR(fid))
  		return PTR_ERR(fid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1081

531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1082
  	v9fs_blank_wstat(&wstat);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1083
  	if (iattr->ia_valid & ATTR_MODE)
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1084
  		wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1085
1086
  
  	if (iattr->ia_valid & ATTR_MTIME)
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1087
  		wstat.mtime = iattr->ia_mtime.tv_sec;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1088
1089
  
  	if (iattr->ia_valid & ATTR_ATIME)
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1090
  		wstat.atime = iattr->ia_atime.tv_sec;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1091
1092
  
  	if (iattr->ia_valid & ATTR_SIZE)
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1093
  		wstat.length = iattr->ia_size;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1094

dd6102fbd   Sripathi Kodi   9P2010.L handshak...
1095
  	if (v9fs_proto_dotu(v9ses)) {
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1096
1097
  		if (iattr->ia_valid & ATTR_UID)
  			wstat.n_uid = iattr->ia_uid;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1098

531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1099
1100
  		if (iattr->ia_valid & ATTR_GID)
  			wstat.n_gid = iattr->ia_gid;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1101
  	}
059c138bc   Aneesh Kumar K.V   fs/9p: Use trunca...
1102

3dc5436aa   Aneesh Kumar K.V   fs/9p: Writeback ...
1103
1104
1105
  	/* Write all dirty data */
  	if (S_ISREG(dentry->d_inode->i_mode))
  		filemap_write_and_wait(dentry->d_inode->i_mapping);
f10fc50f1   Aneesh Kumar K.V   fs/9p: call vmtru...
1106
1107
1108
  	retval = p9_client_wstat(fid, &wstat);
  	if (retval < 0)
  		return retval;
059c138bc   Aneesh Kumar K.V   fs/9p: Use trunca...
1109
1110
1111
1112
  
  	if ((iattr->ia_valid & ATTR_SIZE) &&
  	    iattr->ia_size != i_size_read(dentry->d_inode))
  		truncate_setsize(dentry->d_inode, iattr->ia_size);
f10fc50f1   Aneesh Kumar K.V   fs/9p: call vmtru...
1113
  	v9fs_invalidate_inode_attr(dentry->d_inode);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1114

1025774ce   Christoph Hellwig   remove inode_setattr
1115
1116
1117
  	setattr_copy(dentry->d_inode, iattr);
  	mark_inode_dirty(dentry->d_inode);
  	return 0;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1118
1119
1120
  }
  
  /**
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1121
1122
   * v9fs_stat2inode - populate an inode structure with mistat info
   * @stat: Plan 9 metadata (mistat) structure
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1123
1124
1125
1126
1127
1128
   * @inode: inode to populate
   * @sb: superblock of filesystem
   *
   */
  
  void
51a87c552   Eric Van Hensbergen   9p: rework client...
1129
  v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1130
  	struct super_block *sb)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1131
  {
3eda0de67   Al Viro   9p: propagate umo...
1132
  	umode_t mode;
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1133
  	char ext[32];
5717144a0   Aneesh Kumar K.V   fs/9p: Add hardli...
1134
1135
  	char tag_name[14];
  	unsigned int i_nlink;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1136
  	struct v9fs_session_info *v9ses = sb->s_fs_info;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
1137
  	struct v9fs_inode *v9inode = V9FS_I(inode);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1138

bfe868486   Miklos Szeredi   filesystems: add ...
1139
  	set_nlink(inode, 1);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1140

531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1141
1142
1143
  	inode->i_atime.tv_sec = stat->atime;
  	inode->i_mtime.tv_sec = stat->mtime;
  	inode->i_ctime.tv_sec = stat->mtime;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1144

bd32b82df   Latchesar Ionkov   9p: rename uid an...
1145
1146
  	inode->i_uid = v9ses->dfltuid;
  	inode->i_gid = v9ses->dfltgid;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1147

dd6102fbd   Sripathi Kodi   9P2010.L handshak...
1148
  	if (v9fs_proto_dotu(v9ses)) {
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1149
1150
  		inode->i_uid = stat->n_uid;
  		inode->i_gid = stat->n_gid;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1151
  	}
5717144a0   Aneesh Kumar K.V   fs/9p: Add hardli...
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
  	if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
  		if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) {
  			/*
  			 * Hadlink support got added later to
  			 * to the .u extension. So there can be
  			 * server out there that doesn't support
  			 * this even with .u extension. So check
  			 * for non NULL stat->extension
  			 */
  			strncpy(ext, stat->extension, sizeof(ext));
  			/* HARDLINKCOUNT %u */
  			sscanf(ext, "%13s %u", tag_name, &i_nlink);
  			if (!strncmp(tag_name, "HARDLINKCOUNT", 13))
bfe868486   Miklos Szeredi   filesystems: add ...
1165
  				set_nlink(inode, i_nlink);
5717144a0   Aneesh Kumar K.V   fs/9p: Add hardli...
1166
1167
  		}
  	}
df345c674   Aneesh Kumar K.V   fs/9p: v9fs_stat2...
1168
  	mode = p9mode2perm(v9ses, stat);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
1169
1170
  	mode |= inode->i_mode & ~S_IALLUGO;
  	inode->i_mode = mode;
7549ae3e8   Abhishek Kulkarni   9p: Use the i_siz...
1171
  	i_size_write(inode, stat->length);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1172

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1173
  	/* not real number of blocks, but 512 byte ones ... */
7549ae3e8   Abhishek Kulkarni   9p: Use the i_siz...
1174
  	inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
1175
  	v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1176
1177
1178
1179
1180
1181
1182
1183
  }
  
  /**
   * v9fs_qid2ino - convert qid into inode number
   * @qid: qid to hash
   *
   * BUG: potential for inode number collisions?
   */
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1184
  ino_t v9fs_qid2ino(struct p9_qid *qid)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
  {
  	u64 path = qid->path + 2;
  	ino_t i = 0;
  
  	if (sizeof(ino_t) == sizeof(path))
  		memcpy(&i, &path, sizeof(ino_t));
  	else
  		i = (ino_t) (path ^ (path >> 32));
  
  	return i;
  }
  
  /**
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1198
1199
   * v9fs_readlink - read a symlink's location (internal version)
   * @dentry: dentry for symlink
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
1200
   * @buffer: buffer to load symlink location into
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1201
1202
1203
1204
1205
1206
   * @buflen: length of buffer
   *
   */
  
  static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
  {
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1207
  	int retval;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1208

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1209
1210
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *fid;
51a87c552   Eric Van Hensbergen   9p: rework client...
1211
  	struct p9_wstat *st;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1212

5d3851530   Joe Perches   9p: Reduce object...
1213
1214
  	p9_debug(P9_DEBUG_VFS, " %s
  ", dentry->d_name.name);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1215
  	retval = -EPERM;
42869c8ad   Aneesh Kumar K.V   fs/9p: Add v9fs_d...
1216
  	v9ses = v9fs_dentry2v9ses(dentry);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1217
  	fid = v9fs_fid_lookup(dentry);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
1218
  	if (IS_ERR(fid))
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1219
  		return PTR_ERR(fid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1220

329176cc2   M. Mohan Kumar   9p: Implement TRE...
1221
  	if (!v9fs_proto_dotu(v9ses))
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1222
  		return -EBADF;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1223

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1224
1225
1226
  	st = p9_client_stat(fid);
  	if (IS_ERR(st))
  		return PTR_ERR(st);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1227

bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1228
  	if (!(st->mode & P9_DMSYMLINK)) {
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1229
  		retval = -EINVAL;
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1230
  		goto done;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1231
1232
1233
  	}
  
  	/* copy extension buffer into buffer */
51a87c552   Eric Van Hensbergen   9p: rework client...
1234
  	strncpy(buffer, st->extension, buflen);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1235

5d3851530   Joe Perches   9p: Reduce object...
1236
1237
1238
  	p9_debug(P9_DEBUG_VFS, "%s -> %s (%s)
  ",
  		 dentry->d_name.name, st->extension, buffer);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1239

2511cd0b3   Martin Stava   9p: fix readlink
1240
  	retval = strnlen(buffer, buflen);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1241
  done:
62b2be591   Latchesar Ionkov   fs/9p, net/9p: me...
1242
  	p9stat_free(st);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1243
  	kfree(st);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1244
1245
1246
1247
  	return retval;
  }
  
  /**
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
   * v9fs_vfs_follow_link - follow a symlink path
   * @dentry: dentry for symlink
   * @nd: nameidata
   *
   */
  
  static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
  {
  	int len = 0;
  	char *link = __getname();
5d3851530   Joe Perches   9p: Reduce object...
1258
1259
  	p9_debug(P9_DEBUG_VFS, "%s
  ", dentry->d_name.name);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1260
1261
1262
1263
  
  	if (!link)
  		link = ERR_PTR(-ENOMEM);
  	else {
16cce6d27   Latchesar Ionkov   [PATCH] v9fs: add...
1264
  		len = v9fs_readlink(dentry, link, PATH_MAX);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1265
1266
  
  		if (len < 0) {
ce44eeb69   Davi Arnaut   [PATCH] V9FS: 'na...
1267
  			__putname(link);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1268
1269
  			link = ERR_PTR(len);
  		} else
2511cd0b3   Martin Stava   9p: fix readlink
1270
  			link[min(len, PATH_MAX-1)] = 0;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
  	}
  	nd_set_link(nd, link);
  
  	return NULL;
  }
  
  /**
   * v9fs_vfs_put_link - release a symlink path
   * @dentry: dentry for symlink
   * @nd: nameidata
ee443996a   Eric Van Hensbergen   9p: Documentation...
1281
   * @p: unused
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1282
1283
   *
   */
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
1284
  void
ee443996a   Eric Van Hensbergen   9p: Documentation...
1285
  v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1286
1287
  {
  	char *s = nd_get_link(nd);
5d3851530   Joe Perches   9p: Reduce object...
1288
1289
1290
  	p9_debug(P9_DEBUG_VFS, " %s %s
  ",
  		 dentry->d_name.name, IS_ERR(s) ? "<error>" : s);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1291
  	if (!IS_ERR(s))
ce44eeb69   Davi Arnaut   [PATCH] V9FS: 'na...
1292
  		__putname(s);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1293
  }
ee443996a   Eric Van Hensbergen   9p: Documentation...
1294
1295
1296
1297
1298
1299
1300
1301
  /**
   * v9fs_vfs_mkspecial - create a special file
   * @dir: inode to create special file in
   * @dentry: dentry to create
   * @mode: mode to create special file
   * @extension: 9p2000.u format extension string representing special file
   *
   */
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1302
  static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
c2837de73   Al Viro   9p: don't bother ...
1303
  	u32 perm, const char *extension)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1304
  {
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1305
  	struct p9_fid *fid;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
1306
  	struct v9fs_session_info *v9ses;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1307

6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
1308
  	v9ses = v9fs_inode2v9ses(dir);
dd6102fbd   Sripathi Kodi   9P2010.L handshak...
1309
  	if (!v9fs_proto_dotu(v9ses)) {
5d3851530   Joe Perches   9p: Reduce object...
1310
1311
  		p9_debug(P9_DEBUG_ERROR, "not extended
  ");
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
1312
  		return -EPERM;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1313
  	}
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1314
1315
1316
1317
  	fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm,
  								P9_OREAD);
  	if (IS_ERR(fid))
  		return PTR_ERR(fid);
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1318

d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
1319
  	v9fs_invalidate_inode_attr(dir);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1320
  	p9_client_clunk(fid);
6a3124a39   Latchesar Ionkov   [PATCH] v9fs: fix...
1321
  	return 0;
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1322
1323
1324
1325
1326
1327
1328
1329
  }
  
  /**
   * v9fs_vfs_symlink - helper function to create symlinks
   * @dir: directory inode containing symlink
   * @dentry: dentry for symlink
   * @symname: symlink data
   *
ee443996a   Eric Van Hensbergen   9p: Documentation...
1330
   * See Also: 9P2000.u RFC for more information
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1331
1332
1333
1334
1335
1336
   *
   */
  
  static int
  v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
  {
5d3851530   Joe Perches   9p: Reduce object...
1337
1338
1339
  	p9_debug(P9_DEBUG_VFS, " %lu,%s,%s
  ",
  		 dir->i_ino, dentry->d_name.name, symname);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1340

c2837de73   Al Viro   9p: don't bother ...
1341
  	return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1342
1343
1344
1345
1346
1347
1348
1349
1350
  }
  
  /**
   * v9fs_vfs_link - create a hardlink
   * @old_dentry: dentry for file to link to
   * @dir: inode destination for new link
   * @dentry: dentry for link
   *
   */
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1351
1352
1353
1354
1355
  static int
  v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
  	      struct dentry *dentry)
  {
  	int retval;
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1356
  	char *name;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
1357
  	struct p9_fid *oldfid;
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1358

5d3851530   Joe Perches   9p: Reduce object...
1359
1360
1361
  	p9_debug(P9_DEBUG_VFS, " %lu,%s,%s
  ",
  		 dir->i_ino, dentry->d_name.name, old_dentry->d_name.name);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1362

da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1363
  	oldfid = v9fs_fid_clone(old_dentry);
ba17674fe   Latchesar Ionkov   9p: attach-per-user
1364
  	if (IS_ERR(oldfid))
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1365
  		return PTR_ERR(oldfid);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1366
1367
  
  	name = __getname();
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1368
1369
1370
1371
  	if (unlikely(!name)) {
  		retval = -ENOMEM;
  		goto clunk_fid;
  	}
0710d36a0   Florin Malita   [PATCH] 9pfs: mis...
1372

16cce6d27   Latchesar Ionkov   [PATCH] v9fs: add...
1373
1374
  	sprintf(name, "%d
  ", oldfid->fid);
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1375
  	retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1376
  	__putname(name);
c06c066a0   Aneesh Kumar K.V   fs/9p: Properly u...
1377
1378
  	if (!retval) {
  		v9fs_refresh_inode(oldfid, old_dentry->d_inode);
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
1379
  		v9fs_invalidate_inode_attr(dir);
c06c066a0   Aneesh Kumar K.V   fs/9p: Properly u...
1380
  	}
da977b2c7   Eric Van Hensbergen   [PATCH] 9p: fix s...
1381
  clunk_fid:
bd238fb43   Latchesar Ionkov   9p: Reorganizatio...
1382
  	p9_client_clunk(oldfid);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1383
1384
1385
1386
1387
1388
1389
1390
  	return retval;
  }
  
  /**
   * v9fs_vfs_mknod - create a special file
   * @dir: inode destination for new link
   * @dentry: dentry for file
   * @mode: mode for creation
ee443996a   Eric Van Hensbergen   9p: Documentation...
1391
   * @rdev: device associated with special file
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1392
1393
1394
1395
   *
   */
  
  static int
1a67aafb5   Al Viro   switch ->mknod() ...
1396
  v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1397
  {
c2837de73   Al Viro   9p: don't bother ...
1398
  	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1399
1400
  	int retval;
  	char *name;
c2837de73   Al Viro   9p: don't bother ...
1401
  	u32 perm;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1402

609eac1c1   Linus Torvalds   Merge branch 'for...
1403
1404
  	p9_debug(P9_DEBUG_VFS, " %lu,%s mode: %hx MAJOR: %u MINOR: %u
  ",
5d3851530   Joe Perches   9p: Reduce object...
1405
1406
  		 dir->i_ino, dentry->d_name.name, mode,
  		 MAJOR(rdev), MINOR(rdev));
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1407

531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1408
1409
  	if (!new_valid_dev(rdev))
  		return -EINVAL;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1410

531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1411
  	name = __getname();
c0291a05f   Eugene Teo   [PATCH] v9fs: fix...
1412
1413
  	if (!name)
  		return -ENOMEM;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1414
1415
  	/* build extension */
  	if (S_ISBLK(mode))
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1416
  		sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1417
  	else if (S_ISCHR(mode))
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1418
  		sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
73c592b9b   Eric Van Hensbergen   [PATCH] v9fs: Cle...
1419
  	else if (S_ISFIFO(mode))
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1420
  		*name = 0;
75cc5c9b8   Venkateswararao Jujjuri   9p: Add mksock su...
1421
1422
  	else if (S_ISSOCK(mode))
  		*name = 0;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1423
  	else {
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1424
1425
  		__putname(name);
  		return -EINVAL;
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1426
  	}
c2837de73   Al Viro   9p: don't bother ...
1427
1428
  	perm = unixmode2p9mode(v9ses, mode);
  	retval = v9fs_vfs_mkspecial(dir, dentry, perm, name);
531b1094b   Latchesar Ionkov   [PATCH] v9fs: zer...
1429
  	__putname(name);
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1430
1431
1432
  
  	return retval;
  }
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
1433
1434
  int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
  {
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
1435
1436
  	int umode;
  	dev_t rdev;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
1437
1438
1439
1440
1441
1442
1443
1444
  	loff_t i_size;
  	struct p9_wstat *st;
  	struct v9fs_session_info *v9ses;
  
  	v9ses = v9fs_inode2v9ses(inode);
  	st = p9_client_stat(fid);
  	if (IS_ERR(st))
  		return PTR_ERR(st);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
1445
1446
1447
1448
1449
1450
  	/*
  	 * Don't update inode if the file type is different
  	 */
  	umode = p9mode2unixmode(v9ses, st, &rdev);
  	if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
  		goto out;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
  
  	spin_lock(&inode->i_lock);
  	/*
  	 * We don't want to refresh inode->i_size,
  	 * because we may have cached data
  	 */
  	i_size = inode->i_size;
  	v9fs_stat2inode(st, inode, inode->i_sb);
  	if (v9ses->cache)
  		inode->i_size = i_size;
  	spin_unlock(&inode->i_lock);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
1462
  out:
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
1463
1464
1465
1466
  	p9stat_free(st);
  	kfree(st);
  	return 0;
  }
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
1467
1468
1469
1470
  static const struct inode_operations v9fs_dir_inode_operations_dotu = {
  	.create = v9fs_vfs_create,
  	.lookup = v9fs_vfs_lookup,
  	.symlink = v9fs_vfs_symlink,
50cc42ff3   Venkateswararao Jujjuri (JV)   9p: Define and im...
1471
  	.link = v9fs_vfs_link,
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
1472
1473
1474
  	.unlink = v9fs_vfs_unlink,
  	.mkdir = v9fs_vfs_mkdir,
  	.rmdir = v9fs_vfs_rmdir,
1d76e3135   Aneesh Kumar K.V   fs/9p: Don't use ...
1475
  	.mknod = v9fs_vfs_mknod,
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
1476
1477
1478
1479
  	.rename = v9fs_vfs_rename,
  	.getattr = v9fs_vfs_getattr,
  	.setattr = v9fs_vfs_setattr,
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
1480
  static const struct inode_operations v9fs_dir_inode_operations = {
b501611a6   Eric Van Hensbergen   [PATCH] v9fs: rea...
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
  	.create = v9fs_vfs_create,
  	.lookup = v9fs_vfs_lookup,
  	.unlink = v9fs_vfs_unlink,
  	.mkdir = v9fs_vfs_mkdir,
  	.rmdir = v9fs_vfs_rmdir,
  	.mknod = v9fs_vfs_mknod,
  	.rename = v9fs_vfs_rename,
  	.getattr = v9fs_vfs_getattr,
  	.setattr = v9fs_vfs_setattr,
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
1491
  static const struct inode_operations v9fs_file_inode_operations = {
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1492
1493
1494
  	.getattr = v9fs_vfs_getattr,
  	.setattr = v9fs_vfs_setattr,
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
1495
  static const struct inode_operations v9fs_symlink_inode_operations = {
204f2f0e8   Al Viro   Kill 9p readlink()
1496
  	.readlink = generic_readlink,
2bad84715   Eric Van Hensbergen   [PATCH] v9fs: VFS...
1497
1498
1499
1500
1501
  	.follow_link = v9fs_vfs_follow_link,
  	.put_link = v9fs_vfs_put_link,
  	.getattr = v9fs_vfs_getattr,
  	.setattr = v9fs_vfs_setattr,
  };
9b6533c9b   Sripathi Kodi   9p: VFS switches ...
1502