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 <linux/lustre_version.h>
34 #ifndef POSIX_ACL_XATTR_ACCESS
35 #ifndef XATTR_NAME_ACL_ACCESS
36 #define XATTR_NAME_ACL_ACCESS "system.posix_acl_access"
38 #define POSIX_ACL_XATTR_ACCESS XATTR_NAME_ACL_ACCESS
40 #ifndef POSIX_ACL_XATTR_DEFAULT
41 #ifndef XATTR_NAME_ACL_DEFAULT
42 #define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default"
44 #define POSIX_ACL_XATTR_DEFAULT XATTR_NAME_ACL_DEFAULT
47 #include "llite_internal.h"
49 #define XATTR_USER_PREFIX "user."
50 #define XATTR_TRUSTED_PREFIX "trusted."
51 #define XATTR_SECURITY_PREFIX "security."
52 #define XATTR_LUSTRE_PREFIX "lustre."
54 #define XATTR_USER_T (1)
55 #define XATTR_TRUSTED_T (2)
56 #define XATTR_SECURITY_T (3)
57 #define XATTR_ACL_ACCESS_T (4)
58 #define XATTR_ACL_DEFAULT_T (5)
59 #define XATTR_LUSTRE_T (6)
60 #define XATTR_OTHER_T (7)
63 int get_xattr_type(const char *name)
65 if (!strcmp(name, POSIX_ACL_XATTR_ACCESS))
66 return XATTR_ACL_ACCESS_T;
68 if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT))
69 return XATTR_ACL_DEFAULT_T;
71 if (!strncmp(name, XATTR_USER_PREFIX,
72 sizeof(XATTR_USER_PREFIX) - 1))
75 if (!strncmp(name, XATTR_TRUSTED_PREFIX,
76 sizeof(XATTR_TRUSTED_PREFIX) - 1))
77 return XATTR_TRUSTED_T;
79 if (!strncmp(name, XATTR_SECURITY_PREFIX,
80 sizeof(XATTR_SECURITY_PREFIX) - 1))
81 return XATTR_SECURITY_T;
83 if (!strncmp(name, XATTR_LUSTRE_PREFIX,
84 sizeof(XATTR_LUSTRE_PREFIX) - 1))
85 return XATTR_LUSTRE_T;
91 int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
93 if ((xattr_type == XATTR_ACL_ACCESS_T ||
94 xattr_type == XATTR_ACL_DEFAULT_T) &&
95 !(sbi->ll_flags & LL_SBI_ACL))
98 if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
100 if (xattr_type == XATTR_TRUSTED_T && !capable(CAP_SYS_ADMIN))
102 if (xattr_type == XATTR_OTHER_T)
109 int ll_setxattr_common(struct inode *inode, const char *name,
110 const void *value, size_t size,
111 int flags, __u64 valid)
113 struct ll_sb_info *sbi = ll_i2sbi(inode);
114 struct ptlrpc_request *req;
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) ||
127 (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
130 ll_inode2fid(&fid, inode);
131 rc = mdc_setxattr(sbi->ll_mdc_exp, &fid, valid,
132 name, 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 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
159 if ((strncmp(name, XATTR_TRUSTED_PREFIX,
160 sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
161 strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
162 (strncmp(name, XATTR_LUSTRE_PREFIX,
163 sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
164 strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
165 struct lov_user_md *lump = (struct lov_user_md *)value;
168 if (S_ISREG(inode->i_mode)) {
170 int flags = FMODE_WRITE;
173 rc = ll_lov_setstripe_ea_info(inode, &f, flags,
174 lump, sizeof(*lump));
175 /* b10667: rc always be 0 here for now */
177 } else if (S_ISDIR(inode->i_mode)) {
178 rc = ll_dir_setstripe(inode, lump, 0);
184 return ll_setxattr_common(inode, name, value, size, flags,
188 int ll_removexattr(struct dentry *dentry, const char *name)
190 struct inode *inode = dentry->d_inode;
195 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
196 inode->i_ino, inode->i_generation, inode, name);
198 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
199 return ll_setxattr_common(inode, name, NULL, 0, 0,
204 int ll_getxattr_common(struct inode *inode, const char *name,
205 void *buffer, size_t size, __u64 valid)
207 struct ll_sb_info *sbi = ll_i2sbi(inode);
208 struct ptlrpc_request *req = NULL;
209 struct mds_body *body;
215 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
216 inode->i_ino, inode->i_generation, inode);
219 /* listxattr have slightly different behavior from of ext3:
220 * without 'user_xattr' ext3 will list all xattr names but
221 * filtered out "^user..*"; we list them all for simplicity.
224 xattr_type = XATTR_OTHER_T;
228 xattr_type = get_xattr_type(name);
229 rc = xattr_type_filter(sbi, xattr_type);
233 /* posix acl is under protection of LOOKUP lock. when calling to this,
234 * we just have path resolution to the target inode, so we have great
235 * chance that cached ACL is uptodate.
237 #ifdef CONFIG_FS_POSIX_ACL
238 if (xattr_type == XATTR_ACL_ACCESS_T) {
239 struct ll_inode_info *lli = ll_i2info(inode);
240 struct posix_acl *acl;
242 spin_lock(&lli->lli_lock);
243 acl = posix_acl_dup(lli->lli_posix_acl);
244 spin_unlock(&lli->lli_lock);
249 rc = posix_acl_to_xattr(acl, buffer, size);
250 posix_acl_release(acl);
253 if (xattr_type == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
258 ll_inode2fid(&fid, inode);
259 rc = mdc_getxattr(sbi->ll_mdc_exp, &fid, valid, name, NULL, 0, size,
262 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
263 LCONSOLE_INFO("Disabling user_xattr feature because "
264 "it is not supported on the server\n");
265 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
270 body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*body));
272 LASSERT(lustre_rep_swabbed(req, REPLY_REC_OFF));
274 /* only detect the xattr size */
276 GOTO(out, rc = body->eadatasize);
278 if (size < body->eadatasize) {
279 CERROR("server bug: replied size %u > %u\n",
280 body->eadatasize, (int)size);
281 GOTO(out, rc = -ERANGE);
284 if (lustre_msg_bufcount(req->rq_repmsg) < 3) {
285 CERROR("reply bufcount %u\n",
286 lustre_msg_bufcount(req->rq_repmsg));
287 GOTO(out, rc = -EFAULT);
290 /* do not need swab xattr data */
291 lustre_set_rep_swabbed(req, REPLY_REC_OFF + 1);
292 xdata = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF + 1,
295 CERROR("can't extract: %u : %u\n", body->eadatasize,
296 lustre_msg_buflen(req->rq_repmsg, REPLY_REC_OFF + 1));
297 GOTO(out, rc = -EFAULT);
301 memcpy(buffer, xdata, body->eadatasize);
302 rc = body->eadatasize;
304 ptlrpc_req_finished(req);
308 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
309 void *buffer, size_t size)
311 struct inode *inode = dentry->d_inode;
316 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), xattr %s\n",
317 inode->i_ino, inode->i_generation, inode, name);
319 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
321 if ((strncmp(name, XATTR_TRUSTED_PREFIX,
322 sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
323 strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
324 (strncmp(name, XATTR_LUSTRE_PREFIX,
325 sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
326 strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
327 struct lov_user_md *lump;
328 struct lov_mds_md *lmm = NULL;
329 struct ptlrpc_request *request = NULL;
332 if (S_ISREG(inode->i_mode)) {
333 rc = ll_lov_getstripe_ea_info(dentry->d_parent->d_inode,
334 dentry->d_name.name, &lmm,
336 } else if (S_ISDIR(inode->i_mode)) {
337 rc = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
343 GOTO(out, rc = lmmsize);
345 if (size < lmmsize) {
346 CERROR("server bug: replied size %u > %u\n",
348 GOTO(out, rc = -ERANGE);
351 lump = (struct lov_user_md *)buffer;
352 memcpy(lump, lmm, lmmsize);
356 ptlrpc_req_finished(request);
360 return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
363 ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
365 struct inode *inode = dentry->d_inode;
367 struct lov_mds_md *lmm = NULL;
368 struct ptlrpc_request *request = NULL;
373 CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
374 inode->i_ino, inode->i_generation, inode);
376 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
378 rc = ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);
380 if (S_ISREG(inode->i_mode)) {
381 struct ll_inode_info *lli = ll_i2info(inode);
382 struct lov_stripe_md *lsm = NULL;
386 } else if (S_ISDIR(inode->i_mode)) {
387 rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
393 const int prefix_len = sizeof(XATTR_LUSTRE_PREFIX) - 1;
394 const size_t name_len = sizeof("lov") - 1;
395 const size_t total_len = prefix_len + name_len + 1;
397 if (buffer && (rc + total_len) <= size) {
399 memcpy(buffer,XATTR_LUSTRE_PREFIX, prefix_len);
400 memcpy(buffer+prefix_len, "lov", name_len);
401 buffer[prefix_len + name_len] = '\0';
406 ptlrpc_req_finished(request);