Whamcloud - gitweb
mds_fid2locked_dentry(): kill unused parameters
[fs/lustre-release.git] / lustre / mds / mds_xattr.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  linux/mds/mds_xattr.c
5  *  Lustre Metadata Server (mds) extended attributes handling
6  *
7  *  Copyright (C) 2004-2005 Cluster File Systems, Inc.
8  *
9  *   This file is part of the Lustre file system, http://www.lustre.org
10  *   Lustre is a trademark of Cluster File Systems, Inc.
11  *
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.
16  *
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.
21  *
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.
26  */
27
28 #ifndef EXPORT_SYMTAB
29 # define EXPORT_SYMTAB
30 #endif
31 #define DEBUG_SUBSYSTEM S_MDS
32
33 #include <linux/fs.h>
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>
43
44 #include "mds_internal.h"
45
46 static int mds_getxattr_pack_msg(struct ptlrpc_request *req,
47                                  struct dentry *de,
48                                  struct mds_body *body)
49 {
50         struct inode *inode = de->d_inode;
51         int size[2] = {sizeof(*body)}, bufcnt = 1;
52         char *xattr_name;
53         int rc = -EOPNOTSUPP, rc2;
54
55         if (inode == NULL)
56                 return -ENOENT;
57
58         if (body->valid & OBD_MD_FLXATTR) {
59                 xattr_name = lustre_msg_string(req->rq_reqmsg, 1, 0);
60                 if (!xattr_name) {
61                         CERROR("can't extract xattr name\n");
62                         return -EFAULT;
63                 }
64
65                 if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) &&
66                     (strncmp(xattr_name, "user.", 5) == 0))
67                         return -EOPNOTSUPP;
68
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);
74         } else {
75                 CERROR("valid bits: "LPX64"\n", body->valid);
76                 return -EINVAL;
77         }
78
79         if (rc < 0) {
80                 if (rc != -ENODATA && rc != -EOPNOTSUPP)
81                         CWARN("get inode %lu EA size error: %d\n",
82                               inode->i_ino, rc);
83                 bufcnt = 0;
84         } else {
85                 size[bufcnt++] = min_t(int, body->eadatasize, rc);
86         }
87
88         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) {
89                 CERROR("failed MDS_GETXATTR_PACK test\n");
90                 req->rq_status = -ENOMEM;
91                 return -ENOMEM;
92         }
93
94         rc2 = lustre_pack_reply(req, bufcnt, size, NULL);
95         if (rc2)
96                 return rc2;
97
98         if (rc < 0)
99                 req->rq_status = rc;
100         return 0;
101 }
102
103 static int mds_getxattr_internal(struct obd_device *obd,
104                                  struct dentry *dentry,
105                                  struct ptlrpc_request *req,
106                                  struct mds_body *reqbody)
107 {
108         struct mds_body *repbody;
109         struct inode *inode = dentry->d_inode;
110         char *xattr_name;
111         void *buf = NULL;
112         int buflen, rc = -EOPNOTSUPP;
113         ENTRY;
114
115         if (inode == NULL)
116                 GOTO(out, rc = -ENOENT);
117
118         repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
119         LASSERT(repbody != NULL);
120
121         buflen = lustre_msg_buflen(req->rq_repmsg, 1);
122         if (buflen)
123                 buf = lustre_msg_buf(req->rq_repmsg, 1, buflen);
124
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);
128
129                 if (inode->i_op && inode->i_op->getxattr) {
130                         lock_24kernel();
131                         rc = inode->i_op->getxattr(dentry, xattr_name,
132                                                    buf, buflen);
133                         unlock_24kernel();
134                 }
135
136                 if (rc < 0 && rc != -ENODATA && rc != -EOPNOTSUPP &&
137                     rc != -ERANGE)
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");
141
142                 if (inode->i_op && inode->i_op->listxattr) {
143                         lock_24kernel();
144                         rc = inode->i_op->listxattr(dentry, buf, buflen);
145                         unlock_24kernel();
146                 }
147                 if (rc < 0)
148                         CDEBUG(D_OTHER, "listxattr failed: %d\n", rc);
149         } else
150                 LBUG();
151
152         if (rc >= 0) {
153                 repbody->eadatasize = rc;
154                 rc = 0;
155         }
156 out:
157         req->rq_status = rc;
158         RETURN(0);
159 }
160
161 int mds_getxattr(struct ptlrpc_request *req)
162 {
163         struct mds_obd *mds = mds_req2mds(req);
164         struct obd_device *obd = req->rq_export->exp_obd;
165         struct lvfs_run_ctxt saved;
166         struct dentry *de;
167         struct mds_body *body;
168         struct lvfs_ucred uc = {NULL,};
169         int rc = 0;
170         ENTRY;
171
172         body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
173         if (body == NULL)
174                 RETURN(-EFAULT);
175
176         rc = mds_init_ucred(&uc, req, 0);
177         if (rc)
178                 GOTO(out_ucred, rc);
179
180         push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
181         de = mds_fid2dentry(mds, &body->fid1, NULL);
182         if (IS_ERR(de)) {
183                 rc = req->rq_status = PTR_ERR(de);
184                 GOTO(out_pop, rc);
185         }
186
187         rc = mds_getxattr_pack_msg(req, de, body);
188         if (rc != 0 || req->rq_status)
189                 GOTO(out_dput, rc);
190
191         rc = mds_getxattr_internal(obd, de, req, body);
192
193 out_dput:
194         l_dput(de);
195 out_pop:
196         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
197 out_ucred:
198         mds_exit_ucred(&uc, mds);
199         return rc;
200 }
201
202 static
203 int mds_setxattr_internal(struct ptlrpc_request *req, struct mds_body *body)
204 {
205         struct mds_obd *mds = mds_req2mds(req);
206         struct obd_device *obd = req->rq_export->exp_obd;
207         struct dentry *de;
208         struct inode *inode = NULL;
209         struct lustre_handle lockh;
210         void *handle = NULL;
211         char *xattr_name;
212         char *xattr = NULL;
213         int xattrlen;
214         int rc = -EOPNOTSUPP, err = 0;
215         __u64 lockpart;
216         ENTRY;
217
218         body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof (*body));
219         LASSERT(body);
220
221         DEBUG_REQ(D_INODE, req, "setxattr "LPU64"/%u",
222                   body->fid1.id, body->fid1.generation);
223
224         MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
225
226         lockpart = MDS_INODELOCK_UPDATE;
227
228         de = mds_fid2locked_dentry(obd, &body->fid1, NULL, LCK_EX,
229                                    &lockh, lockpart);
230         if (IS_ERR(de))
231                 GOTO(out, rc = PTR_ERR(de));
232
233         inode = de->d_inode;
234         LASSERT(inode);
235
236         OBD_FAIL_WRITE(OBD_FAIL_MDS_SETXATTR_WRITE, inode->i_sb);
237
238         xattr_name = lustre_msg_string(req->rq_reqmsg, 1, 0);
239         if (!xattr_name) {
240                 CERROR("can't extract xattr name\n");
241                 GOTO(out_dput, rc = -EPROTO);
242         }
243
244         DEBUG_REQ(D_INODE, req, "%sxattr %s\n",
245                   body->valid & OBD_MD_FLXATTR ? "set" : "remove",
246                   xattr_name);
247
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);
251         }
252
253         if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) &&
254             (strncmp(xattr_name, "user.", 5) == 0)) {
255                 GOTO(out_dput, rc = -EOPNOTSUPP);
256         }
257
258         /* filter_op simply use setattr one */
259         handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL);
260         if (IS_ERR(handle))
261                 GOTO(out_dput, rc = PTR_ERR(handle));
262
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);
268                         }
269
270                         xattrlen = lustre_msg_buflen(req->rq_reqmsg, 2);
271                         if (xattrlen)
272                                 xattr = lustre_msg_buf(req->rq_reqmsg, 2,
273                                                        xattrlen);
274
275                         down(&inode->i_sem);
276                         lock_24kernel();
277                         rc = inode->i_op->setxattr(de, xattr_name, xattr,
278                                                    xattrlen, body->flags);
279                         unlock_24kernel();
280                         up(&inode->i_sem);
281                 }
282         } else if (body->valid & OBD_MD_FLXATTRRM) {
283                 if (inode->i_op && inode->i_op->removexattr) {
284                         down(&inode->i_sem);
285                         lock_24kernel();
286                         rc = inode->i_op->removexattr(de, xattr_name);
287                         unlock_24kernel();
288                         up(&inode->i_sem);
289                 }
290         } else {
291                 CERROR("valid bits: "LPX64"\n", body->valid);
292                 rc = -EINVAL;
293         }
294
295         LASSERT(rc <= 0);
296 out_trans:
297         err = mds_finish_transno(mds, inode, handle, req, rc, 0);
298
299 out_dput:
300         l_dput(de);
301         if (rc)
302                 ldlm_lock_decref(&lockh, LCK_EX);
303         else
304                 ptlrpc_save_lock (req, &lockh, LCK_EX);
305
306         if (err && !rc)
307                 rc = err;
308 out:
309         req->rq_status = rc;
310         return 0;
311 }
312
313 int mds_setxattr(struct ptlrpc_request *req)
314 {
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,};
320         int rc;
321         ENTRY;
322
323         body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
324         if (body == NULL)
325                 RETURN(-EFAULT);
326
327         if (req->rq_reqmsg->bufcount < 2)
328                 RETURN(-EFAULT);
329
330         rc = mds_init_ucred(&uc, req, 0);
331         if (rc)
332                 GOTO(out_ucred, rc);
333
334         push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
335
336         rc = lustre_pack_reply(req, 0, NULL, NULL);
337         if (rc)
338                 GOTO(out_pop, rc);
339
340         rc = mds_setxattr_internal(req, body);
341
342 out_pop:
343         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
344 out_ucred:
345         mds_exit_ucred(&uc, mds);
346         return rc;
347 }