1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2004 - 2005 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <linux/sched.h>
25 #include <linux/smp_lock.h>
26 #ifdef HAVE_LINUX_XATTR_ACL_H
27 #include <linux/xattr_acl.h>
29 #define XATTR_NAME_ACL_ACCESS "system.posix_acl_access"
30 #define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default"
33 #define DEBUG_SUBSYSTEM S_LLITE
35 #include <linux/obd_support.h>
36 #include <linux/lustre_lite.h>
37 #include <linux/lustre_dlm.h>
38 #include <linux/lustre_version.h>
39 #include <linux/lustre_mdc.h>
41 #include "llite_internal.h"
43 #define XATTR_USER_PREFIX "user."
44 #define XATTR_TRUSTED_PREFIX "trusted."
45 #define XATTR_SECURITY_PREFIX "security."
47 #define XATTR_USER_T (1)
48 #define XATTR_TRUSTED_T (2)
49 #define XATTR_SECURITY_T (3)
50 #define XATTR_ACL_T (4)
51 #define XATTR_OTHER_T (5)
54 int get_xattr_type(const char *name)
56 if (!strcmp(name, XATTR_NAME_ACL_ACCESS) ||
57 !strcmp(name, XATTR_NAME_ACL_DEFAULT))
60 if (!strncmp(name, XATTR_USER_PREFIX,
61 sizeof(XATTR_USER_PREFIX) - 1))
64 if (!strncmp(name, XATTR_TRUSTED_PREFIX,
65 sizeof(XATTR_TRUSTED_PREFIX) - 1))
66 return XATTR_TRUSTED_T;
68 if (!strncmp(name, XATTR_SECURITY_PREFIX,
69 sizeof(XATTR_SECURITY_PREFIX) - 1))
70 return XATTR_SECURITY_T;
76 int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
78 if (xattr_type == XATTR_ACL_T && !(sbi->ll_flags & LL_SBI_ACL))
80 if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
82 if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN))
84 if (xattr_type == XATTR_OTHER_T)
91 int ll_setxattr_common(struct inode *inode, const char *name,
92 const void *value, size_t size,
93 int flags, __u64 valid)
95 struct ll_sb_info *sbi = ll_i2sbi(inode);
96 struct ptlrpc_request *req;
100 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_SETXATTR);
102 xattr_type = get_xattr_type(name);
103 rc = xattr_type_filter(sbi, xattr_type);
107 rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), valid,
108 name, value, size, 0, flags, &req);
110 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
111 LCONSOLE_INFO("Disabling user_xattr feature because "
112 "it is not supported on the server\n");
113 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
118 ptlrpc_req_finished(req);
122 int ll_setxattr(struct dentry *dentry, const char *name,
123 const void *value, size_t size, int flags)
125 struct inode *inode = dentry->d_inode;
130 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
131 inode->i_ino, inode->i_generation, inode, name);
133 return ll_setxattr_common(inode, name, value, size, flags,
137 int ll_removexattr(struct dentry *dentry, const char *name)
139 struct inode *inode = dentry->d_inode;
144 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
145 inode->i_ino, inode->i_generation, inode, name);
147 return ll_setxattr_common(inode, name, NULL, 0, 0,
152 int ll_getxattr_common(struct inode *inode, const char *name,
153 void *buffer, size_t size, __u64 valid)
155 struct ll_sb_info *sbi = ll_i2sbi(inode);
156 struct ptlrpc_request *req = NULL;
157 struct mdt_body *body;
162 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
163 inode->i_ino, inode->i_generation, inode);
165 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_GETXATTR);
167 /* listxattr have slightly different behavior from of ext3:
168 * without 'user_xattr' ext3 will list all xattr names but
169 * filtered out "^user..*"; we list them all for simplicity.
172 xattr_type = XATTR_OTHER_T;
176 xattr_type = get_xattr_type(name);
177 rc = xattr_type_filter(sbi, xattr_type);
182 rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), valid,
183 name, NULL, 0, size, 0, &req);
185 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
186 LCONSOLE_INFO("Disabling user_xattr feature because "
187 "it is not supported on the server\n");
188 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
193 body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
195 LASSERT_REPSWABBED(req, 0);
197 /* only detect the xattr size */
199 GOTO(out, rc = body->eadatasize);
201 if (size < body->eadatasize) {
202 CERROR("server bug: replied size %u > %u\n",
203 body->eadatasize, (int)size);
204 GOTO(out, rc = -ERANGE);
207 if (req->rq_repmsg->bufcount < 2) {
208 CERROR("reply bufcount %u\n", req->rq_repmsg->bufcount);
209 GOTO(out, rc = -EFAULT);
212 /* do not need swab xattr data */
213 LASSERT_REPSWAB(req, 1);
214 xdata = lustre_msg_buf(req->rq_repmsg, 1, body->eadatasize);
216 CERROR("can't extract: %u : %u\n", body->eadatasize,
217 lustre_msg_buflen(req->rq_repmsg, 1));
218 GOTO(out, rc = -EFAULT);
222 memcpy(buffer, xdata, body->eadatasize);
223 rc = body->eadatasize;
225 ptlrpc_req_finished(req);
229 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
230 void *buffer, size_t size)
232 struct inode *inode = dentry->d_inode;
237 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
238 inode->i_ino, inode->i_generation, inode, name);
240 return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
243 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
245 struct inode *inode = dentry->d_inode;
249 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
250 inode->i_ino, inode->i_generation, inode);
252 return ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);