Blame view

fs/9p/vfs_inode_dotl.c 24.4 KB
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  /*
   *  linux/fs/9p/vfs_inode_dotl.c
   *
   * This file contains vfs inode ops for the 9P2000.L protocol.
   *
   *  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
   *  it under the terms of the GNU General Public License version 2
   *  as published by the Free Software Foundation.
   *
   *  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
   *
   */
  
  #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>
  #include <linux/inet.h>
  #include <linux/namei.h>
  #include <linux/idr.h>
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/xattr.h>
  #include <linux/posix_acl.h>
  #include <net/9p/9p.h>
  #include <net/9p/client.h>
  
  #include "v9fs.h"
  #include "v9fs_vfs.h"
  #include "fid.h"
  #include "cache.h"
  #include "xattr.h"
  #include "acl.h"
  
  static int
1a67aafb5   Al Viro   switch ->mknod() ...
51
  v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
52
53
54
55
56
57
58
  		    dev_t rdev);
  
  /**
   * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
   * new file system object. This checks the S_ISGID to determine the owning
   * group of the new file system object.
   */
d4ef4e358   Eric W. Biederman   9p: Modify v9fs_g...
59
  static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
60
61
62
63
64
65
66
67
68
  {
  	BUG_ON(dir_inode == NULL);
  
  	if (dir_inode->i_mode & S_ISGID) {
  		/* set_gid bit is set.*/
  		return dir_inode->i_gid;
  	}
  	return current_fsgid();
  }
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  static int v9fs_test_inode_dotl(struct inode *inode, void *data)
  {
  	struct v9fs_inode *v9inode = V9FS_I(inode);
  	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  
  	/* don't match inode of different type */
  	if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
  		return 0;
  
  	if (inode->i_generation != st->st_gen)
  		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...
90
91
92
93
94
  /* Always get a new inode */
  static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
  {
  	return 0;
  }
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
95
96
97
98
99
100
101
102
103
  static int v9fs_set_inode_dotl(struct inode *inode,  void *data)
  {
  	struct v9fs_inode *v9inode = V9FS_I(inode);
  	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  
  	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
  	inode->i_generation = st->st_gen;
  	return 0;
  }
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
104
105
106
  static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
  					struct p9_qid *qid,
  					struct p9_fid *fid,
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
107
108
  					struct p9_stat_dotl *st,
  					int new)
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
109
110
111
112
113
  {
  	int retval;
  	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...
114
115
116
117
118
119
  	int (*test)(struct inode *, void *);
  
  	if (new)
  		test = v9fs_test_new_inode_dotl;
  	else
  		test = v9fs_test_inode_dotl;
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
120
121
  
  	i_ino = v9fs_qid2ino(qid);
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
122
  	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
123
124
125
126
127
128
129
130
131
  	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...
132
  	inode->i_ino = i_ino;
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
133
134
  	retval = v9fs_init_inode(v9ses, inode,
  				 st->st_mode, new_decode_dev(st->st_rdev));
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
135
136
137
138
  	if (retval)
  		goto error;
  
  	v9fs_stat2inode_dotl(st, inode);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
139
  	v9fs_cache_inode_get_cookie(inode);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
140
141
142
143
144
145
146
  	retval = v9fs_get_acl(inode, fid);
  	if (retval)
  		goto error;
  
  	unlock_new_inode(inode);
  	return inode;
  error:
0a73d0a20   Al Viro   9p: don't leave a...
147
  	iget_failed(inode);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
148
149
150
  	return ERR_PTR(retval);
  
  }
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
151
  struct inode *
a78ce05d5   Aneesh Kumar K.V   fs/9p: Add v9fs_i...
152
  v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
153
  			 struct super_block *sb, int new)
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
154
  {
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
155
  	struct p9_stat_dotl *st;
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
156
  	struct inode *inode = NULL;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
157

fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
158
  	st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
159
160
  	if (IS_ERR(st))
  		return ERR_CAST(st);
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
161
  	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
162
  	kfree(st);
5ffc0cb30   Aneesh Kumar K.V   fs/9p: Add inode ...
163
  	return inode;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
164
  }
f88657ce3   Aneesh Kumar K.V   fs/9p: Add OS dep...
165
166
167
168
169
170
171
172
173
174
175
176
177
  struct dotl_openflag_map {
  	int open_flag;
  	int dotl_flag;
  };
  
  static int v9fs_mapped_dotl_flags(int flags)
  {
  	int i;
  	int rflags = 0;
  	struct dotl_openflag_map dotl_oflag_map[] = {
  		{ O_CREAT,	P9_DOTL_CREATE },
  		{ O_EXCL,	P9_DOTL_EXCL },
  		{ O_NOCTTY,	P9_DOTL_NOCTTY },
f88657ce3   Aneesh Kumar K.V   fs/9p: Add OS dep...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
  		{ O_APPEND,	P9_DOTL_APPEND },
  		{ O_NONBLOCK,	P9_DOTL_NONBLOCK },
  		{ O_DSYNC,	P9_DOTL_DSYNC },
  		{ FASYNC,	P9_DOTL_FASYNC },
  		{ O_DIRECT,	P9_DOTL_DIRECT },
  		{ O_LARGEFILE,	P9_DOTL_LARGEFILE },
  		{ O_DIRECTORY,	P9_DOTL_DIRECTORY },
  		{ O_NOFOLLOW,	P9_DOTL_NOFOLLOW },
  		{ O_NOATIME,	P9_DOTL_NOATIME },
  		{ O_CLOEXEC,	P9_DOTL_CLOEXEC },
  		{ O_SYNC,	P9_DOTL_SYNC},
  	};
  	for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
  		if (flags & dotl_oflag_map[i].open_flag)
  			rflags |= dotl_oflag_map[i].dotl_flag;
  	}
  	return rflags;
  }
  
  /**
   * v9fs_open_to_dotl_flags- convert Linux specific open flags to
   * plan 9 open flag.
   * @flags: flags to convert
   */
  int v9fs_open_to_dotl_flags(int flags)
  {
  	int rflags = 0;
  
  	/*
  	 * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
  	 * and P9_DOTL_NOACCESS
  	 */
  	rflags |= flags & O_ACCMODE;
  	rflags |= v9fs_mapped_dotl_flags(flags);
  
  	return rflags;
  }
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
215
216
217
218
  /**
   * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
   * @dir: directory inode that is being created
   * @dentry:  dentry that is being deleted
fd2916bd7   Fabian Frederick   fs/9p: kerneldoc ...
219
   * @omode: create permissions
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
220
221
222
223
   *
   */
  
  static int
