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>
27 #define DEBUG_SUBSYSTEM S_LLITE
29 #include <obd_support.h>
30 #include <lustre_lite.h>
31 #include <lustre_dlm.h>
32 #include <lustre_ver.h>
33 #include <lustre_mdc.h>
34 #include <linux/lustre_acl.h>
37 #ifndef POSIX_ACL_XATTR_ACCESS
38 #ifndef XATTR_NAME_ACL_ACCESS
39 #define XATTR_NAME_ACL_ACCESS "system.posix_acl_access"
41 #define POSIX_ACL_XATTR_ACCESS XATTR_NAME_ACL_ACCESS
43 #ifndef POSIX_ACL_XATTR_DEFAULT
44 #ifndef XATTR_NAME_ACL_DEFAULT
45 #define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default"
47 #define POSIX_ACL_XATTR_DEFAULT XATTR_NAME_ACL_DEFAULT
51 #include "llite_internal.h"
53 #define XATTR_USER_PREFIX "user."
54 #define XATTR_TRUSTED_PREFIX "trusted."
55 #define XATTR_SECURITY_PREFIX "security."
57 #define XATTR_USER_T (1)
58 #define XATTR_TRUSTED_T (2)
59 #define XATTR_SECURITY_T (3)
60 #define XATTR_ACL_ACCESS_T (4)
61 #define XATTR_ACL_DEFAULT_T (5)
62 #define XATTR_OTHER_T (6)
65 int get_xattr_type(const char *name)
67 if (!strcmp(name, POSIX_ACL_XATTR_ACCESS))
68 return XATTR_ACL_ACCESS_T;
70 if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT))
71 return XATTR_ACL_DEFAULT_T;
73 if (!strncmp(name, XATTR_USER_PREFIX,
74 sizeof(XATTR_USER_PREFIX) - 1))
77 if (!strncmp(name, XATTR_TRUSTED_PREFIX,
78 sizeof(XATTR_TRUSTED_PREFIX) - 1))
79 return XATTR_TRUSTED_T;
81 if (!strncmp(name, XATTR_SECURITY_PREFIX,
82 sizeof(XATTR_SECURITY_PREFIX) - 1))
83 return XATTR_SECURITY_T;
89 int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
91 if (((xattr_type == XATTR_ACL_ACCESS_T) ||
92 (xattr_type == XATTR_ACL_DEFAULT_T)) &&
93 (!(sbi->ll_flags & LL_SBI_ACL) ||
94 (sbi->ll_flags & LL_SBI_RMT_CLIENT)))
97 if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
99 if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN))
101 if (xattr_type == XATTR_OTHER_T)
108 int ll_setxattr_common(struct inode *inode, const char *name,
109 const void *value, size_t size,
110 int flags, __u64 valid)
112 struct ll_sb_info *sbi = ll_i2sbi(inode);
113 struct ptlrpc_request *req;
118 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_SETXATTR);
120 xattr_type = get_xattr_type(name);
121 rc = xattr_type_filter(sbi, xattr_type);
125 /* b10667: ignore lustre special xattr for now */
126 if (xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0)
129 oc = ll_mdscapa_get(inode);
130 rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid, name,
131 value, size, 0, flags, &req);
134 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
135 LCONSOLE_INFO("Disabling user_xattr feature because "
136 "it is not supported on the server\n");
137 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
142 ptlrpc_req_finished(req);
146 int ll_setxattr(struct dentry *dentry, const char *name,
147 const void *value, size_t size, int flags)
149 struct inode *inode = dentry->d_inode;
154 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
155 inode->i_ino, inode->i_generation, inode, name);
157 return ll_setxattr_common(inode, name, value, size, flags,
161 int ll_removexattr(struct dentry *dentry, const char *name)
163 struct inode *inode = dentry->d_inode;
168 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
169 inode->i_ino, inode->i_generation, inode, name);
171 return ll_setxattr_common(inode, name, NULL, 0, 0,
176 int ll_getxattr_common(struct inode *inode, const char *name,
177 void *buffer, size_t size, __u64 valid)
179 struct ll_sb_info *sbi = ll_i2sbi(inode);
180 struct ptlrpc_request *req = NULL;
181 struct mdt_body *body;
187 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
188 inode->i_ino, inode->i_generation, inode);
190 lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_GETXATTR);
192 /* listxattr have slightly different behavior from of ext3:
193 * without 'user_xattr' ext3 will list all xattr names but
194 * filtered out "^user..*"; we list them all for simplicity.
197 xattr_type = XATTR_OTHER_T;
201 xattr_type = get_xattr_type(name);
202 rc = xattr_type_filter(sbi, xattr_type);
206 /* posix acl is under protection of LOOKUP lock. when calling to this,
207 * we just have path resolution to the target inode, so we have great
208 * chance that cached ACL is uptodate.
210 #ifdef CONFIG_FS_POSIX_ACL
211 if (xattr_type == XATTR_ACL_ACCESS_T) {
212 struct ll_inode_info *lli = ll_i2info(inode);
213 struct posix_acl *acl;
215 spin_lock(&lli->lli_lock);
216 acl = posix_acl_dup(lli->lli_posix_acl);
217 spin_unlock(&lli->lli_lock);
222 rc = posix_acl_to_xattr(acl, buffer, size);
223 posix_acl_release(acl);
229 oc = ll_mdscapa_get(inode);
230 rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid, name,
231 NULL, 0, size, 0, &req);
234 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
235 LCONSOLE_INFO("Disabling user_xattr feature because "
236 "it is not supported on the server\n");
237 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
242 body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*body));
244 LASSERT_REPSWABBED(req, REPLY_REC_OFF);
246 /* only detect the xattr size */
248 GOTO(out, rc = body->eadatasize);
250 if (size < body->eadatasize) {
251 CERROR("server bug: replied size %u > %u\n",
252 body->eadatasize, (int)size);
253 GOTO(out, rc = -ERANGE);
256 if (lustre_msg_bufcount(req->rq_repmsg) < 3) {
257 CERROR("reply bufcount %u\n",
258 lustre_msg_bufcount(req->rq_repmsg));
259 GOTO(out, rc = -EFAULT);
262 /* do not need swab xattr data */
263 LASSERT_REPSWAB(req, REPLY_REC_OFF + 1);
264 xdata = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF + 1,
267 CERROR("can't extract: %u : %u\n", body->eadatasize,
268 lustre_msg_buflen(req->rq_repmsg, REPLY_REC_OFF + 1));
269 GOTO(out, rc = -EFAULT);
273 memcpy(buffer, xdata, body->eadatasize);
274 rc = body->eadatasize;
276 ptlrpc_req_finished(req);
280 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
281 void *buffer, size_t size)
283 struct inode *inode = dentry->d_inode;
288 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
289 inode->i_ino, inode->i_generation, inode, name);
291 return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
294 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
296 struct inode *inode = dentry->d_inode;
300 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
301 inode->i_ino, inode->i_generation, inode);
303 return ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);