1 /*
2  * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31  */
32 
33 #include "xfs.h"
34 #include "xfs_fs.h"
35 #include "xfs_inum.h"
36 #include "xfs_log.h"
37 #include "xfs_trans.h"
38 #include "xfs_sb.h"
39 #include "xfs_ag.h"
40 #include "xfs_dir.h"
41 #include "xfs_dir2.h"
42 #include "xfs_alloc.h"
43 #include "xfs_dmapi.h"
44 #include "xfs_quota.h"
45 #include "xfs_mount.h"
46 #include "xfs_alloc_btree.h"
47 #include "xfs_bmap_btree.h"
48 #include "xfs_ialloc_btree.h"
49 #include "xfs_btree.h"
50 #include "xfs_ialloc.h"
51 #include "xfs_attr_sf.h"
52 #include "xfs_dir_sf.h"
53 #include "xfs_dir2_sf.h"
54 #include "xfs_dinode.h"
55 #include "xfs_inode.h"
56 #include "xfs_bmap.h"
57 #include "xfs_bit.h"
58 #include "xfs_rtalloc.h"
59 #include "xfs_error.h"
60 #include "xfs_itable.h"
61 #include "xfs_rw.h"
62 #include "xfs_acl.h"
63 #include "xfs_cap.h"
64 #include "xfs_mac.h"
65 #include "xfs_attr.h"
66 #include "xfs_buf_item.h"
67 #include "xfs_utils.h"
68 
69 #include <linux/xattr.h>
70 
71 
72 /*
73  * Pull the link count and size up from the xfs inode to the linux inode
74  */
75 STATIC void
validate_fields(struct inode * ip)76 validate_fields(
77 	struct inode	*ip)
78 {
79 	vnode_t		*vp = LINVFS_GET_VP(ip);
80 	vattr_t		va;
81 	int		error;
82 
83 	va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
84 	VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error);
85 	if (likely(!error)) {
86 		ip->i_nlink = va.va_nlink;
87 		ip->i_blocks = va.va_nblocks;
88 
89 		/* we're under i_sem so i_size can't change under us */
90 		if (i_size_read(ip) != va.va_size)
91 			i_size_write(ip, va.va_size);
92 	}
93 }
94 
95 #ifdef CONFIG_XFS_POSIX_ACL
96 /*
97  * Determine whether a process has a valid fs_struct (kernel daemons
98  * like knfsd don't have an fs_struct).
99  */
100 STATIC int inline
has_fs_struct(struct task_struct * task)101 has_fs_struct(struct task_struct *task)
102 {
103 	return (task->fs != init_task.fs);
104 }
105 #endif
106 
107 STATIC int
linvfs_mknod(struct inode * dir,struct dentry * dentry,int mode,int rdev)108 linvfs_mknod(
109 	struct inode	*dir,
110 	struct dentry	*dentry,
111 	int		mode,
112 	int		rdev)
113 {
114 	struct inode	*ip;
115 	vattr_t		va;
116 	vnode_t		*vp = NULL, *dvp = LINVFS_GET_VP(dir);
117 	xfs_acl_t	*default_acl = NULL;
118 	attrexists_t	test_default_acl = _ACL_DEFAULT_EXISTS;
119 	int		error;
120 
121 	if (test_default_acl && test_default_acl(dvp)) {
122 		if (!_ACL_ALLOC(default_acl))
123 			return -ENOMEM;
124 		if (!_ACL_GET_DEFAULT(dvp, default_acl)) {
125 			_ACL_FREE(default_acl);
126 			default_acl = NULL;
127 		}
128 	}
129 
130 #ifdef CONFIG_XFS_POSIX_ACL
131 	/*
132 	 * Conditionally compiled so that the ACL base kernel changes can be
133 	 * split out into separate patches - remove this once MS_POSIXACL is
134 	 * accepted, or some other way to implement this exists.
135 	 */
136 	if (IS_POSIXACL(dir) && !default_acl && has_fs_struct(current))
137 		mode &= ~current->fs->umask;
138 #endif
139 
140 	memset(&va, 0, sizeof(va));
141 	va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
142 	va.va_type = IFTOVT(mode);
143 	va.va_mode = mode;
144 
145 	switch (mode & S_IFMT) {
146 	case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
147 		va.va_rdev = XFS_MKDEV(MAJOR(rdev), MINOR(rdev));
148 		va.va_mask |= XFS_AT_RDEV;
149 		/*FALLTHROUGH*/
150 	case S_IFREG:
151 		VOP_CREATE(dvp, dentry, &va, &vp, NULL, error);
152 		break;
153 	case S_IFDIR:
154 		VOP_MKDIR(dvp, dentry, &va, &vp, NULL, error);
155 		break;
156 	default:
157 		error = EINVAL;
158 		break;
159 	}
160 
161 	if (default_acl) {
162 		if (!error) {
163 			error = _ACL_INHERIT(vp, &va, default_acl);
164 			if (!error) {
165 				VMODIFY(vp);
166 			} else {
167 				struct dentry	teardown = {};
168 				int		err2;
169 
170 				/* Oh, the horror.
171 				 * If we can't add the ACL we must back out.
172 				 * ENOSPC can hit here, among other things.
173 				 */
174 				teardown.d_inode = ip = LINVFS_GET_IP(vp);
175 				teardown.d_name = dentry->d_name;
176 
177 				vn_mark_bad(vp);
178 
179 				if (S_ISDIR(mode))
180 					VOP_RMDIR(dvp, &teardown, NULL, err2);
181 				else
182 					VOP_REMOVE(dvp, &teardown, NULL, err2);
183 				VN_RELE(vp);
184 			}
185 		}
186 		_ACL_FREE(default_acl);
187 	}
188 
189 	if (!error) {
190 		ASSERT(vp);
191 		ip = LINVFS_GET_IP(vp);
192 
193 		if (S_ISCHR(mode) || S_ISBLK(mode))
194 			ip->i_rdev = to_kdev_t(rdev);
195 		else if (S_ISDIR(mode))
196 			validate_fields(ip);
197 		d_instantiate(dentry, ip);
198 		validate_fields(dir);
199 	}
200 	return -error;
201 }
202 
203 STATIC int
linvfs_create(struct inode * dir,struct dentry * dentry,int mode)204 linvfs_create(
205 	struct inode	*dir,
206 	struct dentry	*dentry,
207 	int		mode)
208 {
209 	return linvfs_mknod(dir, dentry, mode, 0);
210 }
211 
212 STATIC int
linvfs_mkdir(struct inode * dir,struct dentry * dentry,int mode)213 linvfs_mkdir(
214 	struct inode	*dir,
215 	struct dentry	*dentry,
216 	int		mode)
217 {
218 	return linvfs_mknod(dir, dentry, mode|S_IFDIR, 0);
219 }
220 
221 STATIC struct dentry *
linvfs_lookup(struct inode * dir,struct dentry * dentry)222 linvfs_lookup(
223 	struct inode	*dir,
224 	struct dentry	*dentry)
225 {
226 	struct inode	*ip = NULL;
227 	vnode_t		*vp, *cvp = NULL;
228 	int		error;
229 
230 	if (dentry->d_name.len >= MAXNAMELEN)
231 		return ERR_PTR(-ENAMETOOLONG);
232 
233 	vp = LINVFS_GET_VP(dir);
234 	VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
235 	if (!error) {
236 		ASSERT(cvp);
237 		ip = LINVFS_GET_IP(cvp);
238 		if (!ip) {
239 			VN_RELE(cvp);
240 			return ERR_PTR(-EACCES);
241 		}
242 	}
243 	if (error && (error != ENOENT))
244 		return ERR_PTR(-error);
245 	d_add(dentry, ip);	/* Negative entry goes in if ip is NULL */
246 	return NULL;
247 }
248 
249 STATIC int
linvfs_link(struct dentry * old_dentry,struct inode * dir,struct dentry * dentry)250 linvfs_link(
251 	struct dentry	*old_dentry,
252 	struct inode	*dir,
253 	struct dentry	*dentry)
254 {
255 	struct inode	*ip;	/* inode of guy being linked to */
256 	vnode_t		*tdvp;	/* target directory for new name/link */
257 	vnode_t		*vp;	/* vp of name being linked */
258 	int		error;
259 
260 	ip = old_dentry->d_inode;	/* inode being linked to */
261 	if (S_ISDIR(ip->i_mode))
262 		return -EPERM;
263 
264 	tdvp = LINVFS_GET_VP(dir);
265 	vp = LINVFS_GET_VP(ip);
266 
267 	VOP_LINK(tdvp, vp, dentry, NULL, error);
268 	if (!error) {
269 		VMODIFY(tdvp);
270 		VN_HOLD(vp);
271 		validate_fields(ip);
272 		d_instantiate(dentry, ip);
273 	}
274 	return -error;
275 }
276 
277 STATIC int
linvfs_unlink(struct inode * dir,struct dentry * dentry)278 linvfs_unlink(
279 	struct inode	*dir,
280 	struct dentry	*dentry)
281 {
282 	struct inode	*inode;
283 	vnode_t		*dvp;	/* directory containing name to remove */
284 	int		error;
285 
286 	inode = dentry->d_inode;
287 	dvp = LINVFS_GET_VP(dir);
288 
289 	VOP_REMOVE(dvp, dentry, NULL, error);
290 	if (!error) {
291 		validate_fields(dir);	/* For size only */
292 		validate_fields(inode);
293 	}
294 
295 	return -error;
296 }
297 
298 STATIC int
linvfs_symlink(struct inode * dir,struct dentry * dentry,const char * symname)299 linvfs_symlink(
300 	struct inode	*dir,
301 	struct dentry	*dentry,
302 	const char	*symname)
303 {
304 	struct inode	*ip;
305 	vattr_t		va;
306 	vnode_t		*dvp;	/* directory containing name of symlink */
307 	vnode_t		*cvp;	/* used to lookup symlink to put in dentry */
308 	int		error;
309 
310 	dvp = LINVFS_GET_VP(dir);
311 	cvp = NULL;
312 
313 	memset(&va, 0, sizeof(va));
314 	va.va_type = VLNK;
315 	va.va_mode = irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO;
316 	va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
317 
318 	error = 0;
319 	VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error);
320 	if (!error && cvp) {
321 		ASSERT(cvp->v_type == VLNK);
322 		ip = LINVFS_GET_IP(cvp);
323 		d_instantiate(dentry, ip);
324 		validate_fields(dir);
325 		validate_fields(ip); /* size needs update */
326 	}
327 	return -error;
328 }
329 
330 STATIC int
linvfs_rmdir(struct inode * dir,struct dentry * dentry)331 linvfs_rmdir(
332 	struct inode	*dir,
333 	struct dentry	*dentry)
334 {
335 	struct inode	*inode = dentry->d_inode;
336 	vnode_t		*dvp = LINVFS_GET_VP(dir);
337 	int		error;
338 
339 	VOP_RMDIR(dvp, dentry, NULL, error);
340 	if (!error) {
341 		validate_fields(inode);
342 		validate_fields(dir);
343 	}
344 	return -error;
345 }
346 
347 STATIC int
linvfs_rename(struct inode * odir,struct dentry * odentry,struct inode * ndir,struct dentry * ndentry)348 linvfs_rename(
349 	struct inode	*odir,
350 	struct dentry	*odentry,
351 	struct inode	*ndir,
352 	struct dentry	*ndentry)
353 {
354 	struct inode	*new_inode = ndentry->d_inode;
355 	vnode_t		*fvp;	/* from directory */
356 	vnode_t		*tvp;	/* target directory */
357 	int		error;
358 
359 	fvp = LINVFS_GET_VP(odir);
360 	tvp = LINVFS_GET_VP(ndir);
361 
362 	VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
363 	if (error)
364 		return -error;
365 
366 	if (new_inode)
367 		validate_fields(new_inode);
368 
369 	validate_fields(odir);
370 	if (ndir != odir)
371 		validate_fields(ndir);
372 	return 0;
373 }
374 
375 STATIC int
linvfs_readlink(struct dentry * dentry,char * buf,int size)376 linvfs_readlink(
377 	struct dentry	*dentry,
378 	char		*buf,
379 	int		size)
380 {
381 	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
382 	uio_t		uio;
383 	iovec_t		iov;
384 	int		error;
385 
386 	iov.iov_base = buf;
387 	iov.iov_len = size;
388 
389 	uio.uio_iov = &iov;
390 	uio.uio_offset = 0;
391 	uio.uio_segflg = UIO_USERSPACE;
392 	uio.uio_resid = size;
393 	uio.uio_iovcnt = 1;
394 
395 	VOP_READLINK(vp, &uio, 0, NULL, error);
396 	if (error)
397 		return -error;
398 
399 	return (size - uio.uio_resid);
400 }
401 
402 /*
403  * careful here - this function can get called recursively, so
404  * we need to be very careful about how much stack we use.
405  * uio is kmalloced for this reason...
406  */
407 STATIC int
linvfs_follow_link(struct dentry * dentry,struct nameidata * nd)408 linvfs_follow_link(
409 	struct dentry		*dentry,
410 	struct nameidata	*nd)
411 {
412 	vnode_t			*vp;
413 	uio_t			*uio;
414 	iovec_t			iov;
415 	int			error;
416 	char			*link;
417 
418 	ASSERT(dentry);
419 	ASSERT(nd);
420 
421 	link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
422 	if (!link)
423 		return -ENOMEM;
424 
425 	uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL);
426 	if (!uio) {
427 		kfree(link);
428 		return -ENOMEM;
429 	}
430 
431 	vp = LINVFS_GET_VP(dentry->d_inode);
432 
433 	iov.iov_base = link;
434 	iov.iov_len = MAXNAMELEN;
435 
436 	uio->uio_iov = &iov;
437 	uio->uio_offset = 0;
438 	uio->uio_segflg = UIO_SYSSPACE;
439 	uio->uio_resid = MAXNAMELEN;
440 	uio->uio_iovcnt = 1;
441 
442 	VOP_READLINK(vp, uio, 0, NULL, error);
443 	if (error) {
444 		kfree(uio);
445 		kfree(link);
446 		return -error;
447 	}
448 
449 	link[MAXNAMELEN - uio->uio_resid] = '\0';
450 	kfree(uio);
451 
452 	/* vfs_follow_link returns (-) errors */
453 	error = vfs_follow_link(nd, link);
454 	kfree(link);
455 	return error;
456 }
457 
458 STATIC int
linvfs_permission(struct inode * inode,int mode)459 linvfs_permission(
460 	struct inode	*inode,
461 	int		mode)
462 {
463 	vnode_t		*vp = LINVFS_GET_VP(inode);
464 	int		error;
465 
466 	mode <<= 6;		/* convert from linux to vnode access bits */
467 	VOP_ACCESS(vp, mode, NULL, error);
468 	return -error;
469 }
470 
471 STATIC int
linvfs_revalidate(struct dentry * dentry)472 linvfs_revalidate(
473 	struct dentry	*dentry)
474 {
475 	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
476 
477 	if (unlikely(vp->v_flag & VMODIFIED))
478 		return vn_revalidate(vp);
479 	return 0;
480 }
481 
482 STATIC int
linvfs_setattr(struct dentry * dentry,struct iattr * attr)483 linvfs_setattr(
484 	struct dentry	*dentry,
485 	struct iattr	*attr)
486 {
487 	struct inode	*inode = dentry->d_inode;
488 	unsigned int	ia_valid = attr->ia_valid;
489 	vnode_t		*vp = LINVFS_GET_VP(inode);
490 	vattr_t		vattr;
491 	int		flags = 0;
492 	int		error;
493 
494 	memset(&vattr, 0, sizeof(vattr_t));
495 	if (ia_valid & ATTR_UID) {
496 		vattr.va_mask |= XFS_AT_UID;
497 		vattr.va_uid = attr->ia_uid;
498 	}
499 	if (ia_valid & ATTR_GID) {
500 		vattr.va_mask |= XFS_AT_GID;
501 		vattr.va_gid = attr->ia_gid;
502 	}
503 	if (ia_valid & ATTR_SIZE) {
504 		vattr.va_mask |= XFS_AT_SIZE;
505 		vattr.va_size = attr->ia_size;
506 	}
507 	if (ia_valid & ATTR_ATIME) {
508 		vattr.va_mask |= XFS_AT_ATIME;
509 		vattr.va_atime.tv_sec = attr->ia_atime;
510 		vattr.va_atime.tv_nsec = 0;
511 	}
512 	if (ia_valid & ATTR_MTIME) {
513 		vattr.va_mask |= XFS_AT_MTIME;
514 		vattr.va_mtime.tv_sec = attr->ia_mtime;
515 		vattr.va_mtime.tv_nsec = 0;
516 	}
517 	if (ia_valid & ATTR_CTIME) {
518 		vattr.va_mask |= XFS_AT_CTIME;
519 		vattr.va_ctime.tv_sec = attr->ia_ctime;
520 		vattr.va_ctime.tv_nsec = 0;
521 	}
522 	if (ia_valid & ATTR_MODE) {
523 		vattr.va_mask |= XFS_AT_MODE;
524 		vattr.va_mode = attr->ia_mode;
525 		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
526 			inode->i_mode &= ~S_ISGID;
527 	}
528 
529 	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))
530 		flags |= ATTR_UTIME;
531 
532 	VOP_SETATTR(vp, &vattr, flags, NULL, error);
533 	if (error)
534 		return -error;
535 	vn_revalidate(vp);
536 	return error;
537 }
538 
539 STATIC void
linvfs_truncate(struct inode * inode)540 linvfs_truncate(
541 	struct inode	*inode)
542 {
543 	block_truncate_page(inode->i_mapping, inode->i_size, linvfs_get_block);
544 }
545 
546 STATIC int
linvfs_setxattr(struct dentry * dentry,const char * name,void * data,size_t size,int flags)547 linvfs_setxattr(
548 	struct dentry	*dentry,
549 	const char	*name,
550 	void		*data,
551 	size_t		size,
552 	int		flags)
553 {
554 	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
555 	char		*attr = (char *)name;
556 	attrnames_t	*namesp;
557 	int		xflags = 0;
558 	int		error;
559 
560 	namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
561 	if (!namesp)
562 		return -EOPNOTSUPP;
563 	attr += namesp->attr_namelen;
564 	error = namesp->attr_capable(vp, NULL);
565 	if (error)
566 		return error;
567 
568 	/* Convert Linux syscall to XFS internal ATTR flags */
569 	if (flags & XATTR_CREATE)
570 		xflags |= ATTR_CREATE;
571 	if (flags & XATTR_REPLACE)
572 		xflags |= ATTR_REPLACE;
573 	xflags |= namesp->attr_flag;
574 	return namesp->attr_set(vp, attr, (void *)data, size, xflags);
575 }
576 
577 STATIC ssize_t
linvfs_getxattr(struct dentry * dentry,const char * name,void * data,size_t size)578 linvfs_getxattr(
579 	struct dentry	*dentry,
580 	const char	*name,
581 	void		*data,
582 	size_t		size)
583 {
584 	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
585 	char		*attr = (char *)name;
586 	attrnames_t	*namesp;
587 	int		xflags = 0;
588 	ssize_t		error;
589 
590 	namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
591 	if (!namesp)
592 		return -EOPNOTSUPP;
593 	attr += namesp->attr_namelen;
594 	error = namesp->attr_capable(vp, NULL);
595 	if (error)
596 		return error;
597 
598 	/* Convert Linux syscall to XFS internal ATTR flags */
599 	if (!size) {
600 		xflags |= ATTR_KERNOVAL;
601 		data = NULL;
602 	}
603 	xflags |= namesp->attr_flag;
604 	return namesp->attr_get(vp, attr, (void *)data, size, xflags);
605 }
606 
607 STATIC ssize_t
linvfs_listxattr(struct dentry * dentry,char * data,size_t size)608 linvfs_listxattr(
609 	struct dentry		*dentry,
610 	char			*data,
611 	size_t			size)
612 {
613 	vnode_t			*vp = LINVFS_GET_VP(dentry->d_inode);
614 	int			error, xflags = ATTR_KERNAMELS;
615 	ssize_t			result;
616 
617 	if (!size)
618 		xflags |= ATTR_KERNOVAL;
619 	xflags |= capable(CAP_SYS_ADMIN) ? ATTR_KERNFULLS : ATTR_KERNORMALS;
620 
621 	error = attr_generic_list(vp, data, size, xflags, &result);
622 	if (error < 0)
623 		return error;
624 	return result;
625 }
626 
627 STATIC int
linvfs_removexattr(struct dentry * dentry,const char * name)628 linvfs_removexattr(
629 	struct dentry	*dentry,
630 	const char	*name)
631 {
632 	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
633 	char		*attr = (char *)name;
634 	attrnames_t	*namesp;
635 	int		xflags = 0;
636 	int		error;
637 
638 	namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
639 	if (!namesp)
640 		return -EOPNOTSUPP;
641 	attr += namesp->attr_namelen;
642 	error = namesp->attr_capable(vp, NULL);
643 	if (error)
644 		return error;
645 	xflags |= namesp->attr_flag;
646 	return namesp->attr_remove(vp, attr, xflags);
647 }
648 
649 
650 struct inode_operations linvfs_file_inode_operations = {
651 	.permission		= linvfs_permission,
652 	.truncate		= linvfs_truncate,
653 	.revalidate		= linvfs_revalidate,
654 	.setattr		= linvfs_setattr,
655 	.setxattr		= linvfs_setxattr,
656 	.getxattr		= linvfs_getxattr,
657 	.listxattr		= linvfs_listxattr,
658 	.removexattr		= linvfs_removexattr,
659 };
660 
661 struct inode_operations linvfs_dir_inode_operations = {
662 	.create			= linvfs_create,
663 	.lookup			= linvfs_lookup,
664 	.link			= linvfs_link,
665 	.unlink			= linvfs_unlink,
666 	.symlink		= linvfs_symlink,
667 	.mkdir			= linvfs_mkdir,
668 	.rmdir			= linvfs_rmdir,
669 	.mknod			= linvfs_mknod,
670 	.rename			= linvfs_rename,
671 	.permission		= linvfs_permission,
672 	.revalidate		= linvfs_revalidate,
673 	.setattr		= linvfs_setattr,
674 	.setxattr		= linvfs_setxattr,
675 	.getxattr		= linvfs_getxattr,
676 	.listxattr		= linvfs_listxattr,
677 	.removexattr		= linvfs_removexattr,
678 };
679 
680 struct inode_operations linvfs_symlink_inode_operations = {
681 	.readlink		= linvfs_readlink,
682 	.follow_link		= linvfs_follow_link,
683 	.permission		= linvfs_permission,
684 	.revalidate		= linvfs_revalidate,
685 	.setattr		= linvfs_setattr,
686 	.setxattr		= linvfs_setxattr,
687 	.getxattr		= linvfs_getxattr,
688 	.listxattr		= linvfs_listxattr,
689 	.removexattr		= linvfs_removexattr,
690 };
691