4acdaf27e   Al Viro   switch ->create()...
224
  v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
ebfc3b49a   Al Viro   don't pass nameid...
225
  		bool excl)
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
226
  {
e43ae79c5   Miklos Szeredi   9p: implement i_o...
227
228
  	return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
  }
d95852777   Al Viro   make ->atomic_ope...
229
  static int
e43ae79c5   Miklos Szeredi   9p: implement i_o...
230
  v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
30d904947   Al Viro   kill struct opendata
231
  			  struct file *file, unsigned flags, umode_t omode,
47237687d   Al Viro   ->atomic_open() p...
232
  			  int *opened)
e43ae79c5   Miklos Szeredi   9p: implement i_o...
233
  {
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
234
  	int err = 0;
d4ef4e358   Eric W. Biederman   9p: Modify v9fs_g...
235
  	kgid_t gid;
d3fb61207   Al Viro   switch posix_acl_...
236
  	umode_t mode;
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
237
  	char *name = NULL;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
238
239
  	struct p9_qid qid;
  	struct inode *inode;
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
240
241
242
243
  	struct p9_fid *fid = NULL;
  	struct v9fs_inode *v9inode;
  	struct p9_fid *dfid, *ofid, *inode_fid;
  	struct v9fs_session_info *v9ses;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
244
  	struct posix_acl *pacl = NULL, *dacl = NULL;
e43ae79c5   Miklos Szeredi   9p: implement i_o...
245
  	struct dentry *res = NULL;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
246

00699ad85   Al Viro   Use the right pre...
247
  	if (d_in_lookup(dentry)) {
00cd8dd3b   Al Viro   stop passing name...
248
  		res = v9fs_vfs_lookup(dir, dentry, 0);
e43ae79c5   Miklos Szeredi   9p: implement i_o...
249
  		if (IS_ERR(res))
d95852777   Al Viro   make ->atomic_ope...
250
  			return PTR_ERR(res);
e43ae79c5   Miklos Szeredi   9p: implement i_o...
251
252
253
254
255
256
  
  		if (res)
  			dentry = res;
  	}
  
  	/* Only creates */
2b0143b5c   David Howells   VFS: normal files...
257
  	if (!(flags & O_CREAT) || d_really_is_positive(dentry))
b6f4bee02   M. Mohan Kumar   fs/9p: Fix atomic...
258
  		return	finish_no_open(file, res);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
259

e43ae79c5   Miklos Szeredi   9p: implement i_o...
260
  	v9ses = v9fs_inode2v9ses(dir);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
261
  	name = (char *) dentry->d_name.name;
609eac1c1   Linus Torvalds   Merge branch 'for...
262
263
  	p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx
  ",
5d3851530   Joe Perches   9p: Reduce object...
264
  		 name, flags, omode);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
265

77d5a6b7d   Al Viro   9p: new helper - ...
266
  	dfid = v9fs_parent_fid(dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
267
268
  	if (IS_ERR(dfid)) {
  		err = PTR_ERR(dfid);
5d3851530   Joe Perches   9p: Reduce object...
269
270
  		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d
  ", err);
d95852777   Al Viro   make ->atomic_ope...
271
  		goto out;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
272
273
274
  	}
  
  	/* clone a fid to use for creation */
7d50a29fe   Al Viro   9p: use clone_fid()
275
  	ofid = clone_fid(dfid);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
276
277
  	if (IS_ERR(ofid)) {
  		err = PTR_ERR(ofid);
5d3851530   Joe Perches   9p: Reduce object...
278
279
  		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d
  ", err);
d95852777   Al Viro   make ->atomic_ope...
280
  		goto out;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
281
282
283
284
285
286
287
288
  	}
  
  	gid = v9fs_get_fsgid_for_create(dir);
  
  	mode = omode;
  	/* Update mode based on ACL value */
  	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
  	if (err) {
5d3851530   Joe Perches   9p: Reduce object...
289
290
291
  		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d
  ",
  			 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
292
293
  		goto error;
  	}
f88657ce3   Aneesh Kumar K.V   fs/9p: Add OS dep...
294
295
  	err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
  				    mode, gid, &qid);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
