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;
101 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_SETXATTR);
103 xattr_type = get_xattr_type(name);
104 rc = xattr_type_filter(sbi, xattr_type);
108 ll_inode2fid(&fid, inode);
109 rc = mdc_setxattr(sbi->ll_mdc_exp, &fid, valid,
110 name, value, size, 0, flags, &req);
112 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
113 LCONSOLE_INFO("Disabling user_xattr feature because "
114 "it is not supported on the server\n");
115 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
120 ptlrpc_req_finished(req);
124 int ll_setxattr(struct dentry *dentry, const char *name,
125 const void *value, size_t size, int flags)
127 struct inode *inode = dentry->d_inode;
132 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
133 inode->i_ino, inode->i_generation, inode, name);
135 return ll_setxattr_common(inode, name, value, size, flags,
139 int ll_removexattr(struct dentry *dentry, const char *name)
141 struct inode *inode = dentry->d_inode;
146 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
147 inode->i_ino, inode->i_generation, inode, name);
149 return ll_setxattr_common(inode, name, NULL, 0, 0,
154 int ll_getxattr_common(struct inode *inode, const char *name,
155 void *buffer, size_t size, __u64 valid)
157 struct ll_sb_info *sbi = ll_i2sbi(inode);
158 struct ptlrpc_request *req = NULL;
159 struct mdt_body *body;
165 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
166 inode->i_ino, inode->i_generation, inode);
168 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_GETXATTR);
170 /* listxattr have slightly different behavior from of ext3:
171 * without 'user_xattr' ext3 will list all xattr names but
172 * filtered out "^user..*"; we list them all for simplicity.
175 xattr_type = XATTR_OTHER_T;
179 xattr_type = get_xattr_type(name);
180 rc = xattr_type_filter(sbi, xattr_type);
185 ll_inode2fid(&fid, inode);
186 rc = mdc_getxattr(sbi->ll_mdc_exp, &fid, valid, name, NULL, 0,
189 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
190 LCONSOLE_INFO("Disabling user_xattr feature because "
191 "it is not supported on the server\n");
192 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
197 body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
199 LASSERT_REPSWABBED(req, 0);
201 /* only detect the xattr size */
203 GOTO(out, rc = body->eadatasize);
205 if (size < body->eadatasize) {
206 CERROR("server bug: replied size %u > %u\n",
207 body->eadatasize, (int)size);
208 GOTO(out, rc = -ERANGE);
211 if (req->rq_repmsg->bufcount < 2) {
212 CERROR("reply bufcount %u\n", req->rq_repmsg->bufcount);
213 GOTO(out, rc = -EFAULT);
216 /* do not need swab xattr data */
217 LASSERT_REPSWAB(req, 1);
218 xdata = lustre_msg_buf(req->rq_repmsg, 1, body->eadatasize);
220 CERROR("can't extract: %u : %u\n", body->eadatasize,
221 lustre_msg_buflen(req->rq_repmsg, 1));
222 GOTO(out, rc = -EFAULT);
226 memcpy(buffer, xdata, body->eadatasize);
227 rc = body->eadatasize;
229 ptlrpc_req_finished(req);
233 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
234 void *buffer, size_t size)
236 struct inode *inode = dentry->d_inode;
241 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
242 inode->i_ino, inode->i_generation, inode, name);
244 return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
247 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
249 struct inode *inode = dentry->d_inode;
253 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
254 inode->i_ino, inode->i_generation, inode);
256 return ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);