1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * linux/mds/mds_xattr.c
5 * Lustre Metadata Server (mds) extended attributes handling
7 * Copyright (C) 2004-2005 Cluster File Systems, Inc.
9 * This file is part of the Lustre file system, http://www.lustre.org
10 * Lustre is a trademark of Cluster File Systems, Inc.
12 * You may have signed or agreed to another license before downloading
13 * this software. If so, you are bound by the terms and conditions
14 * of that agreement, and the following does not apply to you. See the
15 * LICENSE file included with this distribution for more information.
17 * If you did not agree to a different license, then this copy of Lustre
18 * is open source software; you can redistribute it and/or modify it
19 * under the terms of version 2 of the GNU General Public License as
20 * published by the Free Software Foundation.
22 * In either case, Lustre is distributed in the hope that it will be
23 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
24 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * license text for more details.
29 # define EXPORT_SYMTAB
31 #define DEBUG_SUBSYSTEM S_MDS
34 #include <linux/obd_support.h>
35 #include <linux/obd_class.h>
36 #include <linux/obd.h>
37 #include <linux/lustre_lib.h>
38 #include <linux/lustre_idl.h>
39 #include <linux/lustre_mds.h>
40 #include <linux/lustre_dlm.h>
41 #include <linux/lustre_fsfilt.h>
42 #include <linux/lustre_ucache.h>
44 #include "mds_internal.h"
46 static int mds_getxattr_pack_msg(struct ptlrpc_request *req,
48 struct mds_body *body)
50 struct inode *inode = de->d_inode;
51 int size[2] = {sizeof(*body)}, bufcnt = 1;
53 int rc = -EOPNOTSUPP, rc2;
58 if (body->valid & OBD_MD_FLXATTR) {
59 xattr_name = lustre_msg_string(req->rq_reqmsg, 1, 0);
61 CERROR("can't extract xattr name\n");
65 if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) &&
66 (strncmp(xattr_name, "user.", 5) == 0))
69 if (inode->i_op && inode->i_op->getxattr)
70 rc = inode->i_op->getxattr(de, xattr_name, NULL, 0);
71 } else if (body->valid & OBD_MD_FLXATTRLS) {
72 if (inode->i_op && inode->i_op->listxattr)
73 rc = inode->i_op->listxattr(de, NULL, 0);
75 CERROR("valid bits: "LPX64"\n", body->valid);
80 if (rc != -ENODATA && rc != -EOPNOTSUPP)
81 CWARN("get inode %lu EA size error: %d\n",
85 size[bufcnt++] = min_t(int, body->eadatasize, rc);
88 if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) {
89 CERROR("failed MDS_GETXATTR_PACK test\n");
90 req->rq_status = -ENOMEM;
94 rc2 = lustre_pack_reply(req, bufcnt, size, NULL);
103 static int mds_getxattr_internal(struct obd_device *obd,
104 struct dentry *dentry,
105 struct ptlrpc_request *req,
106 struct mds_body *reqbody)
108 struct mds_body *repbody;
109 struct inode *inode = dentry->d_inode;
112 int buflen, rc = -EOPNOTSUPP;
116 GOTO(out, rc = -ENOENT);
118 repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
119 LASSERT(repbody != NULL);
121 buflen = lustre_msg_buflen(req->rq_repmsg, 1);
123 buf = lustre_msg_buf(req->rq_repmsg, 1, buflen);
125 if (reqbody->valid & OBD_MD_FLXATTR) {
126 xattr_name = lustre_msg_string(req->rq_reqmsg, 1, 0);
127 DEBUG_REQ(D_INODE, req, "getxattr %s\n", xattr_name);
129 if (inode->i_op && inode->i_op->getxattr) {
131 rc = inode->i_op->getxattr(dentry, xattr_name,
136 if (rc < 0 && rc != -ENODATA && rc != -EOPNOTSUPP &&
138 CDEBUG(D_OTHER, "getxattr failed: %d\n", rc);
139 } else if (reqbody->valid & OBD_MD_FLXATTRLS) {
140 DEBUG_REQ(D_INODE, req, "listxattr\n");
142 if (inode->i_op && inode->i_op->listxattr) {
144 rc = inode->i_op->listxattr(dentry, buf, buflen);
148 CDEBUG(D_OTHER, "listxattr failed: %d\n", rc);
153 repbody->eadatasize = rc;
161 int mds_getxattr(struct ptlrpc_request *req)
163 struct mds_obd *mds = mds_req2mds(req);
164 struct obd_device *obd = req->rq_export->exp_obd;
165 struct lvfs_run_ctxt saved;
167 struct mds_body *body;
168 struct lvfs_ucred uc = {NULL,};
172 body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
176 rc = mds_init_ucred(&uc, req, 0);
180 push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
181 de = mds_fid2dentry(mds, &body->fid1, NULL);
183 rc = req->rq_status = PTR_ERR(de);
187 rc = mds_getxattr_pack_msg(req, de, body);
188 if (rc != 0 || req->rq_status)
191 rc = mds_getxattr_internal(obd, de, req, body);
196 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
198 mds_exit_ucred(&uc, mds);
203 int mds_setxattr_internal(struct ptlrpc_request *req, struct mds_body *body)
205 struct mds_obd *mds = mds_req2mds(req);
206 struct obd_device *obd = req->rq_export->exp_obd;
208 struct inode *inode = NULL;
209 struct lustre_handle lockh;
214 int rc = -EOPNOTSUPP, err = 0;
218 body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
221 DEBUG_REQ(D_INODE, req, "setxattr "LPU64"/%u",
222 body->fid1.id, body->fid1.generation);
224 MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
226 lockpart = MDS_INODELOCK_UPDATE;
228 de = mds_fid2locked_dentry(obd, &body->fid1, NULL, LCK_EX,
231 GOTO(out, rc = PTR_ERR(de));
236 OBD_FAIL_WRITE(OBD_FAIL_MDS_SETXATTR_WRITE, inode->i_sb);
238 xattr_name = lustre_msg_string(req->rq_reqmsg, 1, 0);
240 CERROR("can't extract xattr name\n");
241 GOTO(out_dput, rc = -EPROTO);
244 DEBUG_REQ(D_INODE, req, "%sxattr %s\n",
245 body->valid & OBD_MD_FLXATTR ? "set" : "remove",
248 if (strncmp(xattr_name, "trusted.", 8) == 0) {
249 if (strcmp(xattr_name + 8, XATTR_LUSTRE_MDS_LOV_EA) == 0)
250 GOTO(out_dput, rc = -EACCES);
253 if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) &&
254 (strncmp(xattr_name, "user.", 5) == 0)) {
255 GOTO(out_dput, rc = -EOPNOTSUPP);
258 /* filter_op simply use setattr one */
259 handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
261 GOTO(out_dput, rc = PTR_ERR(handle));
263 if (body->valid & OBD_MD_FLXATTR) {
264 if (inode->i_op && inode->i_op->setxattr) {
265 if (req->rq_reqmsg->bufcount < 3) {
266 CERROR("no xattr data supplied\n");
267 GOTO(out_trans, rc = -EFAULT);
270 xattrlen = lustre_msg_buflen(req->rq_reqmsg, 2);
272 xattr = lustre_msg_buf(req->rq_reqmsg, 2,
277 rc = inode->i_op->setxattr(de, xattr_name, xattr,
278 xattrlen, body->flags);
282 } else if (body->valid & OBD_MD_FLXATTRRM) {
283 if (inode->i_op && inode->i_op->removexattr) {
286 rc = inode->i_op->removexattr(de, xattr_name);
291 CERROR("valid bits: "LPX64"\n", body->valid);
297 err = mds_finish_transno(mds, inode, handle, req, rc, 0);
302 ldlm_lock_decref(&lockh, LCK_EX);
304 ptlrpc_save_lock (req, &lockh, LCK_EX);
313 int mds_setxattr(struct ptlrpc_request *req)
315 struct mds_obd *mds = mds_req2mds(req);
316 struct obd_device *obd = req->rq_export->exp_obd;
317 struct lvfs_run_ctxt saved;
318 struct mds_body *body;
319 struct lvfs_ucred uc = {NULL,};
323 body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
327 if (req->rq_reqmsg->bufcount < 2)
330 rc = mds_init_ucred(&uc, req, 0);
334 push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
336 rc = lustre_pack_reply(req, 0, NULL, NULL);
340 rc = mds_setxattr_internal(req, body);
343 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
345 mds_exit_ucred(&uc, mds);