blob: 47dfd5d29a6b9c42eb350b890b31677c52cd15d7 [file] [log] [blame]
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001/*
2 * linux/fs/9p/vfs_inode.c
3 *
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07004 * This file contains vfs inode ops for the 9P2000 protocol.
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07005 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 *
9 * This program is free software; you can redistribute it and/or modify
Eric Van Hensbergen42e8c502006-03-25 03:07:28 -080010 * it under the terms of the GNU General Public License version 2
11 * as published by the Free Software Foundation.
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070012 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to:
20 * Free Software Foundation
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02111-1301 USA
23 *
24 */
25
26#include <linux/module.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/file.h>
30#include <linux/pagemap.h>
31#include <linux/stat.h>
32#include <linux/string.h>
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070033#include <linux/inet.h>
34#include <linux/namei.h>
35#include <linux/idr.h>
Alexey Dobriyane8edc6e2007-05-21 01:22:52 +040036#include <linux/sched.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090037#include <linux/slab.h>
Aneesh Kumar K.Vebf46262010-05-31 13:22:56 +053038#include <linux/xattr.h>
Aneesh Kumar K.V85ff8722010-09-28 00:27:39 +053039#include <linux/posix_acl.h>
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050040#include <net/9p/9p.h>
41#include <net/9p/client.h>
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070042
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070043#include "v9fs.h"
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070044#include "v9fs_vfs.h"
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070045#include "fid.h"
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -050046#include "cache.h"
Aneesh Kumar K.Vebf46262010-05-31 13:22:56 +053047#include "xattr.h"
Aneesh Kumar K.V85ff8722010-09-28 00:27:39 +053048#include "acl.h"
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070049
Arjan van de Ven754661f2007-02-12 00:55:38 -080050static const struct inode_operations v9fs_dir_inode_operations;
Sripathi Kodi9b6533c2010-03-25 12:41:54 +000051static const struct inode_operations v9fs_dir_inode_operations_dotu;
52static const struct inode_operations v9fs_dir_inode_operations_dotl;
Arjan van de Ven754661f2007-02-12 00:55:38 -080053static const struct inode_operations v9fs_file_inode_operations;
Sripathi Kodi9b6533c2010-03-25 12:41:54 +000054static const struct inode_operations v9fs_file_inode_operations_dotl;
Arjan van de Ven754661f2007-02-12 00:55:38 -080055static const struct inode_operations v9fs_symlink_inode_operations;
Sripathi Kodi9b6533c2010-03-25 12:41:54 +000056static const struct inode_operations v9fs_symlink_inode_operations_dotl;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070057
Aneesh Kumar K.Vf5fc6142010-10-12 13:02:25 +053058static int
59v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
60 dev_t rdev);
61
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070062/**
63 * unixmode2p9mode - convert unix mode bits to plan 9
64 * @v9ses: v9fs session information
65 * @mode: mode to convert
66 *
67 */
68
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -070069static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070070{
71 int res;
72 res = mode & 0777;
73 if (S_ISDIR(mode))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050074 res |= P9_DMDIR;
Sripathi Kodidd6102f2010-03-05 18:48:00 +000075 if (v9fs_proto_dotu(v9ses)) {
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070076 if (S_ISLNK(mode))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050077 res |= P9_DMSYMLINK;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070078 if (v9ses->nodev == 0) {
79 if (S_ISSOCK(mode))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050080 res |= P9_DMSOCKET;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070081 if (S_ISFIFO(mode))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050082 res |= P9_DMNAMEDPIPE;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070083 if (S_ISBLK(mode))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050084 res |= P9_DMDEVICE;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070085 if (S_ISCHR(mode))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050086 res |= P9_DMDEVICE;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070087 }
88
89 if ((mode & S_ISUID) == S_ISUID)
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050090 res |= P9_DMSETUID;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070091 if ((mode & S_ISGID) == S_ISGID)
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050092 res |= P9_DMSETGID;
Anthony Liguorid199d652008-02-06 19:25:06 -060093 if ((mode & S_ISVTX) == S_ISVTX)
94 res |= P9_DMSETVTX;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -050095 if ((mode & P9_DMLINK))
96 res |= P9_DMLINK;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -070097 }
98
99 return res;
100}
101
102/**
103 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
104 * @v9ses: v9fs session information
105 * @mode: mode to convert
106 *
107 */
108
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -0700109static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700110{
111 int res;
112
113 res = mode & 0777;
114
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500115 if ((mode & P9_DMDIR) == P9_DMDIR)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700116 res |= S_IFDIR;
Sripathi Kodidd6102f2010-03-05 18:48:00 +0000117 else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700118 res |= S_IFLNK;
Sripathi Kodidd6102f2010-03-05 18:48:00 +0000119 else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700120 && (v9ses->nodev == 0))
121 res |= S_IFSOCK;
Sripathi Kodidd6102f2010-03-05 18:48:00 +0000122 else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700123 && (v9ses->nodev == 0))
124 res |= S_IFIFO;
Sripathi Kodidd6102f2010-03-05 18:48:00 +0000125 else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700126 && (v9ses->nodev == 0))
127 res |= S_IFBLK;
128 else
129 res |= S_IFREG;
130
Sripathi Kodidd6102f2010-03-05 18:48:00 +0000131 if (v9fs_proto_dotu(v9ses)) {
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500132 if ((mode & P9_DMSETUID) == P9_DMSETUID)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700133 res |= S_ISUID;
134
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500135 if ((mode & P9_DMSETGID) == P9_DMSETGID)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700136 res |= S_ISGID;
Anthony Liguorid199d652008-02-06 19:25:06 -0600137
138 if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
139 res |= S_ISVTX;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700140 }
141
142 return res;
143}
144
Eric Van Hensbergenee443992008-03-05 07:08:09 -0600145/**
146 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
147 * @uflags: flags to convert
Eric Van Hensbergen2e4bef42008-06-24 17:39:39 -0500148 * @extended: if .u extensions are active
Eric Van Hensbergenee443992008-03-05 07:08:09 -0600149 */
150
Eric Van Hensbergen2e4bef42008-06-24 17:39:39 -0500151int v9fs_uflags2omode(int uflags, int extended)
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800152{
153 int ret;
154
155 ret = 0;
156 switch (uflags&3) {
157 default:
158 case O_RDONLY:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500159 ret = P9_OREAD;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800160 break;
161
162 case O_WRONLY:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500163 ret = P9_OWRITE;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800164 break;
165
166 case O_RDWR:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500167 ret = P9_ORDWR;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800168 break;
169 }
170
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800171 if (uflags & O_TRUNC)
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500172 ret |= P9_OTRUNC;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800173
Eric Van Hensbergen2e4bef42008-06-24 17:39:39 -0500174 if (extended) {
175 if (uflags & O_EXCL)
176 ret |= P9_OEXCL;
177
178 if (uflags & O_APPEND)
179 ret |= P9_OAPPEND;
180 }
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800181
182 return ret;
183}
184
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700185/**
Latchesar Ionkov531b1092006-01-08 01:05:00 -0800186 * v9fs_blank_wstat - helper function to setup a 9P stat structure
Latchesar Ionkov531b1092006-01-08 01:05:00 -0800187 * @wstat: structure to initialize
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700188 *
189 */
190
M. Mohan Kumar7a4439c2010-02-08 15:36:48 -0600191void
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500192v9fs_blank_wstat(struct p9_wstat *wstat)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700193{
Latchesar Ionkov531b1092006-01-08 01:05:00 -0800194 wstat->type = ~0;
195 wstat->dev = ~0;
196 wstat->qid.type = ~0;
197 wstat->qid.version = ~0;
198 *((long long *)&wstat->qid.path) = ~0;
199 wstat->mode = ~0;
200 wstat->atime = ~0;
201 wstat->mtime = ~0;
202 wstat->length = ~0;
203 wstat->name = NULL;
204 wstat->uid = NULL;
205 wstat->gid = NULL;
206 wstat->muid = NULL;
207 wstat->n_uid = ~0;
208 wstat->n_gid = ~0;
209 wstat->n_muid = ~0;
210 wstat->extension = NULL;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700211}
212
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -0500213#ifdef CONFIG_9P_FSCACHE
214/**
215 * v9fs_alloc_inode - helper function to allocate an inode
216 * This callback is executed before setting up the inode so that we
217 * can associate a vcookie with each inode.
218 *
219 */
220
221struct inode *v9fs_alloc_inode(struct super_block *sb)
222{
223 struct v9fs_cookie *vcookie;
224 vcookie = (struct v9fs_cookie *)kmem_cache_alloc(vcookie_cache,
225 GFP_KERNEL);
226 if (!vcookie)
227 return NULL;
228
229 vcookie->fscache = NULL;
230 vcookie->qid = NULL;
231 spin_lock_init(&vcookie->lock);
232 return &vcookie->inode;
233}
234
235/**
236 * v9fs_destroy_inode - destroy an inode
237 *
238 */
239
240void v9fs_destroy_inode(struct inode *inode)
241{
242 kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode));
243}
244#endif
245
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700246/**
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -0500247 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
248 * new file system object. This checks the S_ISGID to determine the owning
249 * group of the new file system object.
250 */
251
252static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
253{
254 BUG_ON(dir_inode == NULL);
255
256 if (dir_inode->i_mode & S_ISGID) {
257 /* set_gid bit is set.*/
258 return dir_inode->i_gid;
259 }
260 return current_fsgid();
261}
262
263/**
264 * v9fs_dentry_from_dir_inode - helper function to get the dentry from
265 * dir inode.
266 *
267 */
268
Eric Van Hensbergenea1375332010-07-27 14:49:43 -0500269static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -0500270{
271 struct dentry *dentry;
272
273 spin_lock(&dcache_lock);
Nick Pigginb23fb0a2011-01-07 17:49:35 +1100274 spin_lock(&dcache_inode_lock);
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -0500275 /* Directory should have only one entry. */
276 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
277 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
Nick Pigginb23fb0a2011-01-07 17:49:35 +1100278 spin_unlock(&dcache_inode_lock);
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -0500279 spin_unlock(&dcache_lock);
280 return dentry;
281}
282
283/**
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700284 * v9fs_get_inode - helper function to setup an inode
285 * @sb: superblock
286 * @mode: mode to setup inode with
287 *
288 */
289
290struct inode *v9fs_get_inode(struct super_block *sb, int mode)
291{
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600292 int err;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800293 struct inode *inode;
Eric Van Hensbergenb5016112005-09-09 13:04:27 -0700294 struct v9fs_session_info *v9ses = sb->s_fs_info;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700295
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500296 P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700297
298 inode = new_inode(sb);
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600299 if (!inode) {
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500300 P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
Abhishek Kulkarni48559b4c2009-08-17 16:32:18 -0500301 return ERR_PTR(-ENOMEM);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700302 }
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600303
Dmitry Monakhov217f2062010-03-04 17:30:57 +0300304 inode_init_owner(inode, NULL, mode);
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600305 inode->i_blocks = 0;
306 inode->i_rdev = 0;
307 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
308 inode->i_mapping->a_ops = &v9fs_addr_operations;
309
310 switch (mode & S_IFMT) {
311 case S_IFIFO:
312 case S_IFBLK:
313 case S_IFCHR:
314 case S_IFSOCK:
M. Mohan Kumar4b435162010-06-16 14:27:01 +0530315 if (v9fs_proto_dotl(v9ses)) {
316 inode->i_op = &v9fs_file_inode_operations_dotl;
317 inode->i_fop = &v9fs_file_operations_dotl;
318 } else if (v9fs_proto_dotu(v9ses)) {
319 inode->i_op = &v9fs_file_inode_operations;
320 inode->i_fop = &v9fs_file_operations;
321 } else {
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600322 P9_DPRINTK(P9_DEBUG_ERROR,
323 "special files without extended mode\n");
324 err = -EINVAL;
325 goto error;
326 }
327 init_special_inode(inode, inode->i_mode, inode->i_rdev);
328 break;
329 case S_IFREG:
Sripathi Kodi9b6533c2010-03-25 12:41:54 +0000330 if (v9fs_proto_dotl(v9ses)) {
331 inode->i_op = &v9fs_file_inode_operations_dotl;
332 inode->i_fop = &v9fs_file_operations_dotl;
333 } else {
334 inode->i_op = &v9fs_file_inode_operations;
335 inode->i_fop = &v9fs_file_operations;
336 }
337
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600338 break;
Sripathi Kodi9b6533c2010-03-25 12:41:54 +0000339
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600340 case S_IFLNK:
Sripathi Kodi9b6533c2010-03-25 12:41:54 +0000341 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
342 P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used with "
343 "legacy protocol.\n");
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600344 err = -EINVAL;
345 goto error;
346 }
Sripathi Kodi9b6533c2010-03-25 12:41:54 +0000347
348 if (v9fs_proto_dotl(v9ses))
349 inode->i_op = &v9fs_symlink_inode_operations_dotl;
350 else
351 inode->i_op = &v9fs_symlink_inode_operations;
352
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600353 break;
354 case S_IFDIR:
355 inc_nlink(inode);
Sripathi Kodi9b6533c2010-03-25 12:41:54 +0000356 if (v9fs_proto_dotl(v9ses))
357 inode->i_op = &v9fs_dir_inode_operations_dotl;
358 else if (v9fs_proto_dotu(v9ses))
359 inode->i_op = &v9fs_dir_inode_operations_dotu;
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600360 else
361 inode->i_op = &v9fs_dir_inode_operations;
Sripathi Kodi9b6533c2010-03-25 12:41:54 +0000362
363 if (v9fs_proto_dotl(v9ses))
364 inode->i_fop = &v9fs_dir_operations_dotl;
365 else
366 inode->i_fop = &v9fs_dir_operations;
367
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600368 break;
369 default:
370 P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n",
371 mode, mode & S_IFMT);
372 err = -EINVAL;
373 goto error;
374 }
375
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700376 return inode;
Abhishek Kulkarni2bb54112009-07-19 13:41:56 -0600377
378error:
379 iput(inode);
380 return ERR_PTR(err);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700381}
382
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500383/*
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800384static struct v9fs_fid*
385v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
386{
387 int err;
Mika Kukkonen736c4b82006-12-06 20:36:29 -0800388 int nfid;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800389 struct v9fs_fid *ret;
390 struct v9fs_fcall *fcall;
391
392 nfid = v9fs_get_idpool(&v9ses->fidpool);
393 if (nfid < 0) {
394 eprintk(KERN_WARNING, "no free fids available\n");
Latchesar Ionkov731805b2006-03-07 21:55:42 -0800395 return ERR_PTR(-ENOSPC);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800396 }
397
398 err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name,
399 &fcall);
400
401 if (err < 0) {
Latchesar Ionkov41e5a6a2006-05-15 09:44:21 -0700402 if (fcall && fcall->id == RWALK)
403 goto clunk_fid;
404
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800405 PRINT_FCALL_ERROR("walk error", fcall);
406 v9fs_put_idpool(nfid, &v9ses->fidpool);
407 goto error;
408 }
409
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700410 kfree(fcall);
Latchesar Ionkov3cf64292006-01-08 01:04:58 -0800411 fcall = NULL;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800412 ret = v9fs_fid_create(v9ses, nfid);
413 if (!ret) {
414 err = -ENOMEM;
415 goto clunk_fid;
416 }
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700417
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800418 err = v9fs_fid_insert(ret, dentry);
419 if (err < 0) {
420 v9fs_fid_destroy(ret);
421 goto clunk_fid;
Latchesar Ionkov0b8dd172005-09-27 21:45:24 -0700422 }
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800423
424 return ret;
425
426clunk_fid:
427 v9fs_t_clunk(v9ses, nfid);
428
429error:
430 kfree(fcall);
431 return ERR_PTR(err);
432}
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500433*/
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800434
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -0500435
436/**
437 * v9fs_clear_inode - release an inode
438 * @inode: inode to release
439 *
440 */
Al Virob57922d2010-06-07 14:34:48 -0400441void v9fs_evict_inode(struct inode *inode)
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -0500442{
Al Virob57922d2010-06-07 14:34:48 -0400443 truncate_inode_pages(inode->i_mapping, 0);
444 end_writeback(inode);
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -0500445 filemap_fdatawrite(inode->i_mapping);
446
447#ifdef CONFIG_9P_FSCACHE
448 v9fs_cache_inode_put_cookie(inode);
449#endif
450}
451
Latchesar Ionkov5174fda2006-03-25 03:07:25 -0800452static struct inode *
Sripathi Kodif0853122010-07-12 20:07:23 +0530453v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800454 struct super_block *sb)
455{
456 int err, umode;
Sripathi Kodif0853122010-07-12 20:07:23 +0530457 struct inode *ret = NULL;
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500458 struct p9_wstat *st;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800459
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500460 st = p9_client_stat(fid);
Abhishek Kulkarni02bc3562009-07-19 13:41:54 -0600461 if (IS_ERR(st))
462 return ERR_CAST(st);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800463
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500464 umode = p9mode2unixmode(v9ses, st->mode);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800465 ret = v9fs_get_inode(sb, umode);
466 if (IS_ERR(ret)) {
467 err = PTR_ERR(ret);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800468 goto error;
469 }
470
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500471 v9fs_stat2inode(st, ret, sb);
472 ret->i_ino = v9fs_qid2ino(&st->qid);
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -0500473
474#ifdef CONFIG_9P_FSCACHE
475 v9fs_vcookie_set_qid(ret, &st->qid);
476 v9fs_cache_inode_get_cookie(ret);
477#endif
Abhishek Kulkarni02bc3562009-07-19 13:41:54 -0600478 p9stat_free(st);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500479 kfree(st);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800480 return ret;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800481error:
Abhishek Kulkarni02bc3562009-07-19 13:41:54 -0600482 p9stat_free(st);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500483 kfree(st);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800484 return ERR_PTR(err);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700485}
486
Sripathi Kodif0853122010-07-12 20:07:23 +0530487static struct inode *
488v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
489 struct super_block *sb)
490{
491 struct inode *ret = NULL;
492 int err;
493 struct p9_stat_dotl *st;
494
495 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
496 if (IS_ERR(st))
497 return ERR_CAST(st);
498
499 ret = v9fs_get_inode(sb, st->st_mode);
500 if (IS_ERR(ret)) {
501 err = PTR_ERR(ret);
502 goto error;
503 }
504
505 v9fs_stat2inode_dotl(st, ret);
506 ret->i_ino = v9fs_qid2ino(&st->qid);
507#ifdef CONFIG_9P_FSCACHE
508 v9fs_vcookie_set_qid(ret, &st->qid);
509 v9fs_cache_inode_get_cookie(ret);
510#endif
Aneesh Kumar K.V85ff8722010-09-28 00:27:39 +0530511 err = v9fs_get_acl(ret, fid);
512 if (err) {
513 iput(ret);
514 goto error;
515 }
Sripathi Kodif0853122010-07-12 20:07:23 +0530516 kfree(st);
517 return ret;
518error:
519 kfree(st);
520 return ERR_PTR(err);
521}
522
523/**
524 * v9fs_inode_from_fid - Helper routine to populate an inode by
525 * issuing a attribute request
526 * @v9ses: session information
527 * @fid: fid to issue attribute request for
528 * @sb: superblock on which to create inode
529 *
530 */
531static inline struct inode *
532v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
533 struct super_block *sb)
534{
535 if (v9fs_proto_dotl(v9ses))
536 return v9fs_inode_dotl(v9ses, fid, sb);
537 else
538 return v9fs_inode(v9ses, fid, sb);
539}
540
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700541/**
542 * v9fs_remove - helper function to remove files and directories
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -0700543 * @dir: directory inode that is being deleted
544 * @file: dentry that is being deleted
545 * @rmdir: removing a directory
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700546 *
547 */
548
549static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
550{
Aneesh Kumar K.Vd994f402010-03-29 18:14:50 -0500551 int retval;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500552 struct inode *file_inode;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500553 struct p9_fid *v9fid;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700554
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500555 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700556 rmdir);
557
558 file_inode = file->d_inode;
Latchesar Ionkovc959df92007-04-23 14:41:11 -0700559 v9fid = v9fs_fid_clone(file);
Latchesar Ionkovba176742007-10-17 14:31:07 -0500560 if (IS_ERR(v9fid))
Eric Van Hensbergenda977b22007-01-26 00:57:06 -0800561 return PTR_ERR(v9fid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700562
Aneesh Kumar K.Vd994f402010-03-29 18:14:50 -0500563 retval = p9_client_remove(v9fid);
564 if (!retval)
565 drop_nlink(file_inode);
566 return retval;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700567}
568
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500569/**
570 * v9fs_create - Create a file
Eric Van Hensbergenee443992008-03-05 07:08:09 -0600571 * @v9ses: session information
572 * @dir: directory that dentry is being created in
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500573 * @dentry: dentry that is being created
Abhishek Kulkarni0e155972009-07-19 13:41:55 -0600574 * @extension: 9p2000.u extension string to support devices, etc.
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500575 * @perm: create permissions
576 * @mode: open mode
577 *
578 */
579static struct p9_fid *
580v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
581 struct dentry *dentry, char *extension, u32 perm, u8 mode)
582{
583 int err;
584 char *name;
585 struct p9_fid *dfid, *ofid, *fid;
586 struct inode *inode;
587
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500588 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
589
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500590 err = 0;
591 ofid = NULL;
592 fid = NULL;
593 name = (char *) dentry->d_name.name;
Venkateswararao Jujjuri6d27e642010-05-10 18:08:28 +0000594 dfid = v9fs_fid_lookup(dentry->d_parent);
Latchesar Ionkovba176742007-10-17 14:31:07 -0500595 if (IS_ERR(dfid)) {
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500596 err = PTR_ERR(dfid);
Venkateswararao Jujjuri6d27e642010-05-10 18:08:28 +0000597 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
598 return ERR_PTR(err);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500599 }
600
601 /* clone a fid to use for creation */
602 ofid = p9_client_walk(dfid, 0, NULL, 1);
603 if (IS_ERR(ofid)) {
604 err = PTR_ERR(ofid);
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500605 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
Venkateswararao Jujjuri6d27e642010-05-10 18:08:28 +0000606 return ERR_PTR(err);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500607 }
608
609 err = p9_client_fcreate(ofid, name, perm, mode, extension);
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500610 if (err < 0) {
611 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500612 goto error;
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500613 }
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500614
615 /* now walk from the parent so we can get unopened fid */
Venkateswararao Jujjuri6d27e642010-05-10 18:08:28 +0000616 fid = p9_client_walk(dfid, 1, &name, 1);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500617 if (IS_ERR(fid)) {
618 err = PTR_ERR(fid);
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500619 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500620 fid = NULL;
621 goto error;
Venkateswararao Jujjuri6d27e642010-05-10 18:08:28 +0000622 }
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500623
624 /* instantiate inode and assign the unopened fid to the dentry */
625 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
626 if (IS_ERR(inode)) {
627 err = PTR_ERR(inode);
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -0500628 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500629 goto error;
630 }
631
Latchesar Ionkovba176742007-10-17 14:31:07 -0500632 if (v9ses->cache)
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500633 dentry->d_op = &v9fs_cached_dentry_operations;
634 else
635 dentry->d_op = &v9fs_dentry_operations;
636
637 d_instantiate(dentry, inode);
Abhishek Kulkarni50fb6d22009-07-19 13:41:57 -0600638 err = v9fs_fid_add(dentry, fid);
639 if (err < 0)
640 goto error;
641
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500642 return ofid;
643
644error:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500645 if (ofid)
646 p9_client_clunk(ofid);
647
648 if (fid)
649 p9_client_clunk(fid);
650
651 return ERR_PTR(err);
652}
653
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700654/**
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700655 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
656 * @dir: directory inode that is being created
657 * @dentry: dentry that is being deleted
658 * @mode: create permissions
659 * @nd: path information
660 *
661 */
662
663static int
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530664v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700665 struct nameidata *nd)
666{
667 int err = 0;
668 char *name = NULL;
669 gid_t gid;
670 int flags;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530671 mode_t mode;
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700672 struct v9fs_session_info *v9ses;
673 struct p9_fid *fid = NULL;
674 struct p9_fid *dfid, *ofid;
675 struct file *filp;
676 struct p9_qid qid;
677 struct inode *inode;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530678 struct posix_acl *pacl = NULL, *dacl = NULL;
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700679
680 v9ses = v9fs_inode2v9ses(dir);
681 if (nd && nd->flags & LOOKUP_OPEN)
682 flags = nd->intent.open.flags - 1;
Aneesh Kumar K.Vf5fc6142010-10-12 13:02:25 +0530683 else {
684 /*
685 * create call without LOOKUP_OPEN is due
686 * to mknod of regular files. So use mknod
687 * operation.
688 */
689 return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
690 }
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700691
692 name = (char *) dentry->d_name.name;
693 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530694 "mode:0x%x\n", name, flags, omode);
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700695
696 dfid = v9fs_fid_lookup(dentry->d_parent);
697 if (IS_ERR(dfid)) {
698 err = PTR_ERR(dfid);
699 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
700 return err;
701 }
702
703 /* clone a fid to use for creation */
704 ofid = p9_client_walk(dfid, 0, NULL, 1);
705 if (IS_ERR(ofid)) {
706 err = PTR_ERR(ofid);
707 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
708 return err;
709 }
710
711 gid = v9fs_get_fsgid_for_create(dir);
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530712
713 mode = omode;
714 /* Update mode based on ACL value */
715 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
716 if (err) {
717 P9_DPRINTK(P9_DEBUG_VFS,
718 "Failed to get acl values in creat %d\n", err);
719 goto error;
720 }
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700721 err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
722 if (err < 0) {
723 P9_DPRINTK(P9_DEBUG_VFS,
724 "p9_client_open_dotl failed in creat %d\n",
725 err);
726 goto error;
727 }
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530728 /* instantiate inode and assign the unopened fid to the dentry */
729 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE ||
730 (nd && nd->flags & LOOKUP_OPEN)) {
731 fid = p9_client_walk(dfid, 1, &name, 1);
732 if (IS_ERR(fid)) {
733 err = PTR_ERR(fid);
734 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
735 err);
736 fid = NULL;
737 goto error;
738 }
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700739
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530740 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
741 if (IS_ERR(inode)) {
742 err = PTR_ERR(inode);
743 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
744 err);
745 goto error;
746 }
Aneesh Kumar K.V3c307502010-08-30 16:04:35 +0000747 dentry->d_op = &v9fs_cached_dentry_operations;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530748 d_instantiate(dentry, inode);
749 err = v9fs_fid_add(dentry, fid);
750 if (err < 0)
751 goto error;
752 /* The fid would get clunked via a dput */
753 fid = NULL;
754 } else {
755 /*
756 * Not in cached mode. No need to populate
757 * inode with stat. We need to get an inode
758 * so that we can set the acl with dentry
759 */
760 inode = v9fs_get_inode(dir->i_sb, mode);
761 if (IS_ERR(inode)) {
762 err = PTR_ERR(inode);
763 goto error;
764 }
Aneesh Kumar K.V3c307502010-08-30 16:04:35 +0000765 dentry->d_op = &v9fs_dentry_operations;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530766 d_instantiate(dentry, inode);
767 }
768 /* Now set the ACL based on the default value */
769 v9fs_set_create_acl(dentry, dacl, pacl);
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700770
771 /* if we are opening a file, assign the open fid to the file */
772 if (nd && nd->flags & LOOKUP_OPEN) {
Aneesh Kumar K.V877cb3d2010-09-22 12:42:30 +0530773 filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -0700774 if (IS_ERR(filp)) {
775 p9_client_clunk(ofid);
776 return PTR_ERR(filp);
777 }
778 filp->private_data = ofid;
779 } else
780 p9_client_clunk(ofid);
781
782 return 0;
783
784error:
785 if (ofid)
786 p9_client_clunk(ofid);
787 if (fid)
788 p9_client_clunk(fid);
789 return err;
790}
791
792/**
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700793 * v9fs_vfs_create - VFS hook to create files
Eric Van Hensbergenee443992008-03-05 07:08:09 -0600794 * @dir: directory inode that is being created
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700795 * @dentry: dentry that is being deleted
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800796 * @mode: create permissions
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700797 * @nd: path information
798 *
799 */
800
801static int
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800802v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700803 struct nameidata *nd)
804{
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800805 int err;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500806 u32 perm;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800807 int flags;
808 struct v9fs_session_info *v9ses;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500809 struct p9_fid *fid;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800810 struct file *filp;
811
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500812 err = 0;
813 fid = NULL;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800814 v9ses = v9fs_inode2v9ses(dir);
Eric Van Hensbergenda977b22007-01-26 00:57:06 -0800815 perm = unixmode2p9mode(v9ses, mode);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800816 if (nd && nd->flags & LOOKUP_OPEN)
817 flags = nd->intent.open.flags - 1;
818 else
819 flags = O_RDWR;
820
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500821 fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
Sripathi Kodidd6102f2010-03-05 18:48:00 +0000822 v9fs_uflags2omode(flags,
823 v9fs_proto_dotu(v9ses)));
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500824 if (IS_ERR(fid)) {
825 err = PTR_ERR(fid);
826 fid = NULL;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800827 goto error;
828 }
829
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500830 /* if we are opening a file, assign the open fid to the file */
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800831 if (nd && nd->flags & LOOKUP_OPEN) {
Aneesh Kumar K.V877cb3d2010-09-22 12:42:30 +0530832 filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800833 if (IS_ERR(filp)) {
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500834 err = PTR_ERR(filp);
835 goto error;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800836 }
837
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500838 filp->private_data = fid;
839 } else
840 p9_client_clunk(fid);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800841
842 return 0;
843
844error:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500845 if (fid)
846 p9_client_clunk(fid);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800847
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800848 return err;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700849}
850
851/**
852 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
Eric Van Hensbergenee443992008-03-05 07:08:09 -0600853 * @dir: inode that is being unlinked
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700854 * @dentry: dentry that is being unlinked
855 * @mode: mode for new directory
856 *
857 */
858
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800859static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700860{
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800861 int err;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500862 u32 perm;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800863 struct v9fs_session_info *v9ses;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500864 struct p9_fid *fid;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800865
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500866 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
867 err = 0;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800868 v9ses = v9fs_inode2v9ses(dir);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800869 perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500870 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD);
871 if (IS_ERR(fid)) {
872 err = PTR_ERR(fid);
873 fid = NULL;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800874 }
875
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500876 if (fid)
877 p9_client_clunk(fid);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800878
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -0800879 return err;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700880}
881
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530882
883/**
884 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
885 * @dir: inode that is being unlinked
886 * @dentry: dentry that is being unlinked
887 * @mode: mode for new directory
888 *
889 */
890
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530891static int v9fs_vfs_mkdir_dotl(struct inode *dir,
892 struct dentry *dentry, int omode)
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530893{
894 int err;
895 struct v9fs_session_info *v9ses;
896 struct p9_fid *fid = NULL, *dfid = NULL;
897 gid_t gid;
898 char *name;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530899 mode_t mode;
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530900 struct inode *inode;
901 struct p9_qid qid;
902 struct dentry *dir_dentry;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530903 struct posix_acl *dacl = NULL, *pacl = NULL;
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530904
905 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
906 err = 0;
907 v9ses = v9fs_inode2v9ses(dir);
908
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530909 omode |= S_IFDIR;
Harsh Prateek Bora7c7298c2010-08-18 06:01:52 +0000910 if (dir->i_mode & S_ISGID)
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530911 omode |= S_ISGID;
912
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530913 dir_dentry = v9fs_dentry_from_dir_inode(dir);
914 dfid = v9fs_fid_lookup(dir_dentry);
915 if (IS_ERR(dfid)) {
916 err = PTR_ERR(dfid);
917 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
918 dfid = NULL;
919 goto error;
920 }
921
922 gid = v9fs_get_fsgid_for_create(dir);
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530923 mode = omode;
924 /* Update mode based on ACL value */
925 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
926 if (err) {
927 P9_DPRINTK(P9_DEBUG_VFS,
928 "Failed to get acl values in mkdir %d\n", err);
929 goto error;
930 }
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530931 name = (char *) dentry->d_name.name;
932 err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
933 if (err < 0)
934 goto error;
935
936 /* instantiate inode and assign the unopened fid to the dentry */
937 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
938 fid = p9_client_walk(dfid, 1, &name, 1);
939 if (IS_ERR(fid)) {
940 err = PTR_ERR(fid);
941 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
942 err);
943 fid = NULL;
944 goto error;
945 }
946
947 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
948 if (IS_ERR(inode)) {
949 err = PTR_ERR(inode);
950 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
951 err);
952 goto error;
953 }
954 dentry->d_op = &v9fs_cached_dentry_operations;
955 d_instantiate(dentry, inode);
956 err = v9fs_fid_add(dentry, fid);
957 if (err < 0)
958 goto error;
959 fid = NULL;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530960 } else {
961 /*
962 * Not in cached mode. No need to populate
963 * inode with stat. We need to get an inode
964 * so that we can set the acl with dentry
965 */
966 inode = v9fs_get_inode(dir->i_sb, mode);
967 if (IS_ERR(inode)) {
968 err = PTR_ERR(inode);
969 goto error;
970 }
971 dentry->d_op = &v9fs_dentry_operations;
972 d_instantiate(dentry, inode);
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530973 }
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +0530974 /* Now set the ACL based on the default value */
975 v9fs_set_create_acl(dentry, dacl, pacl);
976
M. Mohan Kumar01a622b2010-06-16 14:27:22 +0530977error:
978 if (fid)
979 p9_client_clunk(fid);
980 return err;
981}
982
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700983/**
984 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
985 * @dir: inode that is being walked from
986 * @dentry: dentry that is being walked to?
987 * @nameidata: path data
988 *
989 */
990
991static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
992 struct nameidata *nameidata)
993{
994 struct super_block *sb;
995 struct v9fs_session_info *v9ses;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500996 struct p9_fid *dfid, *fid;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700997 struct inode *inode;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -0500998 char *name;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -0700999 int result = 0;
1000
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001001 P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
Latchesar Ionkov731805b2006-03-07 21:55:42 -08001002 dir, dentry->d_name.name, dentry, nameidata);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001003
Sripathi Kodi11e9b492010-03-29 18:13:59 -05001004 if (dentry->d_name.len > NAME_MAX)
1005 return ERR_PTR(-ENAMETOOLONG);
1006
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001007 sb = dir->i_sb;
1008 v9ses = v9fs_inode2v9ses(dir);
Aneesh Kumar K.Va534c8d2010-06-30 19:18:50 +05301009 /* We can walk d_parent because we hold the dir->i_mutex */
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001010 dfid = v9fs_fid_lookup(dentry->d_parent);
1011 if (IS_ERR(dfid))
David Howellse231c2e2008-02-07 00:15:26 -08001012 return ERR_CAST(dfid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001013
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001014 name = (char *) dentry->d_name.name;
1015 fid = p9_client_walk(dfid, 1, &name, 1);
1016 if (IS_ERR(fid)) {
1017 result = PTR_ERR(fid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001018 if (result == -ENOENT) {
Aneesh Kumar K.V85e0df22010-05-14 13:04:39 +00001019 inode = NULL;
1020 goto inst_out;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001021 }
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001022
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001023 return ERR_PTR(result);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001024 }
1025
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001026 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1027 if (IS_ERR(inode)) {
1028 result = PTR_ERR(inode);
1029 inode = NULL;
1030 goto error;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001031 }
1032
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001033 result = v9fs_fid_add(dentry, fid);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -08001034 if (result < 0)
Aneesh Kumar K.V9856af82010-09-22 12:24:23 +05301035 goto error_iput;
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -08001036
Aneesh Kumar K.V85e0df22010-05-14 13:04:39 +00001037inst_out:
1038 if (v9ses->cache)
Eric Van Hensbergene03abc02007-02-11 13:21:39 -06001039 dentry->d_op = &v9fs_cached_dentry_operations;
1040 else
1041 dentry->d_op = &v9fs_dentry_operations;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001042
1043 d_add(dentry, inode);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001044 return NULL;
1045
Aneesh Kumar K.V9856af82010-09-22 12:24:23 +05301046error_iput:
1047 iput(inode);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001048error:
Julien Brunel62aa5282008-09-24 16:22:22 -05001049 p9_client_clunk(fid);
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001050
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001051 return ERR_PTR(result);
1052}
1053
1054/**
1055 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
1056 * @i: inode that is being unlinked
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07001057 * @d: dentry that is being unlinked
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001058 *
1059 */
1060
1061static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
1062{
1063 return v9fs_remove(i, d, 0);
1064}
1065
1066/**
1067 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
1068 * @i: inode that is being unlinked
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07001069 * @d: dentry that is being unlinked
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001070 *
1071 */
1072
1073static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
1074{
1075 return v9fs_remove(i, d, 1);
1076}
1077
1078/**
1079 * v9fs_vfs_rename - VFS hook to rename an inode
1080 * @old_dir: old dir inode
1081 * @old_dentry: old dentry
1082 * @new_dir: new dir inode
1083 * @new_dentry: new dentry
1084 *
1085 */
1086
1087static int
1088v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1089 struct inode *new_dir, struct dentry *new_dentry)
1090{
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001091 struct inode *old_inode;
1092 struct v9fs_session_info *v9ses;
1093 struct p9_fid *oldfid;
1094 struct p9_fid *olddirfid;
1095 struct p9_fid *newdirfid;
1096 struct p9_wstat wstat;
1097 int retval;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001098
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001099 P9_DPRINTK(P9_DEBUG_VFS, "\n");
1100 retval = 0;
1101 old_inode = old_dentry->d_inode;
1102 v9ses = v9fs_inode2v9ses(old_inode);
1103 oldfid = v9fs_fid_lookup(old_dentry);
Latchesar Ionkovba176742007-10-17 14:31:07 -05001104 if (IS_ERR(oldfid))
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001105 return PTR_ERR(oldfid);
1106
1107 olddirfid = v9fs_fid_clone(old_dentry->d_parent);
Latchesar Ionkovba176742007-10-17 14:31:07 -05001108 if (IS_ERR(olddirfid)) {
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001109 retval = PTR_ERR(olddirfid);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001110 goto done;
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001111 }
1112
1113 newdirfid = v9fs_fid_clone(new_dentry->d_parent);
Latchesar Ionkovba176742007-10-17 14:31:07 -05001114 if (IS_ERR(newdirfid)) {
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001115 retval = PTR_ERR(newdirfid);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001116 goto clunk_olddir;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001117 }
1118
Aneesh Kumar K.Va534c8d2010-06-30 19:18:50 +05301119 down_write(&v9ses->rename_sem);
Sripathi Kodi4681dbd2010-03-25 12:47:26 +00001120 if (v9fs_proto_dotl(v9ses)) {
1121 retval = p9_client_rename(oldfid, newdirfid,
1122 (char *) new_dentry->d_name.name);
1123 if (retval != -ENOSYS)
1124 goto clunk_newdir;
1125 }
Aneesh Kumar K.Va534c8d2010-06-30 19:18:50 +05301126 if (old_dentry->d_parent != new_dentry->d_parent) {
1127 /*
1128 * 9P .u can only handle file rename in the same directory
1129 */
Sripathi Kodi4681dbd2010-03-25 12:47:26 +00001130
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001131 P9_DPRINTK(P9_DEBUG_ERROR,
1132 "old dir and new dir are different\n");
Eric Van Hensbergen621997c2007-01-26 00:57:04 -08001133 retval = -EXDEV;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001134 goto clunk_newdir;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001135 }
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001136 v9fs_blank_wstat(&wstat);
Latchesar Ionkovba176742007-10-17 14:31:07 -05001137 wstat.muid = v9ses->uname;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001138 wstat.name = (char *) new_dentry->d_name.name;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001139 retval = p9_client_wstat(oldfid, &wstat);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001140
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001141clunk_newdir:
Aneesh Kumar K.Va534c8d2010-06-30 19:18:50 +05301142 if (!retval)
1143 /* successful rename */
1144 d_move(old_dentry, new_dentry);
1145 up_write(&v9ses->rename_sem);
Latchesar Ionkov22150c42007-10-23 13:48:33 -05001146 p9_client_clunk(newdirfid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001147
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001148clunk_olddir:
Latchesar Ionkov22150c42007-10-23 13:48:33 -05001149 p9_client_clunk(olddirfid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001150
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001151done:
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001152 return retval;
1153}
1154
1155/**
Adrian Bunk943ffb52006-01-10 00:10:13 +01001156 * v9fs_vfs_getattr - retrieve file metadata
Eric Van Hensbergenee443992008-03-05 07:08:09 -06001157 * @mnt: mount information
1158 * @dentry: file to get attributes on
1159 * @stat: metadata structure to populate
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001160 *
1161 */
1162
1163static int
1164v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1165 struct kstat *stat)
1166{
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001167 int err;
1168 struct v9fs_session_info *v9ses;
1169 struct p9_fid *fid;
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001170 struct p9_wstat *st;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001171
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001172 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
1173 err = -EPERM;
1174 v9ses = v9fs_inode2v9ses(dentry->d_inode);
Abhishek Kulkarni60e78d22009-09-23 13:00:27 -05001175 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
Eric Van Hensbergen9523a842007-07-13 13:01:27 -05001176 return simple_getattr(mnt, dentry, stat);
1177
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001178 fid = v9fs_fid_lookup(dentry);
1179 if (IS_ERR(fid))
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001180 return PTR_ERR(fid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001181
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001182 st = p9_client_stat(fid);
1183 if (IS_ERR(st))
1184 return PTR_ERR(st);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001185
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001186 v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001187 generic_fillattr(dentry->d_inode, stat);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001188
Latchesar Ionkov62b2be52010-08-24 18:13:59 +00001189 p9stat_free(st);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001190 kfree(st);
1191 return 0;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001192}
1193
Sripathi Kodif0853122010-07-12 20:07:23 +05301194static int
1195v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
1196 struct kstat *stat)
1197{
1198 int err;
1199 struct v9fs_session_info *v9ses;
1200 struct p9_fid *fid;
1201 struct p9_stat_dotl *st;
1202
1203 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
1204 err = -EPERM;
1205 v9ses = v9fs_inode2v9ses(dentry->d_inode);
1206 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
1207 return simple_getattr(mnt, dentry, stat);
1208
1209 fid = v9fs_fid_lookup(dentry);
1210 if (IS_ERR(fid))
1211 return PTR_ERR(fid);
1212
1213 /* Ask for all the fields in stat structure. Server will return
1214 * whatever it supports
1215 */
1216
1217 st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
1218 if (IS_ERR(st))
1219 return PTR_ERR(st);
1220
1221 v9fs_stat2inode_dotl(st, dentry->d_inode);
1222 generic_fillattr(dentry->d_inode, stat);
1223 /* Change block size to what the server returned */
1224 stat->blksize = st->st_blksize;
1225
1226 kfree(st);
1227 return 0;
1228}
1229
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001230/**
1231 * v9fs_vfs_setattr - set file metadata
1232 * @dentry: file whose metadata to set
1233 * @iattr: metadata assignment structure
1234 *
1235 */
1236
1237static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
1238{
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001239 int retval;
1240 struct v9fs_session_info *v9ses;
1241 struct p9_fid *fid;
1242 struct p9_wstat wstat;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001243
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001244 P9_DPRINTK(P9_DEBUG_VFS, "\n");
1245 retval = -EPERM;
1246 v9ses = v9fs_inode2v9ses(dentry->d_inode);
1247 fid = v9fs_fid_lookup(dentry);
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001248 if(IS_ERR(fid))
1249 return PTR_ERR(fid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001250
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001251 v9fs_blank_wstat(&wstat);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001252 if (iattr->ia_valid & ATTR_MODE)
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001253 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001254
1255 if (iattr->ia_valid & ATTR_MTIME)
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001256 wstat.mtime = iattr->ia_mtime.tv_sec;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001257
1258 if (iattr->ia_valid & ATTR_ATIME)
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001259 wstat.atime = iattr->ia_atime.tv_sec;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001260
1261 if (iattr->ia_valid & ATTR_SIZE)
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001262 wstat.length = iattr->ia_size;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001263
Sripathi Kodidd6102f2010-03-05 18:48:00 +00001264 if (v9fs_proto_dotu(v9ses)) {
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001265 if (iattr->ia_valid & ATTR_UID)
1266 wstat.n_uid = iattr->ia_uid;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001267
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001268 if (iattr->ia_valid & ATTR_GID)
1269 wstat.n_gid = iattr->ia_gid;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001270 }
1271
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001272 retval = p9_client_wstat(fid, &wstat);
Christoph Hellwig10257742010-06-04 11:30:02 +02001273 if (retval < 0)
1274 return retval;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001275
Christoph Hellwig10257742010-06-04 11:30:02 +02001276 if ((iattr->ia_valid & ATTR_SIZE) &&
1277 iattr->ia_size != i_size_read(dentry->d_inode)) {
1278 retval = vmtruncate(dentry->d_inode, iattr->ia_size);
1279 if (retval)
1280 return retval;
1281 }
1282
1283 setattr_copy(dentry->d_inode, iattr);
1284 mark_inode_dirty(dentry->d_inode);
1285 return 0;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001286}
1287
1288/**
Sripathi Kodi87d78452010-06-18 11:50:10 +05301289 * v9fs_vfs_setattr_dotl - set file metadata
1290 * @dentry: file whose metadata to set
1291 * @iattr: metadata assignment structure
1292 *
1293 */
1294
Aneesh Kumar K.V22d8dcd2010-09-28 00:27:40 +05301295int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
Sripathi Kodi87d78452010-06-18 11:50:10 +05301296{
1297 int retval;
1298 struct v9fs_session_info *v9ses;
1299 struct p9_fid *fid;
1300 struct p9_iattr_dotl p9attr;
1301
1302 P9_DPRINTK(P9_DEBUG_VFS, "\n");
1303
1304 retval = inode_change_ok(dentry->d_inode, iattr);
1305 if (retval)
1306 return retval;
1307
1308 p9attr.valid = iattr->ia_valid;
1309 p9attr.mode = iattr->ia_mode;
1310 p9attr.uid = iattr->ia_uid;
1311 p9attr.gid = iattr->ia_gid;
1312 p9attr.size = iattr->ia_size;
1313 p9attr.atime_sec = iattr->ia_atime.tv_sec;
1314 p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
1315 p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
1316 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
1317
1318 retval = -EPERM;
1319 v9ses = v9fs_inode2v9ses(dentry->d_inode);
1320 fid = v9fs_fid_lookup(dentry);
1321 if (IS_ERR(fid))
1322 return PTR_ERR(fid);
1323
1324 retval = p9_client_setattr(fid, &p9attr);
Stephen Rothwell8cef9c62010-06-22 11:15:01 +10001325 if (retval < 0)
1326 return retval;
Sripathi Kodi87d78452010-06-18 11:50:10 +05301327
Stephen Rothwell8cef9c62010-06-22 11:15:01 +10001328 if ((iattr->ia_valid & ATTR_SIZE) &&
1329 iattr->ia_size != i_size_read(dentry->d_inode)) {
1330 retval = vmtruncate(dentry->d_inode, iattr->ia_size);
1331 if (retval)
1332 return retval;
1333 }
1334
1335 setattr_copy(dentry->d_inode, iattr);
1336 mark_inode_dirty(dentry->d_inode);
Aneesh Kumar K.V6e8dc552010-09-28 00:27:40 +05301337 if (iattr->ia_valid & ATTR_MODE) {
1338 /* We also want to update ACL when we update mode bits */
1339 retval = v9fs_acl_chmod(dentry);
1340 if (retval < 0)
1341 return retval;
1342 }
Stephen Rothwell8cef9c62010-06-22 11:15:01 +10001343 return 0;
Sripathi Kodi87d78452010-06-18 11:50:10 +05301344}
1345
1346/**
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001347 * v9fs_stat2inode - populate an inode structure with mistat info
1348 * @stat: Plan 9 metadata (mistat) structure
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001349 * @inode: inode to populate
1350 * @sb: superblock of filesystem
1351 *
1352 */
1353
1354void
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001355v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001356 struct super_block *sb)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001357{
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001358 char ext[32];
Aneesh Kumar K.V57171442010-03-05 14:43:43 -06001359 char tag_name[14];
1360 unsigned int i_nlink;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001361 struct v9fs_session_info *v9ses = sb->s_fs_info;
1362
1363 inode->i_nlink = 1;
1364
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001365 inode->i_atime.tv_sec = stat->atime;
1366 inode->i_mtime.tv_sec = stat->mtime;
1367 inode->i_ctime.tv_sec = stat->mtime;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001368
Latchesar Ionkovbd32b822007-10-17 14:31:07 -05001369 inode->i_uid = v9ses->dfltuid;
1370 inode->i_gid = v9ses->dfltgid;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001371
Sripathi Kodidd6102f2010-03-05 18:48:00 +00001372 if (v9fs_proto_dotu(v9ses)) {
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001373 inode->i_uid = stat->n_uid;
1374 inode->i_gid = stat->n_gid;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001375 }
Aneesh Kumar K.V57171442010-03-05 14:43:43 -06001376 if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
1377 if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) {
1378 /*
1379 * Hadlink support got added later to
1380 * to the .u extension. So there can be
1381 * server out there that doesn't support
1382 * this even with .u extension. So check
1383 * for non NULL stat->extension
1384 */
1385 strncpy(ext, stat->extension, sizeof(ext));
1386 /* HARDLINKCOUNT %u */
1387 sscanf(ext, "%13s %u", tag_name, &i_nlink);
1388 if (!strncmp(tag_name, "HARDLINKCOUNT", 13))
1389 inode->i_nlink = i_nlink;
1390 }
1391 }
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001392 inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001393 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
1394 char type = 0;
1395 int major = -1;
1396 int minor = -1;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001397
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001398 strncpy(ext, stat->extension, sizeof(ext));
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001399 sscanf(ext, "%c %u %u", &type, &major, &minor);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001400 switch (type) {
1401 case 'c':
1402 inode->i_mode &= ~S_IFBLK;
1403 inode->i_mode |= S_IFCHR;
1404 break;
1405 case 'b':
1406 break;
1407 default:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001408 P9_DPRINTK(P9_DEBUG_ERROR,
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001409 "Unknown special type %c %s\n", type,
1410 stat->extension);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001411 };
1412 inode->i_rdev = MKDEV(major, minor);
Magnus Deininger57c7b4e2008-10-17 12:44:46 -05001413 init_special_inode(inode, inode->i_mode, inode->i_rdev);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001414 } else
1415 inode->i_rdev = 0;
1416
Abhishek Kulkarni7549ae32009-09-22 11:34:05 -05001417 i_size_write(inode, stat->length);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001418
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001419 /* not real number of blocks, but 512 byte ones ... */
Abhishek Kulkarni7549ae32009-09-22 11:34:05 -05001420 inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001421}
1422
1423/**
Sripathi Kodif0853122010-07-12 20:07:23 +05301424 * v9fs_stat2inode_dotl - populate an inode structure with stat info
1425 * @stat: stat structure
1426 * @inode: inode to populate
1427 * @sb: superblock of filesystem
1428 *
1429 */
1430
1431void
1432v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
1433{
1434
1435 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
1436 inode->i_atime.tv_sec = stat->st_atime_sec;
1437 inode->i_atime.tv_nsec = stat->st_atime_nsec;
1438 inode->i_mtime.tv_sec = stat->st_mtime_sec;
1439 inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
1440 inode->i_ctime.tv_sec = stat->st_ctime_sec;
1441 inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
1442 inode->i_uid = stat->st_uid;
1443 inode->i_gid = stat->st_gid;
1444 inode->i_nlink = stat->st_nlink;
1445 inode->i_mode = stat->st_mode;
1446 inode->i_rdev = new_decode_dev(stat->st_rdev);
1447
1448 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
1449 init_special_inode(inode, inode->i_mode, inode->i_rdev);
1450
1451 i_size_write(inode, stat->st_size);
1452 inode->i_blocks = stat->st_blocks;
1453 } else {
1454 if (stat->st_result_mask & P9_STATS_ATIME) {
1455 inode->i_atime.tv_sec = stat->st_atime_sec;
1456 inode->i_atime.tv_nsec = stat->st_atime_nsec;
1457 }
1458 if (stat->st_result_mask & P9_STATS_MTIME) {
1459 inode->i_mtime.tv_sec = stat->st_mtime_sec;
1460 inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
1461 }
1462 if (stat->st_result_mask & P9_STATS_CTIME) {
1463 inode->i_ctime.tv_sec = stat->st_ctime_sec;
1464 inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
1465 }
1466 if (stat->st_result_mask & P9_STATS_UID)
1467 inode->i_uid = stat->st_uid;
1468 if (stat->st_result_mask & P9_STATS_GID)
1469 inode->i_gid = stat->st_gid;
1470 if (stat->st_result_mask & P9_STATS_NLINK)
1471 inode->i_nlink = stat->st_nlink;
1472 if (stat->st_result_mask & P9_STATS_MODE) {
1473 inode->i_mode = stat->st_mode;
1474 if ((S_ISBLK(inode->i_mode)) ||
1475 (S_ISCHR(inode->i_mode)))
1476 init_special_inode(inode, inode->i_mode,
1477 inode->i_rdev);
1478 }
1479 if (stat->st_result_mask & P9_STATS_RDEV)
1480 inode->i_rdev = new_decode_dev(stat->st_rdev);
1481 if (stat->st_result_mask & P9_STATS_SIZE)
1482 i_size_write(inode, stat->st_size);
1483 if (stat->st_result_mask & P9_STATS_BLOCKS)
1484 inode->i_blocks = stat->st_blocks;
1485 }
1486 if (stat->st_result_mask & P9_STATS_GEN)
1487 inode->i_generation = stat->st_gen;
1488
1489 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
1490 * because the inode structure does not have fields for them.
1491 */
1492}
1493
1494/**
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001495 * v9fs_qid2ino - convert qid into inode number
1496 * @qid: qid to hash
1497 *
1498 * BUG: potential for inode number collisions?
1499 */
1500
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001501ino_t v9fs_qid2ino(struct p9_qid *qid)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001502{
1503 u64 path = qid->path + 2;
1504 ino_t i = 0;
1505
1506 if (sizeof(ino_t) == sizeof(path))
1507 memcpy(&i, &path, sizeof(ino_t));
1508 else
1509 i = (ino_t) (path ^ (path >> 32));
1510
1511 return i;
1512}
1513
1514/**
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001515 * v9fs_readlink - read a symlink's location (internal version)
1516 * @dentry: dentry for symlink
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07001517 * @buffer: buffer to load symlink location into
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001518 * @buflen: length of buffer
1519 *
1520 */
1521
1522static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1523{
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001524 int retval;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001525
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001526 struct v9fs_session_info *v9ses;
1527 struct p9_fid *fid;
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001528 struct p9_wstat *st;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001529
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001530 P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
1531 retval = -EPERM;
1532 v9ses = v9fs_inode2v9ses(dentry->d_inode);
1533 fid = v9fs_fid_lookup(dentry);
Latchesar Ionkovba176742007-10-17 14:31:07 -05001534 if (IS_ERR(fid))
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001535 return PTR_ERR(fid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001536
M. Mohan Kumar329176c2010-09-28 19:59:25 +05301537 if (!v9fs_proto_dotu(v9ses))
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001538 return -EBADF;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001539
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001540 st = p9_client_stat(fid);
1541 if (IS_ERR(st))
1542 return PTR_ERR(st);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001543
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001544 if (!(st->mode & P9_DMSYMLINK)) {
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001545 retval = -EINVAL;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001546 goto done;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001547 }
1548
1549 /* copy extension buffer into buffer */
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001550 strncpy(buffer, st->extension, buflen);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001551
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001552 P9_DPRINTK(P9_DEBUG_VFS,
Eric Van Hensbergen51a87c52008-10-16 08:30:07 -05001553 "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001554
Martin Stava2511cd02009-11-02 08:39:34 -06001555 retval = strnlen(buffer, buflen);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001556done:
Latchesar Ionkov62b2be52010-08-24 18:13:59 +00001557 p9stat_free(st);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001558 kfree(st);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001559 return retval;
1560}
1561
1562/**
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001563 * v9fs_vfs_follow_link - follow a symlink path
1564 * @dentry: dentry for symlink
1565 * @nd: nameidata
1566 *
1567 */
1568
1569static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
1570{
1571 int len = 0;
1572 char *link = __getname();
1573
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001574 P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001575
1576 if (!link)
1577 link = ERR_PTR(-ENOMEM);
1578 else {
Latchesar Ionkov16cce6d2006-03-25 03:07:26 -08001579 len = v9fs_readlink(dentry, link, PATH_MAX);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001580
1581 if (len < 0) {
Davi Arnautce44eeb2005-11-07 00:59:36 -08001582 __putname(link);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001583 link = ERR_PTR(len);
1584 } else
Martin Stava2511cd02009-11-02 08:39:34 -06001585 link[min(len, PATH_MAX-1)] = 0;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001586 }
1587 nd_set_link(nd, link);
1588
1589 return NULL;
1590}
1591
1592/**
1593 * v9fs_vfs_put_link - release a symlink path
1594 * @dentry: dentry for symlink
1595 * @nd: nameidata
Eric Van Hensbergenee443992008-03-05 07:08:09 -06001596 * @p: unused
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001597 *
1598 */
1599
Eric Van Hensbergenee443992008-03-05 07:08:09 -06001600static void
1601v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001602{
1603 char *s = nd_get_link(nd);
1604
Duane Griffin6ff23202008-12-19 16:45:21 -06001605 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
1606 IS_ERR(s) ? "<error>" : s);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001607 if (!IS_ERR(s))
Davi Arnautce44eeb2005-11-07 00:59:36 -08001608 __putname(s);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001609}
1610
Eric Van Hensbergenee443992008-03-05 07:08:09 -06001611/**
1612 * v9fs_vfs_mkspecial - create a special file
1613 * @dir: inode to create special file in
1614 * @dentry: dentry to create
1615 * @mode: mode to create special file
1616 * @extension: 9p2000.u format extension string representing special file
1617 *
1618 */
1619
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001620static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1621 int mode, const char *extension)
1622{
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001623 u32 perm;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001624 struct v9fs_session_info *v9ses;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001625 struct p9_fid *fid;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001626
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -08001627 v9ses = v9fs_inode2v9ses(dir);
Sripathi Kodidd6102f2010-03-05 18:48:00 +00001628 if (!v9fs_proto_dotu(v9ses)) {
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001629 P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n");
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -08001630 return -EPERM;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001631 }
1632
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001633 perm = unixmode2p9mode(v9ses, mode);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001634 fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm,
1635 P9_OREAD);
1636 if (IS_ERR(fid))
1637 return PTR_ERR(fid);
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001638
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001639 p9_client_clunk(fid);
Latchesar Ionkov6a3124a2006-03-02 02:54:30 -08001640 return 0;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001641}
1642
1643/**
Venkateswararao Jujjuri (JV)50cc42f2010-06-09 15:59:31 -07001644 * v9fs_vfs_symlink_dotl - helper function to create symlinks
1645 * @dir: directory inode containing symlink
1646 * @dentry: dentry for symlink
1647 * @symname: symlink data
1648 *
1649 * See Also: 9P2000.L RFC for more information
1650 *
1651 */
1652
1653static int
1654v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
1655 const char *symname)
1656{
1657 struct v9fs_session_info *v9ses;
1658 struct p9_fid *dfid;
1659 struct p9_fid *fid = NULL;
1660 struct inode *inode;
1661 struct p9_qid qid;
1662 char *name;
1663 int err;
1664 gid_t gid;
1665
1666 name = (char *) dentry->d_name.name;
1667 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
1668 dir->i_ino, name, symname);
1669 v9ses = v9fs_inode2v9ses(dir);
1670
1671 dfid = v9fs_fid_lookup(dentry->d_parent);
1672 if (IS_ERR(dfid)) {
1673 err = PTR_ERR(dfid);
1674 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
1675 return err;
1676 }
1677
1678 gid = v9fs_get_fsgid_for_create(dir);
1679
Venkateswararao Jujjuri (JV)50cc42f2010-06-09 15:59:31 -07001680 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
1681 err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
1682
1683 if (err < 0) {
1684 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
1685 goto error;
1686 }
1687
1688 if (v9ses->cache) {
1689 /* Now walk from the parent so we can get an unopened fid. */
1690 fid = p9_client_walk(dfid, 1, &name, 1);
1691 if (IS_ERR(fid)) {
1692 err = PTR_ERR(fid);
1693 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
1694 err);
1695 fid = NULL;
1696 goto error;
1697 }
1698
1699 /* instantiate inode and assign the unopened fid to dentry */
1700 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1701 if (IS_ERR(inode)) {
1702 err = PTR_ERR(inode);
1703 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
1704 err);
1705 goto error;
1706 }
1707 dentry->d_op = &v9fs_cached_dentry_operations;
1708 d_instantiate(dentry, inode);
1709 err = v9fs_fid_add(dentry, fid);
1710 if (err < 0)
1711 goto error;
1712 fid = NULL;
1713 } else {
1714 /* Not in cached mode. No need to populate inode with stat */
1715 inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
1716 if (IS_ERR(inode)) {
1717 err = PTR_ERR(inode);
1718 goto error;
1719 }
1720 dentry->d_op = &v9fs_dentry_operations;
1721 d_instantiate(dentry, inode);
1722 }
1723
1724error:
1725 if (fid)
1726 p9_client_clunk(fid);
1727
1728 return err;
1729}
1730
1731/**
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001732 * v9fs_vfs_symlink - helper function to create symlinks
1733 * @dir: directory inode containing symlink
1734 * @dentry: dentry for symlink
1735 * @symname: symlink data
1736 *
Eric Van Hensbergenee443992008-03-05 07:08:09 -06001737 * See Also: 9P2000.u RFC for more information
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001738 *
1739 */
1740
1741static int
1742v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1743{
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001744 P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino,
1745 dentry->d_name.name, symname);
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001746
1747 return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname);
1748}
1749
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001750/**
1751 * v9fs_vfs_link - create a hardlink
1752 * @old_dentry: dentry for file to link to
1753 * @dir: inode destination for new link
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07001754 * @dentry: dentry for link
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001755 *
1756 */
1757
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001758static int
1759v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1760 struct dentry *dentry)
1761{
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001762 int retval;
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001763 struct p9_fid *oldfid;
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001764 char *name;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001765
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001766 P9_DPRINTK(P9_DEBUG_VFS,
1767 " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001768 old_dentry->d_name.name);
1769
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001770 oldfid = v9fs_fid_clone(old_dentry);
Latchesar Ionkovba176742007-10-17 14:31:07 -05001771 if (IS_ERR(oldfid))
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001772 return PTR_ERR(oldfid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001773
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001774 name = __getname();
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001775 if (unlikely(!name)) {
1776 retval = -ENOMEM;
1777 goto clunk_fid;
1778 }
Florin Malita0710d362006-06-25 05:48:31 -07001779
Latchesar Ionkov16cce6d2006-03-25 03:07:26 -08001780 sprintf(name, "%d\n", oldfid->fid);
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001781 retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name);
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001782 __putname(name);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001783
Eric Van Hensbergenda977b22007-01-26 00:57:06 -08001784clunk_fid:
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001785 p9_client_clunk(oldfid);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001786 return retval;
1787}
1788
1789/**
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -05001790 * v9fs_vfs_link_dotl - create a hardlink for dotl
1791 * @old_dentry: dentry for file to link to
1792 * @dir: inode destination for new link
1793 * @dentry: dentry for link
1794 *
1795 */
1796
1797static int
1798v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
1799 struct dentry *dentry)
1800{
1801 int err;
1802 struct p9_fid *dfid, *oldfid;
1803 char *name;
1804 struct v9fs_session_info *v9ses;
1805 struct dentry *dir_dentry;
1806
1807 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
1808 dir->i_ino, old_dentry->d_name.name,
1809 dentry->d_name.name);
1810
1811 v9ses = v9fs_inode2v9ses(dir);
1812 dir_dentry = v9fs_dentry_from_dir_inode(dir);
1813 dfid = v9fs_fid_lookup(dir_dentry);
1814 if (IS_ERR(dfid))
1815 return PTR_ERR(dfid);
1816
1817 oldfid = v9fs_fid_lookup(old_dentry);
1818 if (IS_ERR(oldfid))
1819 return PTR_ERR(oldfid);
1820
1821 name = (char *) dentry->d_name.name;
1822
1823 err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
1824
1825 if (err < 0) {
1826 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
1827 return err;
1828 }
1829
1830 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
1831 /* Get the latest stat info from server. */
1832 struct p9_fid *fid;
1833 struct p9_stat_dotl *st;
1834
1835 fid = v9fs_fid_lookup(old_dentry);
1836 if (IS_ERR(fid))
1837 return PTR_ERR(fid);
1838
1839 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
1840 if (IS_ERR(st))
1841 return PTR_ERR(st);
1842
1843 v9fs_stat2inode_dotl(st, old_dentry->d_inode);
1844
1845 kfree(st);
1846 } else {
1847 /* Caching disabled. No need to get upto date stat info.
Al Viro7de9c6e2010-10-23 11:11:40 -04001848 * This dentry will be released immediately. So, just hold the
1849 * inode
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -05001850 */
Al Viro7de9c6e2010-10-23 11:11:40 -04001851 ihold(old_dentry->d_inode);
Eric Van Hensbergen09d34ee2010-08-02 14:28:09 -05001852 }
1853
1854 dentry->d_op = old_dentry->d_op;
1855 d_instantiate(dentry, old_dentry->d_inode);
1856
1857 return err;
1858}
1859
1860/**
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001861 * v9fs_vfs_mknod - create a special file
1862 * @dir: inode destination for new link
1863 * @dentry: dentry for file
1864 * @mode: mode for creation
Eric Van Hensbergenee443992008-03-05 07:08:09 -06001865 * @rdev: device associated with special file
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001866 *
1867 */
1868
1869static int
1870v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1871{
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001872 int retval;
1873 char *name;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001874
Latchesar Ionkovbd238fb2007-07-10 17:57:28 -05001875 P9_DPRINTK(P9_DEBUG_VFS,
1876 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001877 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
1878
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001879 if (!new_valid_dev(rdev))
1880 return -EINVAL;
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07001881
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001882 name = __getname();
Eugene Teoc0291a02006-03-25 03:07:27 -08001883 if (!name)
1884 return -ENOMEM;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001885 /* build extension */
1886 if (S_ISBLK(mode))
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001887 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001888 else if (S_ISCHR(mode))
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001889 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
Eric Van Hensbergen73c592b2005-09-09 13:04:26 -07001890 else if (S_ISFIFO(mode))
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001891 *name = 0;
Venkateswararao Jujjuri75cc5c92010-05-22 12:20:30 -05001892 else if (S_ISSOCK(mode))
1893 *name = 0;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001894 else {
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001895 __putname(name);
1896 return -EINVAL;
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001897 }
1898
Latchesar Ionkov531b1092006-01-08 01:05:00 -08001899 retval = v9fs_vfs_mkspecial(dir, dentry, mode, name);
1900 __putname(name);
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07001901
1902 return retval;
1903}
1904
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301905/**
1906 * v9fs_vfs_mknod_dotl - create a special file
1907 * @dir: inode destination for new link
1908 * @dentry: dentry for file
1909 * @mode: mode for creation
1910 * @rdev: device associated with special file
1911 *
1912 */
1913static int
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +05301914v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301915 dev_t rdev)
1916{
1917 int err;
1918 char *name;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +05301919 mode_t mode;
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301920 struct v9fs_session_info *v9ses;
1921 struct p9_fid *fid = NULL, *dfid = NULL;
1922 struct inode *inode;
1923 gid_t gid;
1924 struct p9_qid qid;
M. Mohan Kumar01a622b2010-06-16 14:27:22 +05301925 struct dentry *dir_dentry;
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +05301926 struct posix_acl *dacl = NULL, *pacl = NULL;
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301927
1928 P9_DPRINTK(P9_DEBUG_VFS,
1929 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +05301930 dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301931
1932 if (!new_valid_dev(rdev))
1933 return -EINVAL;
1934
1935 v9ses = v9fs_inode2v9ses(dir);
1936 dir_dentry = v9fs_dentry_from_dir_inode(dir);
M. Mohan Kumar01a622b2010-06-16 14:27:22 +05301937 dfid = v9fs_fid_lookup(dir_dentry);
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301938 if (IS_ERR(dfid)) {
1939 err = PTR_ERR(dfid);
1940 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
1941 dfid = NULL;
1942 goto error;
1943 }
1944
1945 gid = v9fs_get_fsgid_for_create(dir);
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +05301946 mode = omode;
1947 /* Update mode based on ACL value */
1948 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
1949 if (err) {
1950 P9_DPRINTK(P9_DEBUG_VFS,
1951 "Failed to get acl values in mknod %d\n", err);
1952 goto error;
1953 }
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301954 name = (char *) dentry->d_name.name;
1955
1956 err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
1957 if (err < 0)
1958 goto error;
1959
1960 /* instantiate inode and assign the unopened fid to the dentry */
1961 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
1962 fid = p9_client_walk(dfid, 1, &name, 1);
1963 if (IS_ERR(fid)) {
1964 err = PTR_ERR(fid);
1965 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
1966 err);
1967 fid = NULL;
1968 goto error;
1969 }
1970
1971 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1972 if (IS_ERR(inode)) {
1973 err = PTR_ERR(inode);
1974 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
1975 err);
1976 goto error;
1977 }
1978 dentry->d_op = &v9fs_cached_dentry_operations;
1979 d_instantiate(dentry, inode);
1980 err = v9fs_fid_add(dentry, fid);
1981 if (err < 0)
1982 goto error;
1983 fid = NULL;
1984 } else {
1985 /*
1986 * Not in cached mode. No need to populate inode with stat.
1987 * socket syscall returns a fd, so we need instantiate
1988 */
1989 inode = v9fs_get_inode(dir->i_sb, mode);
1990 if (IS_ERR(inode)) {
1991 err = PTR_ERR(inode);
1992 goto error;
1993 }
1994 dentry->d_op = &v9fs_dentry_operations;
1995 d_instantiate(dentry, inode);
1996 }
Aneesh Kumar K.Vad77dbc2010-09-28 00:27:40 +05301997 /* Now set the ACL based on the default value */
1998 v9fs_set_create_acl(dentry, dacl, pacl);
M. Mohan Kumar4b435162010-06-16 14:27:01 +05301999error:
2000 if (fid)
2001 p9_client_clunk(fid);
2002 return err;
2003}
2004
M. Mohan Kumar329176c2010-09-28 19:59:25 +05302005static int
2006v9fs_vfs_readlink_dotl(struct dentry *dentry, char *buffer, int buflen)
2007{
2008 int retval;
2009 struct p9_fid *fid;
2010 char *target = NULL;
2011
2012 P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
2013 retval = -EPERM;
2014 fid = v9fs_fid_lookup(dentry);
2015 if (IS_ERR(fid))
2016 return PTR_ERR(fid);
2017
2018 retval = p9_client_readlink(fid, &target);
2019 if (retval < 0)
2020 return retval;
2021
2022 strncpy(buffer, target, buflen);
2023 P9_DPRINTK(P9_DEBUG_VFS, "%s -> %s\n", dentry->d_name.name, buffer);
2024
2025 retval = strnlen(buffer, buflen);
2026 return retval;
2027}
2028
2029/**
2030 * v9fs_vfs_follow_link_dotl - follow a symlink path
2031 * @dentry: dentry for symlink
2032 * @nd: nameidata
2033 *
2034 */
2035
2036static void *
2037v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
2038{
2039 int len = 0;
2040 char *link = __getname();
2041
2042 P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name);
2043
2044 if (!link)
2045 link = ERR_PTR(-ENOMEM);
2046 else {
2047 len = v9fs_vfs_readlink_dotl(dentry, link, PATH_MAX);
2048 if (len < 0) {
2049 __putname(link);
2050 link = ERR_PTR(len);
2051 } else
2052 link[min(len, PATH_MAX-1)] = 0;
2053 }
2054 nd_set_link(nd, link);
2055
2056 return NULL;
2057}
2058
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002059static const struct inode_operations v9fs_dir_inode_operations_dotu = {
2060 .create = v9fs_vfs_create,
2061 .lookup = v9fs_vfs_lookup,
2062 .symlink = v9fs_vfs_symlink,
Venkateswararao Jujjuri (JV)50cc42f2010-06-09 15:59:31 -07002063 .link = v9fs_vfs_link,
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002064 .unlink = v9fs_vfs_unlink,
2065 .mkdir = v9fs_vfs_mkdir,
2066 .rmdir = v9fs_vfs_rmdir,
Aneesh Kumar K.V1d76e312010-08-30 17:43:07 +00002067 .mknod = v9fs_vfs_mknod,
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002068 .rename = v9fs_vfs_rename,
2069 .getattr = v9fs_vfs_getattr,
2070 .setattr = v9fs_vfs_setattr,
2071};
2072
2073static const struct inode_operations v9fs_dir_inode_operations_dotl = {
Venkateswararao Jujjuri (JV)56431352010-06-17 18:27:46 -07002074 .create = v9fs_vfs_create_dotl,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002075 .lookup = v9fs_vfs_lookup,
Venkateswararao Jujjuri (JV)50cc42f2010-06-09 15:59:31 -07002076 .link = v9fs_vfs_link_dotl,
2077 .symlink = v9fs_vfs_symlink_dotl,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002078 .unlink = v9fs_vfs_unlink,
M. Mohan Kumar01a622b2010-06-16 14:27:22 +05302079 .mkdir = v9fs_vfs_mkdir_dotl,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002080 .rmdir = v9fs_vfs_rmdir,
M. Mohan Kumar4b435162010-06-16 14:27:01 +05302081 .mknod = v9fs_vfs_mknod_dotl,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002082 .rename = v9fs_vfs_rename,
Sripathi Kodif0853122010-07-12 20:07:23 +05302083 .getattr = v9fs_vfs_getattr_dotl,
Sripathi Kodi87d78452010-06-18 11:50:10 +05302084 .setattr = v9fs_vfs_setattr_dotl,
Aneesh Kumar K.Vebf46262010-05-31 13:22:56 +05302085 .setxattr = generic_setxattr,
2086 .getxattr = generic_getxattr,
2087 .removexattr = generic_removexattr,
2088 .listxattr = v9fs_listxattr,
Aneesh Kumar K.V85ff8722010-09-28 00:27:39 +05302089 .check_acl = v9fs_check_acl,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002090};
2091
Arjan van de Ven754661f2007-02-12 00:55:38 -08002092static const struct inode_operations v9fs_dir_inode_operations = {
Eric Van Hensbergenb5016112005-09-09 13:04:27 -07002093 .create = v9fs_vfs_create,
2094 .lookup = v9fs_vfs_lookup,
2095 .unlink = v9fs_vfs_unlink,
2096 .mkdir = v9fs_vfs_mkdir,
2097 .rmdir = v9fs_vfs_rmdir,
2098 .mknod = v9fs_vfs_mknod,
2099 .rename = v9fs_vfs_rename,
2100 .getattr = v9fs_vfs_getattr,
2101 .setattr = v9fs_vfs_setattr,
2102};
2103
Arjan van de Ven754661f2007-02-12 00:55:38 -08002104static const struct inode_operations v9fs_file_inode_operations = {
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002105 .getattr = v9fs_vfs_getattr,
2106 .setattr = v9fs_vfs_setattr,
2107};
2108
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002109static const struct inode_operations v9fs_file_inode_operations_dotl = {
Sripathi Kodif0853122010-07-12 20:07:23 +05302110 .getattr = v9fs_vfs_getattr_dotl,
Sripathi Kodi87d78452010-06-18 11:50:10 +05302111 .setattr = v9fs_vfs_setattr_dotl,
Aneesh Kumar K.Vebf46262010-05-31 13:22:56 +05302112 .setxattr = generic_setxattr,
2113 .getxattr = generic_getxattr,
2114 .removexattr = generic_removexattr,
2115 .listxattr = v9fs_listxattr,
Aneesh Kumar K.V85ff8722010-09-28 00:27:39 +05302116 .check_acl = v9fs_check_acl,
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002117};
2118
Arjan van de Ven754661f2007-02-12 00:55:38 -08002119static const struct inode_operations v9fs_symlink_inode_operations = {
Al Viro204f2f02009-12-23 00:35:54 -05002120 .readlink = generic_readlink,
Eric Van Hensbergen2bad8472005-09-09 13:04:19 -07002121 .follow_link = v9fs_vfs_follow_link,
2122 .put_link = v9fs_vfs_put_link,
2123 .getattr = v9fs_vfs_getattr,
2124 .setattr = v9fs_vfs_setattr,
2125};
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002126
2127static const struct inode_operations v9fs_symlink_inode_operations_dotl = {
M. Mohan Kumar329176c2010-09-28 19:59:25 +05302128 .readlink = v9fs_vfs_readlink_dotl,
2129 .follow_link = v9fs_vfs_follow_link_dotl,
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002130 .put_link = v9fs_vfs_put_link,
Sripathi Kodif0853122010-07-12 20:07:23 +05302131 .getattr = v9fs_vfs_getattr_dotl,
Sripathi Kodi87d78452010-06-18 11:50:10 +05302132 .setattr = v9fs_vfs_setattr_dotl,
Aneesh Kumar K.Vebf46262010-05-31 13:22:56 +05302133 .setxattr = generic_setxattr,
2134 .getxattr = generic_getxattr,
2135 .removexattr = generic_removexattr,
2136 .listxattr = v9fs_listxattr,
Sripathi Kodi9b6533c2010-03-25 12:41:54 +00002137};