296
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
297
298
299
  		p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d
  ",
  			 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
300
301
  		goto error;
  	}
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
302
  	v9fs_invalidate_inode_attr(dir);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
303

af7542fc8   Aneesh Kumar K.V   fs/9p: Simplify t...
304
305
306
307
  	/* instantiate inode and assign the unopened fid to the dentry */
  	fid = p9_client_walk(dfid, 1, &name, 1);
  	if (IS_ERR(fid)) {
  		err = PTR_ERR(fid);
5d3851530   Joe Perches   9p: Reduce object...
308
309
  		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d
  ", err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
310
  		fid = NULL;
af7542fc8   Aneesh Kumar K.V   fs/9p: Simplify t...
311
  		goto error;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
312
  	}
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
313
  	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
af7542fc8   Aneesh Kumar K.V   fs/9p: Simplify t...
314
315
  	if (IS_ERR(inode)) {
  		err = PTR_ERR(inode);
5d3851530   Joe Perches   9p: Reduce object...
316
317
  		p9_debug(P9_DEBUG_VFS, "inode creation failed %d
  ", err);
af7542fc8   Aneesh Kumar K.V   fs/9p: Simplify t...
318
319
  		goto error;
  	}
3592ac444   Al Viro   9p: switch v9fs_s...
320
321
  	/* Now set the ACL based on the default value */
  	v9fs_set_create_acl(inode, fid, dacl, pacl);
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
322
  	v9fs_fid_add(dentry, fid);
5441ae5eb   Aneesh Kumar K.V   fs/9p: Add fid be...
323
  	d_instantiate(dentry, inode);
af7542fc8   Aneesh Kumar K.V   fs/9p: Simplify t...
324

6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
325
  	v9inode = V9FS_I(inode);
5a7e0a8cf   Aneesh Kumar K.V   fs/9p: Fix race i...
326
  	mutex_lock(&v9inode->v_mutex);
fb89b45cd   Dominique Martinet   9P: introduction ...
327
328
  	if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
  	    !v9inode->writeback_fid &&
7add697a3   Aneesh Kumar K.V   fs/9p: Attach wri...
329
  	    ((flags & O_ACCMODE) != O_RDONLY)) {
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
330
  		/*
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
331
  		 * clone a fid and add it to writeback_fid
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
332
333
334
335
336
337
338
339
  		 * 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...
340
  			mutex_unlock(&v9inode->v_mutex);
398c4f0ef   Aneesh Kumar K.V   fs/9p: Don't clun...
341
  			goto err_clunk_old_fid;
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
342
  		}
6b39f6d22   Aneesh Kumar K.V   fs/9p: Move write...
343
  		v9inode->writeback_fid = (void *) inode_fid;
3cf387d78   Aneesh Kumar K.V   fs/9p: Add fid to...
344
  	}
5a7e0a8cf   Aneesh Kumar K.V   fs/9p: Fix race i...
345
  	mutex_unlock(&v9inode->v_mutex);
af7542fc8   Aneesh Kumar K.V   fs/9p: Simplify t...
346
  	/* Since we are opening a file, assign the open fid to the file */
30d904947   Al Viro   kill struct opendata
347
348
  	err = finish_open(file, dentry, generic_file_open, opened);
  	if (err)
398c4f0ef   Aneesh Kumar K.V   fs/9p: Don't clun...
349
  		goto err_clunk_old_fid;
30d904947   Al Viro   kill struct opendata
350
  	file->private_data = ofid;
fb89b45cd   Dominique Martinet   9P: introduction ...
351
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
30d904947   Al Viro   kill struct opendata
352
  		v9fs_cache_inode_set_cookie(inode, file);
47237687d   Al Viro   ->atomic_open() p...
353
  	*opened |= FILE_CREATED;
e43ae79c5   Miklos Szeredi   9p: implement i_o...
354
  out:
5fa6300ae   Al Viro   9p: split droppin...
355
  	v9fs_put_acl(dacl, pacl);
e43ae79c5   Miklos Szeredi   9p: implement i_o...
356
  	dput(res);
d95852777   Al Viro   make ->atomic_ope...
357
  	return err;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
358
359
  
  error:
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
360
361
  	if (fid)
  		p9_client_clunk(fid);
398c4f0ef   Aneesh Kumar K.V   fs/9p: Don't clun...
362
363
364
  err_clunk_old_fid:
  	if (ofid)
  		p9_client_clunk(ofid);
e43ae79c5   Miklos Szeredi   9p: implement i_o...
365
  	goto out;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
366
367
368
369
370
371
  }
  
  /**
   * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
   * @dir:  inode that is being unlinked
   * @dentry: dentry that is being unlinked
fd2916bd7   Fabian Frederick   fs/9p: kerneldoc ...
372
   * @omode: mode for new directory
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
373
374
375
376
   *
   */
  
  static int v9fs_vfs_mkdir_dotl(struct inode *dir,
18bb1db3e   Al Viro   switch vfs_mkdir(...
377
  			       struct dentry *dentry, umode_t omode)
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
378
379
380
381
  {
  	int err;
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *fid = NULL, *dfid = NULL;
d4ef4e358   Eric W. Biederman   9p: Modify v9fs_g...
382
  	kgid_t gid;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
383
  	char *name;
d3fb61207   Al Viro   switch posix_acl_...
384
  	umode_t mode;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
385
386
  	struct inode *inode;
  	struct p9_qid qid;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
387
  	struct posix_acl *dacl = NULL, *pacl = NULL;
4b8e99239   Al Viro   9p: switch to %p[dD]
388
389
  	p9_debug(P9_DEBUG_VFS, "name %pd
  ", dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
390
391
392
393
394
395
  	err = 0;
  	v9ses = v9fs_inode2v9ses(dir);
  
  	omode |= S_IFDIR;
  	if (dir->i_mode & S_ISGID)
  		omode |= S_ISGID;
77d5a6b7d   Al Viro   9p: new helper - ...
396
  	dfid = v9fs_parent_fid(dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
397
398
  	if (IS_ERR(dfid)) {
  		err = PTR_ERR(dfid);
5d3851530   Joe Perches   9p: Reduce object...
399
400
  		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d
  ", err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
401
402
403
404
405
406
407
408
409
  		dfid = NULL;
  		goto error;
  	}
  
  	gid = v9fs_get_fsgid_for_create(dir);
  	mode = omode;
  	/* Update mode based on ACL value */
  	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
  	if (err) {
5d3851530   Joe Perches   9p: Reduce object...
410
411
412
  		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d
  ",
  			 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
413
414
415
416
417
418
  		goto error;
  	}
  	name = (char *) dentry->d_name.name;
  	err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
  	if (err < 0)
  		goto error;
3592ac444   Al Viro   9p: switch v9fs_s...
419
420
421
422
423
424
425
426
427
  	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;
  	}
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
428
429
  	/* instantiate inode and assign the unopened fid to the dentry */
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
430
  		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
431
432
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
5d3851530   Joe Perches   9p: Reduce object...
433
434
435
  			p9_debug(P9_DEBUG_VFS, "inode creation failed %d
  ",
  				 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
436
437
  			goto error;
  		}
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
438
  		v9fs_fid_add(dentry, fid);
3592ac444   Al Viro   9p: switch v9fs_s...
439
  		v9fs_set_create_acl(inode, fid, dacl, pacl);
5441ae5eb   Aneesh Kumar K.V   fs/9p: Add fid be...
440
  		d_instantiate(dentry, inode);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
441
  		fid = NULL;
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
442
  		err = 0;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
443
444
445
446
447
448
  	} else {
  		/*
  		 * Not in cached mode. No need to populate
  		 * inode with stat. We need to get an inode
  		 * so that we can set the acl with dentry
  		 */
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
449
  		inode = v9fs_get_inode(dir->i_sb, mode, 0);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
450
451
452
453
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
  			goto error;
  		}
3592ac444   Al Viro   9p: switch v9fs_s...
454
  		v9fs_set_create_acl(inode, fid, dacl, pacl);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
455
456
  		d_instantiate(dentry, inode);
  	}
b271ec47b   Aneesh Kumar K.V   fs/9p: Update lin...
457
  	inc_nlink(dir);
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
458
  	v9fs_invalidate_inode_attr(dir);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
459
460
461
  error:
  	if (fid)
  		p9_client_clunk(fid);
5fa6300ae   Al Viro   9p: split droppin...
462
  	v9fs_put_acl(dacl, pacl);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
463
464
465
466
467
468
469
  	return err;
  }
  
  static int
  v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
  		 struct kstat *stat)
  {
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
470
471
472
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *fid;
  	struct p9_stat_dotl *st;
5d3851530   Joe Perches   9p: Reduce object...
473
474
  	p9_debug(P9_DEBUG_VFS, "dentry: %p
  ", dentry);
42869c8ad   Aneesh Kumar K.V   fs/9p: Add v9fs_d...
475
  	v9ses = v9fs_dentry2v9ses(dentry);
a12119087   Aneesh Kumar K.V   fs/9p: Don't set ...
476
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
2b0143b5c   David Howells   VFS: normal files...
477
  		generic_fillattr(d_inode(dentry), stat);
a12119087   Aneesh Kumar K.V   fs/9p: Don't set ...
478
479
  		return 0;
  	}
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
480
481
482
483
484
485
486
487
488
489
490
  	fid = v9fs_fid_lookup(dentry);
  	if (IS_ERR(fid))
  		return PTR_ERR(fid);
  
  	/* Ask for all the fields in stat structure. Server will return
  	 * whatever it supports
  	 */
  
  	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
  	if (IS_ERR(st))
  		return PTR_ERR(st);
2b0143b5c   David Howells   VFS: normal files...
491
492
  	v9fs_stat2inode_dotl(st, d_inode(dentry));
  	generic_fillattr(d_inode(dentry), stat);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
493
494
495
496
497
498
  	/* Change block size to what the server returned */
  	stat->blksize = st->st_blksize;
  
  	kfree(st);
  	return 0;
  }
