2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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.
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.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
34 #include <linux/xattr.h>
38 * Pull the link count and size up from the xfs inode to the linux inode
44 vnode_t
*vp
= LINVFS_GET_VP(ip
);
48 va
.va_mask
= AT_NLINK
|AT_SIZE
;
49 VOP_GETATTR(vp
, &va
, ATTR_LAZY
, NULL
, error
);
50 ip
->i_nlink
= va
.va_nlink
;
51 ip
->i_size
= va
.va_size
;
52 ip
->i_blocks
= va
.va_nblocks
;
56 * Determine whether a process has a valid fs_struct (kernel daemons
57 * like knfsd don't have an fs_struct).
59 * XXX(hch): nfsd is broken, better fix it instead.
62 has_fs_struct(struct task_struct
*task
)
64 return (task
->fs
!= init_task
.fs
);
70 struct dentry
*dentry
,
76 vnode_t
*vp
= NULL
, *dvp
= LINVFS_GET_VP(dir
);
77 xattr_exists_t test_default_acl
= _ACL_DEFAULT_EXISTS
;
78 int have_default_acl
= 0;
82 have_default_acl
= test_default_acl(dvp
);
84 if (IS_POSIXACL(dir
) && !have_default_acl
&& has_fs_struct(current
))
85 mode
&= ~current
->fs
->umask
;
87 memset(&va
, 0, sizeof(va
));
88 va
.va_mask
= AT_TYPE
|AT_MODE
;
89 va
.va_type
= IFTOVT(mode
);
92 switch (mode
& S_IFMT
) {
93 case S_IFCHR
: case S_IFBLK
: case S_IFIFO
: case S_IFSOCK
:
94 va
.va_rdev
= XFS_MKDEV(MAJOR(rdev
), MINOR(rdev
));
95 va
.va_mask
|= AT_RDEV
;
98 VOP_CREATE(dvp
, dentry
, &va
, &vp
, NULL
, error
);
101 VOP_MKDIR(dvp
, dentry
, &va
, &vp
, NULL
, error
);
110 ip
= LINVFS_GET_IP(vp
);
116 if (S_ISCHR(mode
) || S_ISBLK(mode
))
117 ip
->i_rdev
= to_kdev_t(rdev
);
118 validate_fields(dir
);
119 d_instantiate(dentry
, ip
);
120 mark_inode_dirty_sync(ip
);
121 mark_inode_dirty_sync(dir
);
124 if (!error
&& have_default_acl
) {
127 if (!_ACL_ALLOC(pdacl
)) {
130 if (_ACL_GET_DEFAULT(dvp
, pdacl
))
131 error
= _ACL_INHERIT(vp
, &va
, pdacl
);
142 struct dentry
*dentry
,
145 return linvfs_mknod(dir
, dentry
, mode
, 0);
151 struct dentry
*dentry
,
154 return linvfs_mknod(dir
, dentry
, mode
|S_IFDIR
, 0);
158 STATIC
struct dentry
*
161 struct dentry
*dentry
)
165 struct inode
*ip
= NULL
;
167 if (dentry
->d_name
.len
>= MAXNAMELEN
)
168 return ERR_PTR(-ENAMETOOLONG
);
171 vp
= LINVFS_GET_VP(dir
);
172 VOP_LOOKUP(vp
, dentry
, &cvp
, 0, NULL
, NULL
, error
);
175 ip
= LINVFS_GET_IP(cvp
);
178 return ERR_PTR(-EACCES
);
181 if (error
&& (error
!= ENOENT
))
182 return ERR_PTR(-error
);
183 return d_splice_alias(ip
, dentry
);
188 struct dentry
*old_dentry
,
190 struct dentry
*dentry
)
193 vnode_t
*tdvp
; /* Target directory for new name/link */
194 vnode_t
*vp
; /* vp of name being linked */
195 struct inode
*ip
; /* inode of guy being linked to */
197 ip
= old_dentry
->d_inode
; /* inode being linked to */
198 if (S_ISDIR(ip
->i_mode
))
201 tdvp
= LINVFS_GET_VP(dir
);
202 vp
= LINVFS_GET_VP(ip
);
205 VOP_LINK(tdvp
, vp
, dentry
, NULL
, error
);
210 d_instantiate(dentry
, ip
);
211 mark_inode_dirty_sync(ip
);
219 struct dentry
*dentry
)
223 vnode_t
*dvp
; /* directory containing name to remove */
225 inode
= dentry
->d_inode
;
227 dvp
= LINVFS_GET_VP(dir
);
229 VOP_REMOVE(dvp
, dentry
, NULL
, error
);
232 validate_fields(dir
); /* For size only */
233 validate_fields(inode
);
234 mark_inode_dirty_sync(inode
);
235 mark_inode_dirty_sync(dir
);
244 struct dentry
*dentry
,
248 vnode_t
*dvp
; /* directory containing name to remove */
249 vnode_t
*cvp
; /* used to lookup symlink to put in dentry */
251 struct inode
*ip
= NULL
;
253 dvp
= LINVFS_GET_VP(dir
);
255 memset(&va
, 0, sizeof(va
));
257 va
.va_mode
= irix_symlink_mode
? 0777 & ~current
->fs
->umask
: S_IRWXUGO
;
258 va
.va_mask
= AT_TYPE
|AT_MODE
;
261 VOP_SYMLINK(dvp
, dentry
, &va
, (char *)symname
, &cvp
, NULL
, error
);
264 ASSERT(cvp
->v_type
== VLNK
);
265 ip
= LINVFS_GET_IP(cvp
);
270 d_instantiate(dentry
, ip
);
271 validate_fields(dir
);
272 validate_fields(ip
); /* size needs update */
273 mark_inode_dirty_sync(ip
);
274 mark_inode_dirty_sync(dir
);
283 struct dentry
*dentry
)
285 struct inode
*inode
= dentry
->d_inode
;
286 vnode_t
*dvp
= LINVFS_GET_VP(dir
);
289 VOP_RMDIR(dvp
, dentry
, NULL
, error
);
291 validate_fields(inode
);
292 validate_fields(dir
);
293 mark_inode_dirty_sync(inode
);
294 mark_inode_dirty_sync(dir
);
302 struct dentry
*odentry
,
304 struct dentry
*ndentry
)
307 vnode_t
*fvp
; /* from directory */
308 vnode_t
*tvp
; /* target directory */
309 struct inode
*new_inode
= NULL
;
311 fvp
= LINVFS_GET_VP(odir
);
312 tvp
= LINVFS_GET_VP(ndir
);
314 new_inode
= ndentry
->d_inode
;
316 VOP_RENAME(fvp
, odentry
, tvp
, ndentry
, NULL
, error
);
321 validate_fields(new_inode
);
324 validate_fields(odir
);
326 validate_fields(ndir
);
327 mark_inode_dirty(ndir
);
333 struct dentry
*dentry
,
342 vp
= LINVFS_GET_VP(dentry
->d_inode
);
349 uio
.uio_segflg
= UIO_USERSPACE
;
350 uio
.uio_resid
= size
;
352 VOP_READLINK(vp
, &uio
, NULL
, error
);
356 return (size
- uio
.uio_resid
);
360 * careful here - this function can get called recursively, so
361 * we need to be very careful about how much stack we use.
362 * uio is kmalloced for this reason...
366 struct dentry
*dentry
,
367 struct nameidata
*nd
)
378 link
= (char *)kmalloc(MAXNAMELEN
+1, GFP_KERNEL
);
382 uio
= (uio_t
*)kmalloc(sizeof(uio_t
), GFP_KERNEL
);
388 vp
= LINVFS_GET_VP(dentry
->d_inode
);
391 iov
.iov_len
= MAXNAMELEN
;
395 uio
->uio_segflg
= UIO_SYSSPACE
;
396 uio
->uio_resid
= MAXNAMELEN
;
399 VOP_READLINK(vp
, uio
, NULL
, error
);
406 link
[MAXNAMELEN
- uio
->uio_resid
] = '\0';
409 /* vfs_follow_link returns (-) errors */
410 error
= vfs_follow_link(nd
, link
);
420 vnode_t
*vp
= LINVFS_GET_VP(inode
);
423 mode
<<= 6; /* convert from linux to vnode access bits */
424 VOP_ACCESS(vp
, mode
, NULL
, error
);
428 /* Brute force approach for now - copy data into linux inode
429 * from the results of a getattr. This gets called out of things
435 struct vfsmount
*mnt
,
436 struct dentry
*dentry
,
439 struct inode
*inode
= dentry
->d_inode
;
440 vnode_t
*vp
= LINVFS_GET_VP(inode
);
443 if (unlikely(vp
->v_flag
& VMODIFIED
)) {
444 error
= vn_revalidate(vp
);
447 generic_fillattr(inode
, stat
);
453 struct dentry
*dentry
,
456 struct inode
*inode
= dentry
->d_inode
;
457 vnode_t
*vp
= LINVFS_GET_VP(inode
);
459 unsigned int ia_valid
= attr
->ia_valid
;
463 memset(&vattr
, 0, sizeof(vattr_t
));
464 if (ia_valid
& ATTR_UID
) {
465 vattr
.va_mask
|= AT_UID
;
466 vattr
.va_uid
= attr
->ia_uid
;
468 if (ia_valid
& ATTR_GID
) {
469 vattr
.va_mask
|= AT_GID
;
470 vattr
.va_gid
= attr
->ia_gid
;
472 if (ia_valid
& ATTR_SIZE
) {
473 vattr
.va_mask
|= AT_SIZE
;
474 vattr
.va_size
= attr
->ia_size
;
476 if (ia_valid
& ATTR_ATIME
) {
477 vattr
.va_mask
|= AT_ATIME
;
478 vattr
.va_atime
= attr
->ia_atime
;
480 if (ia_valid
& ATTR_MTIME
) {
481 vattr
.va_mask
|= AT_MTIME
;
482 vattr
.va_mtime
= attr
->ia_mtime
;
484 if (ia_valid
& ATTR_CTIME
) {
485 vattr
.va_mask
|= AT_CTIME
;
486 vattr
.va_ctime
= attr
->ia_ctime
;
488 if (ia_valid
& ATTR_MODE
) {
489 vattr
.va_mask
|= AT_MODE
;
490 vattr
.va_mode
= attr
->ia_mode
;
491 if (!in_group_p(inode
->i_gid
) && !capable(CAP_FSETID
))
492 inode
->i_mode
&= ~S_ISGID
;
495 if (ia_valid
& (ATTR_MTIME_SET
| ATTR_ATIME_SET
))
498 VOP_SETATTR(vp
, &vattr
, flags
, NULL
, error
);
500 return(-error
); /* Positive error up from XFS */
501 if (ia_valid
& ATTR_SIZE
) {
502 error
= vmtruncate(inode
, attr
->ia_size
);
507 mark_inode_dirty_sync(inode
);
516 block_truncate_page(inode
->i_mapping
, inode
->i_size
, linvfs_get_block
);
522 * Extended attributes interfaces
525 #define SYSTEM_NAME "system." /* VFS shared names/values */
526 #define ROOT_NAME "xfsroot." /* XFS ondisk names/values */
527 #define USER_NAME "user." /* user's own names/values */
528 STATIC xattr_namespace_t xfs_namespace_array
[] = {
529 { .name
= SYSTEM_NAME
, .namelen
= sizeof(SYSTEM_NAME
)-1,.exists
= NULL
},
530 { .name
= ROOT_NAME
, .namelen
= sizeof(ROOT_NAME
)-1, .exists
= NULL
},
531 { .name
= USER_NAME
, .namelen
= sizeof(USER_NAME
)-1, .exists
= NULL
},
534 xattr_namespace_t
*xfs_namespaces
= &xfs_namespace_array
[0];
536 #define POSIXACL_ACCESS "posix_acl_access"
537 #define POSIXACL_ACCESS_SIZE (sizeof(POSIXACL_ACCESS)-1)
538 #define POSIXACL_DEFAULT "posix_acl_default"
539 #define POSIXACL_DEFAULT_SIZE (sizeof(POSIXACL_DEFAULT)-1)
540 #define POSIXCAP "posix_capabilities"
541 #define POSIXCAP_SIZE (sizeof(POSIXCAP)-1)
542 #define POSIXMAC "posix_mac"
543 #define POSIXMAC_SIZE (sizeof(POSIXMAC)-1)
544 STATIC xattr_namespace_t sys_namespace_array
[] = {
545 { .name
= POSIXACL_ACCESS
,
546 .namelen
= POSIXACL_ACCESS_SIZE
, .exists
= _ACL_ACCESS_EXISTS
},
547 { .name
= POSIXACL_DEFAULT
,
548 .namelen
= POSIXACL_DEFAULT_SIZE
, .exists
= _ACL_DEFAULT_EXISTS
},
550 .namelen
= POSIXCAP_SIZE
, .exists
= _CAP_EXISTS
},
552 .namelen
= POSIXMAC_SIZE
, .exists
= _MAC_EXISTS
},
557 * Some checks to prevent people abusing EAs to get over quota:
558 * - Don't allow modifying user EAs on devices/symlinks;
559 * - Don't allow modifying user EAs if sticky bit set;
565 if (!S_ISREG(inode
->i_mode
) && !S_ISDIR(inode
->i_mode
) &&
566 !capable(CAP_SYS_ADMIN
))
568 if (S_ISDIR(inode
->i_mode
) && (inode
->i_mode
& S_ISVTX
) &&
569 (current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
576 struct dentry
*dentry
,
584 char *p
= (char *)name
;
585 struct inode
*inode
= dentry
->d_inode
;
586 vnode_t
*vp
= LINVFS_GET_VP(inode
);
588 if (strncmp(name
, xfs_namespaces
[SYSTEM_NAMES
].name
,
589 xfs_namespaces
[SYSTEM_NAMES
].namelen
) == 0) {
591 if (flags
& XATTR_CREATE
)
594 p
+= xfs_namespaces
[SYSTEM_NAMES
].namelen
;
595 if (strcmp(p
, POSIXACL_ACCESS
) == 0) {
596 error
= xfs_acl_vset(vp
, data
, size
, _ACL_TYPE_ACCESS
);
598 else if (strcmp(p
, POSIXACL_DEFAULT
) == 0) {
599 error
= xfs_acl_vset(vp
, data
, size
, _ACL_TYPE_DEFAULT
);
601 else if (strcmp(p
, POSIXCAP
) == 0) {
602 error
= xfs_cap_vset(vp
, data
, size
);
605 error
= vn_revalidate(vp
);
610 /* Convert Linux syscall to XFS internal ATTR flags */
611 if (flags
& XATTR_CREATE
)
612 xflags
|= ATTR_CREATE
;
613 if (flags
& XATTR_REPLACE
)
614 xflags
|= ATTR_REPLACE
;
616 if (strncmp(name
, xfs_namespaces
[ROOT_NAMES
].name
,
617 xfs_namespaces
[ROOT_NAMES
].namelen
) == 0) {
618 if (!capable(CAP_SYS_ADMIN
))
621 p
+= xfs_namespaces
[ROOT_NAMES
].namelen
;
622 VOP_ATTR_SET(vp
, p
, data
, size
, xflags
, NULL
, error
);
625 if (strncmp(name
, xfs_namespaces
[USER_NAMES
].name
,
626 xfs_namespaces
[USER_NAMES
].namelen
) == 0) {
627 if (!capable_user_xattr(inode
))
629 p
+= xfs_namespaces
[USER_NAMES
].namelen
;
630 VOP_ATTR_SET(vp
, p
, data
, size
, xflags
, NULL
, error
);
638 struct dentry
*dentry
,
645 char *p
= (char *)name
;
646 struct inode
*inode
= dentry
->d_inode
;
647 vnode_t
*vp
= LINVFS_GET_VP(inode
);
649 if (strncmp(name
, xfs_namespaces
[SYSTEM_NAMES
].name
,
650 xfs_namespaces
[SYSTEM_NAMES
].namelen
) == 0) {
652 p
+= xfs_namespaces
[SYSTEM_NAMES
].namelen
;
653 if (strcmp(p
, POSIXACL_ACCESS
) == 0) {
654 error
= xfs_acl_vget(vp
, data
, size
, _ACL_TYPE_ACCESS
);
656 else if (strcmp(p
, POSIXACL_DEFAULT
) == 0) {
657 error
= xfs_acl_vget(vp
, data
, size
, _ACL_TYPE_DEFAULT
);
659 else if (strcmp(p
, POSIXCAP
) == 0) {
660 error
= xfs_cap_vget(vp
, data
, size
);
665 /* Convert Linux syscall to XFS internal ATTR flags */
667 xflags
|= ATTR_KERNOVAL
;
669 if (strncmp(name
, xfs_namespaces
[ROOT_NAMES
].name
,
670 xfs_namespaces
[ROOT_NAMES
].namelen
) == 0) {
671 if (!capable(CAP_SYS_ADMIN
))
674 p
+= xfs_namespaces
[ROOT_NAMES
].namelen
;
675 VOP_ATTR_GET(vp
, p
, data
, (int *)&size
, xflags
, NULL
, error
);
680 if (strncmp(name
, xfs_namespaces
[USER_NAMES
].name
,
681 xfs_namespaces
[USER_NAMES
].namelen
) == 0) {
682 p
+= xfs_namespaces
[USER_NAMES
].namelen
;
683 if (!capable_user_xattr(inode
))
685 VOP_ATTR_GET(vp
, p
, data
, (int *)&size
, xflags
, NULL
, error
);
696 struct dentry
*dentry
,
702 int xflags
= ATTR_KERNAMELS
;
704 attrlist_cursor_kern_t cursor
;
705 xattr_namespace_t
*sys
;
708 vp
= LINVFS_GET_VP(dentry
->d_inode
);
711 xflags
|= ATTR_KERNOVAL
;
712 if (capable(CAP_SYS_ADMIN
))
713 xflags
|= ATTR_KERNFULLS
;
715 memset(&cursor
, 0, sizeof(cursor
));
716 VOP_ATTR_LIST(vp
, data
, size
, xflags
, &cursor
, NULL
, error
);
721 k
+= result
; /* advance start of our buffer */
722 for (sys
= &sys_namespace_array
[0]; sys
->name
!= NULL
; sys
++) {
723 if (sys
->exists
== NULL
|| !sys
->exists(vp
))
725 result
+= xfs_namespaces
[SYSTEM_NAMES
].namelen
;
726 result
+= sys
->namelen
+ 1;
730 strcpy(k
, xfs_namespaces
[SYSTEM_NAMES
].name
);
731 k
+= xfs_namespaces
[SYSTEM_NAMES
].namelen
;
732 strcpy(k
, sys
->name
);
733 k
+= sys
->namelen
+ 1;
741 struct dentry
*dentry
,
746 char *p
= (char *)name
;
747 struct inode
*inode
= dentry
->d_inode
;
748 vnode_t
*vp
= LINVFS_GET_VP(inode
);
750 if (strncmp(name
, xfs_namespaces
[SYSTEM_NAMES
].name
,
751 xfs_namespaces
[SYSTEM_NAMES
].namelen
) == 0) {
753 p
+= xfs_namespaces
[SYSTEM_NAMES
].namelen
;
754 if (strcmp(p
, POSIXACL_ACCESS
) == 0)
755 error
= xfs_acl_vremove(vp
, _ACL_TYPE_ACCESS
);
756 else if (strcmp(p
, POSIXACL_DEFAULT
) == 0)
757 error
= xfs_acl_vremove(vp
, _ACL_TYPE_DEFAULT
);
758 else if (strcmp(p
, POSIXCAP
) == 0)
759 error
= xfs_cap_vremove(vp
);
763 if (strncmp(name
, xfs_namespaces
[ROOT_NAMES
].name
,
764 xfs_namespaces
[ROOT_NAMES
].namelen
) == 0) {
765 if (!capable(CAP_SYS_ADMIN
))
768 p
+= xfs_namespaces
[ROOT_NAMES
].namelen
;
769 VOP_ATTR_REMOVE(vp
, p
, xflags
, NULL
, error
);
772 if (strncmp(name
, xfs_namespaces
[USER_NAMES
].name
,
773 xfs_namespaces
[USER_NAMES
].namelen
) == 0) {
774 p
+= xfs_namespaces
[USER_NAMES
].namelen
;
775 if (!capable_user_xattr(inode
))
777 VOP_ATTR_REMOVE(vp
, p
, xflags
, NULL
, error
);
784 struct inode_operations linvfs_file_inode_operations
=
786 .permission
= linvfs_permission
,
787 .getattr
= linvfs_getattr
,
788 .truncate
= linvfs_truncate
,
789 .setattr
= linvfs_setattr
,
790 .setxattr
= linvfs_setxattr
,
791 .getxattr
= linvfs_getxattr
,
792 .listxattr
= linvfs_listxattr
,
793 .removexattr
= linvfs_removexattr
,
796 struct inode_operations linvfs_dir_inode_operations
=
798 .create
= linvfs_create
,
799 .lookup
= linvfs_lookup
,
801 .unlink
= linvfs_unlink
,
802 .symlink
= linvfs_symlink
,
803 .mkdir
= linvfs_mkdir
,
804 .rmdir
= linvfs_rmdir
,
805 .mknod
= linvfs_mknod
,
806 .rename
= linvfs_rename
,
807 .permission
= linvfs_permission
,
808 .getattr
= linvfs_getattr
,
809 .setattr
= linvfs_setattr
,
810 .setxattr
= linvfs_setxattr
,
811 .getxattr
= linvfs_getxattr
,
812 .listxattr
= linvfs_listxattr
,
813 .removexattr
= linvfs_removexattr
,
816 struct inode_operations linvfs_symlink_inode_operations
=
818 .readlink
= linvfs_readlink
,
819 .follow_link
= linvfs_follow_link
,
820 .permission
= linvfs_permission
,
821 .getattr
= linvfs_getattr
,
822 .setattr
= linvfs_setattr
,
823 .setxattr
= linvfs_setxattr
,
824 .getxattr
= linvfs_getxattr
,
825 .listxattr
= linvfs_listxattr
,
826 .removexattr
= linvfs_removexattr
,