f766619db   Aneesh Kumar K.V   fs/9p: iattr_vali...
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
  /*
   * Attribute flags.
   */
  #define P9_ATTR_MODE		(1 << 0)
  #define P9_ATTR_UID		(1 << 1)
  #define P9_ATTR_GID		(1 << 2)
  #define P9_ATTR_SIZE		(1 << 3)
  #define P9_ATTR_ATIME		(1 << 4)
  #define P9_ATTR_MTIME		(1 << 5)
  #define P9_ATTR_CTIME		(1 << 6)
  #define P9_ATTR_ATIME_SET	(1 << 7)
  #define P9_ATTR_MTIME_SET	(1 << 8)
  
  struct dotl_iattr_map {
  	int iattr_valid;
  	int p9_iattr_valid;
  };
  
  static int v9fs_mapped_iattr_valid(int iattr_valid)
  {
  	int i;
  	int p9_iattr_valid = 0;
  	struct dotl_iattr_map dotl_iattr_map[] = {
  		{ ATTR_MODE,		P9_ATTR_MODE },
  		{ ATTR_UID,		P9_ATTR_UID },
  		{ ATTR_GID,		P9_ATTR_GID },
  		{ ATTR_SIZE,		P9_ATTR_SIZE },
  		{ ATTR_ATIME,		P9_ATTR_ATIME },
  		{ ATTR_MTIME,		P9_ATTR_MTIME },
  		{ ATTR_CTIME,		P9_ATTR_CTIME },
  		{ ATTR_ATIME_SET,	P9_ATTR_ATIME_SET },
  		{ ATTR_MTIME_SET,	P9_ATTR_MTIME_SET },
  	};
  	for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) {
  		if (iattr_valid & dotl_iattr_map[i].iattr_valid)
  			p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid;
  	}
  	return p9_iattr_valid;
  }
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
538
539
540
541
542
543
544
545
546
547
  /**
   * v9fs_vfs_setattr_dotl - set file metadata
   * @dentry: file whose metadata to set
   * @iattr: metadata assignment structure
   *
   */
  
  int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
  {
  	int retval;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
548
549
  	struct p9_fid *fid;
  	struct p9_iattr_dotl p9attr;
2b0143b5c   David Howells   VFS: normal files...
550
  	struct inode *inode = d_inode(dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
551

5d3851530   Joe Perches   9p: Reduce object...
552
553
  	p9_debug(P9_DEBUG_VFS, "
  ");
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
554

31051c85b   Jan Kara   fs: Give dentry t...
555
  	retval = setattr_prepare(dentry, iattr);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
556
557
  	if (retval)
  		return retval;
f766619db   Aneesh Kumar K.V   fs/9p: iattr_vali...
558
  	p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
559
560
561
562
563
564
565
566
  	p9attr.mode = iattr->ia_mode;
  	p9attr.uid = iattr->ia_uid;
  	p9attr.gid = iattr->ia_gid;
  	p9attr.size = iattr->ia_size;
  	p9attr.atime_sec = iattr->ia_atime.tv_sec;
  	p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
  	p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
  	p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
567
568
569
  	fid = v9fs_fid_lookup(dentry);
  	if (IS_ERR(fid))
  		return PTR_ERR(fid);
3dc5436aa   Aneesh Kumar K.V   fs/9p: Writeback ...
570
  	/* Write all dirty data */
be308f079   Al Viro   9p: switch v9fs_a...
571
572
  	if (S_ISREG(inode->i_mode))
  		filemap_write_and_wait(inode->i_mapping);
3dc5436aa   Aneesh Kumar K.V   fs/9p: Writeback ...
573

f10fc50f1   Aneesh Kumar K.V   fs/9p: call vmtru...
574
575
576
  	retval = p9_client_setattr(fid, &p9attr);
  	if (retval < 0)
  		return retval;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
577

059c138bc   Aneesh Kumar K.V   fs/9p: Use trunca...
578
  	if ((iattr->ia_valid & ATTR_SIZE) &&
be308f079   Al Viro   9p: switch v9fs_a...
579
580
  	    iattr->ia_size != i_size_read(inode))
  		truncate_setsize(inode, iattr->ia_size);
059c138bc   Aneesh Kumar K.V   fs/9p: Use trunca...
581

be308f079   Al Viro   9p: switch v9fs_a...
582
583
584
  	v9fs_invalidate_inode_attr(inode);
  	setattr_copy(inode, iattr);
  	mark_inode_dirty(inode);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
585
586
  	if (iattr->ia_valid & ATTR_MODE) {
  		/* We also want to update ACL when we update mode bits */
be308f079   Al Viro   9p: switch v9fs_a...
587
  		retval = v9fs_acl_chmod(inode, fid);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
588
589
590
591
592
593
594
595
596
597
  		if (retval < 0)
  			return retval;
  	}
  	return 0;
  }
  
  /**
   * v9fs_stat2inode_dotl - populate an inode structure with stat info
   * @stat: stat structure
   * @inode: inode to populate
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
598
599
600
601
602
603
   *
   */
  
  void
  v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
  {
3eda0de67   Al Viro   9p: propagate umo...
604
  	umode_t mode;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
605
  	struct v9fs_inode *v9inode = V9FS_I(inode);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
606
607
608
609
610
611
612
613
614
615
  
  	if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
  		inode->i_atime.tv_sec = stat->st_atime_sec;
  		inode->i_atime.tv_nsec = stat->st_atime_nsec;
  		inode->i_mtime.tv_sec = stat->st_mtime_sec;
  		inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
  		inode->i_ctime.tv_sec = stat->st_ctime_sec;
  		inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
  		inode->i_uid = stat->st_uid;
  		inode->i_gid = stat->st_gid;
bfe868486   Miklos Szeredi   filesystems: add ...
616
  		set_nlink(inode, stat->st_nlink);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
617

45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
618
619
620
  		mode = stat->st_mode & S_IALLUGO;
  		mode |= inode->i_mode & ~S_IALLUGO;
  		inode->i_mode = mode;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  
  		i_size_write(inode, stat->st_size);
  		inode->i_blocks = stat->st_blocks;
  	} else {
  		if (stat->st_result_mask & P9_STATS_ATIME) {
  			inode->i_atime.tv_sec = stat->st_atime_sec;
  			inode->i_atime.tv_nsec = stat->st_atime_nsec;
  		}
  		if (stat->st_result_mask & P9_STATS_MTIME) {
  			inode->i_mtime.tv_sec = stat->st_mtime_sec;
  			inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
  		}
  		if (stat->st_result_mask & P9_STATS_CTIME) {
  			inode->i_ctime.tv_sec = stat->st_ctime_sec;
  			inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
  		}
  		if (stat->st_result_mask & P9_STATS_UID)
  			inode->i_uid = stat->st_uid;
  		if (stat->st_result_mask & P9_STATS_GID)
  			inode->i_gid = stat->st_gid;
  		if (stat->st_result_mask & P9_STATS_NLINK)
bfe868486   Miklos Szeredi   filesystems: add ...
642
  			set_nlink(inode, stat->st_nlink);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
  		if (stat->st_result_mask & P9_STATS_MODE) {
  			inode->i_mode = stat->st_mode;
  			if ((S_ISBLK(inode->i_mode)) ||
  						(S_ISCHR(inode->i_mode)))
  				init_special_inode(inode, inode->i_mode,
  								inode->i_rdev);
  		}
  		if (stat->st_result_mask & P9_STATS_RDEV)
  			inode->i_rdev = new_decode_dev(stat->st_rdev);
  		if (stat->st_result_mask & P9_STATS_SIZE)
  			i_size_write(inode, stat->st_size);
  		if (stat->st_result_mask & P9_STATS_BLOCKS)
  			inode->i_blocks = stat->st_blocks;
  	}
  	if (stat->st_result_mask & P9_STATS_GEN)
fd2421f54   Aneesh Kumar K.V   fs/9p: When doing...
658
  		inode->i_generation = stat->st_gen;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
659
660
661
662
  
  	/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
  	 * because the inode structure does not have fields for them.
  	 */
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
663
  	v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
664
665
666
667
668
669
  }
  
  static int
  v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
  		const char *symname)
  {
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
670
  	int err;
d4ef4e358   Eric W. Biederman   9p: Modify v9fs_g...
671
  	kgid_t gid;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
672
673
674
675
676
677
  	char *name;
  	struct p9_qid qid;
  	struct inode *inode;
  	struct p9_fid *dfid;
  	struct p9_fid *fid = NULL;
  	struct v9fs_session_info *v9ses;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
678
679
  
  	name = (char *) dentry->d_name.name;
5d3851530   Joe Perches   9p: Reduce object...
680
681
  	p9_debug(P9_DEBUG_VFS, "%lu,%s,%s
  ", dir->i_ino, name, symname);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
682
  	v9ses = v9fs_inode2v9ses(dir);
77d5a6b7d   Al Viro   9p: new helper - ...
683
  	dfid = v9fs_parent_fid(dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
684
685
  	if (IS_ERR(dfid)) {
  		err = PTR_ERR(dfid);
5d3851530   Joe Perches   9p: Reduce object...
686
687
  		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d
  ", err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
688
689
690
691
692
693
694
695
696
  		return err;
  	}
  
  	gid = v9fs_get_fsgid_for_create(dir);
  
  	/* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
  	err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
  
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
697
698
  		p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d
  ", err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
699
700
  		goto error;
  	}
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
701
  	v9fs_invalidate_inode_attr(dir);
fb89b45cd   Dominique Martinet   9P: introduction ...
702
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
703
704
705
706
  		/* Now walk from the parent so we can get an unopened fid. */
  		fid = p9_client_walk(dfid, 1, &name, 1);
  		if (IS_ERR(fid)) {
  			err = PTR_ERR(fid);
5d3851530   Joe Perches   9p: Reduce object...
707
708
709
  			p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d
  ",
  				 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
710
711
712
713
714
  			fid = NULL;
  			goto error;
  		}
  
  		/* instantiate inode and assign the unopened fid to dentry */
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
715
  		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
716
717
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
5d3851530   Joe Perches   9p: Reduce object...
718
719
720
  			p9_debug(P9_DEBUG_VFS, "inode creation failed %d
  ",
  				 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
721
722
  			goto error;
  		}
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
723
  		v9fs_fid_add(dentry, fid);
5441ae5eb   Aneesh Kumar K.V   fs/9p: Add fid be...
724
  		d_instantiate(dentry, inode);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
725
  		fid = NULL;
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
726
  		err = 0;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
727
728
  	} else {
  		/* Not in cached mode. No need to populate inode with stat */
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
729
  		inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
730
731
732
733
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
  			goto error;
  		}
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
  		d_instantiate(dentry, inode);
  	}
  
  error:
  	if (fid)
  		p9_client_clunk(fid);
  
  	return err;
  }
  
  /**
   * v9fs_vfs_link_dotl - create a hardlink for dotl
   * @old_dentry: dentry for file to link to
   * @dir: inode destination for new link
   * @dentry: dentry for link
   *
   */
  
  static int
  v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
  		struct dentry *dentry)
  {
  	int err;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
757
758
  	struct p9_fid *dfid, *oldfid;
  	struct v9fs_session_info *v9ses;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
759

4b8e99239   Al Viro   9p: switch to %p[dD]
760
761
762
  	p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd
  ",
  		 dir->i_ino, old_dentry, dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
763
764
  
  	v9ses = v9fs_inode2v9ses(dir);
77d5a6b7d   Al Viro   9p: new helper - ...
765
  	dfid = v9fs_parent_fid(dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
766
767
768
769
770
771
  	if (IS_ERR(dfid))
  		return PTR_ERR(dfid);
  
  	oldfid = v9fs_fid_lookup(old_dentry);
  	if (IS_ERR(oldfid))
  		return PTR_ERR(oldfid);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
772
773
774
  	err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
  
  	if (err < 0) {
5d3851530   Joe Perches   9p: Reduce object...
775
776
  		p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d
  ", err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
777
778
  		return err;
  	}
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
779
  	v9fs_invalidate_inode_attr(dir);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
780
781
782
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
  		/* Get the latest stat info from server. */
  		struct p9_fid *fid;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
783
784
785
  		fid = v9fs_fid_lookup(old_dentry);
  		if (IS_ERR(fid))
  			return PTR_ERR(fid);
2b0143b5c   David Howells   VFS: normal files...
786
  		v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
787
  	}
2b0143b5c   David Howells   VFS: normal files...
788
789
  	ihold(d_inode(old_dentry));
  	d_instantiate(dentry, d_inode(old_dentry));
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
790
791
792
793
794
795
796
797
  
  	return err;
  }
  
  /**
   * v9fs_vfs_mknod_dotl - create a special file
   * @dir: inode destination for new link
   * @dentry: dentry for file
fd2916bd7   Fabian Frederick   fs/9p: kerneldoc ...
798
   * @omode: mode for creation
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
799
800
801
802
   * @rdev: device associated with special file
   *
   */
  static int
1a67aafb5   Al Viro   switch ->mknod() ...
803
  v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
804
805
806
  		dev_t rdev)
  {
  	int err;
d4ef4e358   Eric W. Biederman   9p: Modify v9fs_g...
807
  	kgid_t gid;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
808
  	char *name;
d3fb61207   Al Viro   switch posix_acl_...
809
  	umode_t mode;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
810
811
812
  	struct v9fs_session_info *v9ses;
  	struct p9_fid *fid = NULL, *dfid = NULL;
  	struct inode *inode;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
813
  	struct p9_qid qid;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
814
  	struct posix_acl *dacl = NULL, *pacl = NULL;
a455589f1   Al Viro   assorted conversi...
815
816
817
  	p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u
  ",
  		 dir->i_ino, dentry, omode,
5d3851530   Joe Perches   9p: Reduce object...
818
  		 MAJOR(rdev), MINOR(rdev));
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
819

53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
820
  	v9ses = v9fs_inode2v9ses(dir);
77d5a6b7d   Al Viro   9p: new helper - ...
821
  	dfid = v9fs_parent_fid(dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
822
823
  	if (IS_ERR(dfid)) {
  		err = PTR_ERR(dfid);
5d3851530   Joe Perches   9p: Reduce object...
824
825
  		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d
  ", err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
826
827
828
829
830
831
832
833
834
  		dfid = NULL;
  		goto error;
  	}
  
  	gid = v9fs_get_fsgid_for_create(dir);
  	mode = omode;
  	/* Update mode based on ACL value */
  	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
  	if (err) {
5d3851530   Joe Perches   9p: Reduce object...
835
836
837
  		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d
  ",
  			 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
838
839
840
841
842
843
844
  		goto error;
  	}
  	name = (char *) dentry->d_name.name;
  
  	err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
  	if (err < 0)
  		goto error;
d28c61f0e   Aneesh Kumar K.V   fs/9p: Mark direc...
845
  	v9fs_invalidate_inode_attr(dir);
3592ac444   Al Viro   9p: switch v9fs_s...
846
847
848
849
850
851
852
853
854
  	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;
  	}
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
855
856
  	/* instantiate inode and assign the unopened fid to the dentry */
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
ed80fcfac   Aneesh Kumar K.V   fs/9p: Always ask...
857
  		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
858
859
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
5d3851530   Joe Perches   9p: Reduce object...
860
861
862
  			p9_debug(P9_DEBUG_VFS, "inode creation failed %d
  ",
  				 err);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
863
864
  			goto error;
  		}
3592ac444   Al Viro   9p: switch v9fs_s...
865
  		v9fs_set_create_acl(inode, fid, dacl, pacl);
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
866
  		v9fs_fid_add(dentry, fid);
5441ae5eb   Aneesh Kumar K.V   fs/9p: Add fid be...
867
  		d_instantiate(dentry, inode);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
868
  		fid = NULL;
2ea03e1d6   Al Viro   9p: v9fs_fid_add(...
869
  		err = 0;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
870
871
872
873
874
  	} else {
  		/*
  		 * Not in cached mode. No need to populate inode with stat.
  		 * socket syscall returns a fd, so we need instantiate
  		 */
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
875
  		inode = v9fs_get_inode(dir->i_sb, mode, rdev);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
876
877
878
879
  		if (IS_ERR(inode)) {
  			err = PTR_ERR(inode);
  			goto error;
  		}
3592ac444   Al Viro   9p: switch v9fs_s...
880
  		v9fs_set_create_acl(inode, fid, dacl, pacl);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
881
882
  		d_instantiate(dentry, inode);
  	}
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
883
884
885
  error:
  	if (fid)
  		p9_client_clunk(fid);
5fa6300ae   Al Viro   9p: split droppin...
886
  	v9fs_put_acl(dacl, pacl);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
887
888
  	return err;
  }
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
889
  /**
6b2553918   Al Viro   replace ->follow_...
890
   * v9fs_vfs_get_link_dotl - follow a symlink path
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
891
   * @dentry: dentry for symlink
6b2553918   Al Viro   replace ->follow_...
892
   * @inode: inode for symlink
fceef393a   Al Viro   switch ->get_link...
893
   * @done: destructor for return value
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
894
   */
680baacbc   Al Viro   new ->follow_link...
895
  static const char *
6b2553918   Al Viro   replace ->follow_...
896
  v9fs_vfs_get_link_dotl(struct dentry *dentry,
fceef393a   Al Viro   switch ->get_link...
897
898
  		       struct inode *inode,
  		       struct delayed_call *done)
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
899
  {
6b2553918   Al Viro   replace ->follow_...
900
  	struct p9_fid *fid;
31b6ceac4   M. Mohan Kumar   fs/9p: TREADLINK ...
901
  	char *target;
90e4fc889   Al Viro   9p: don't bother ...
902
  	int retval;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
903

6b2553918   Al Viro   replace ->follow_...
904
905
  	if (!dentry)
  		return ERR_PTR(-ECHILD);
4b8e99239   Al Viro   9p: switch to %p[dD]
906
907
  	p9_debug(P9_DEBUG_VFS, "%pd
  ", dentry);
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
908

6b2553918   Al Viro   replace ->follow_...
909
  	fid = v9fs_fid_lookup(dentry);
90e4fc889   Al Viro   9p: don't bother ...
910
911
  	if (IS_ERR(fid))
  		return ERR_CAST(fid);
31b6ceac4   M. Mohan Kumar   fs/9p: TREADLINK ...
912
  	retval = p9_client_readlink(fid, &target);
90e4fc889   Al Viro   9p: don't bother ...
913
914
  	if (retval)
  		return ERR_PTR(retval);
fceef393a   Al Viro   switch ->get_link...
915
916
  	set_delayed_call(done, kfree_link, target);
  	return target;
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
917
  }
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
918
919
920
921
922
923
924
925
926
927
  int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
  {
  	loff_t i_size;
  	struct p9_stat_dotl *st;
  	struct v9fs_session_info *v9ses;
  
  	v9ses = v9fs_inode2v9ses(inode);
  	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
  	if (IS_ERR(st))
  		return PTR_ERR(st);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
928
929
930
931
932
  	/*
  	 * Don't update inode if the file type is different
  	 */
  	if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
  		goto out;
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
933
934
935
936
937
938
939
940
  
  	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_dotl(st, inode);
fb89b45cd   Dominique Martinet   9P: introduction ...
941
  	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
942
943
  		inode->i_size = i_size;
  	spin_unlock(&inode->i_lock);
45089142b   Aneesh Kumar K.V   fs/9p: Don't upda...
944
  out:
b3cbea03b   Aneesh Kumar K.V   fs/9p: Add suppor...
945
946
947
  	kfree(st);
  	return 0;
  }
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
948
949
  const struct inode_operations v9fs_dir_inode_operations_dotl = {
  	.create = v9fs_vfs_create_dotl,
e43ae79c5   Miklos Szeredi   9p: implement i_o...
950
  	.atomic_open = v9fs_vfs_atomic_open_dotl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
951
952
953
954
955
956
957
958
959
960
  	.lookup = v9fs_vfs_lookup,
  	.link = v9fs_vfs_link_dotl,
  	.symlink = v9fs_vfs_symlink_dotl,
  	.unlink = v9fs_vfs_unlink,
  	.mkdir = v9fs_vfs_mkdir_dotl,
  	.rmdir = v9fs_vfs_rmdir,
  	.mknod = v9fs_vfs_mknod_dotl,
  	.rename = v9fs_vfs_rename,
  	.getattr = v9fs_vfs_getattr_dotl,
  	.setattr = v9fs_vfs_setattr_dotl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
961
  	.listxattr = v9fs_listxattr,
4e34e719e   Christoph Hellwig   fs: take the ACL ...
962
  	.get_acl = v9fs_iop_get_acl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
963
964
965
966
967
  };
  
  const struct inode_operations v9fs_file_inode_operations_dotl = {
  	.getattr = v9fs_vfs_getattr_dotl,
  	.setattr = v9fs_vfs_setattr_dotl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
968
  	.listxattr = v9fs_listxattr,
4e34e719e   Christoph Hellwig   fs: take the ACL ...
969
  	.get_acl = v9fs_iop_get_acl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
970
971
972
  };
  
  const struct inode_operations v9fs_symlink_inode_operations_dotl = {
31b6ceac4   M. Mohan Kumar   fs/9p: TREADLINK ...
973
  	.readlink = generic_readlink,
6b2553918   Al Viro   replace ->follow_...
974
  	.get_link = v9fs_vfs_get_link_dotl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
975
976
  	.getattr = v9fs_vfs_getattr_dotl,
  	.setattr = v9fs_vfs_setattr_dotl,
53c06f4e0   Aneesh Kumar K.V   fs/9p: Move dotl ...
977
978
  	.listxattr = v9fs_listxattr,
  };