Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[fs/lustre-release.git] / lustre / llite / llite_nfs.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  *
31  * lustre/lustre/llite/llite_nfs.c
32  *
33  * NFS export of Lustre Light File System
34  *
35  * Author: Yury Umanets <umka@clusterfs.com>
36  * Author: Huang Hua <huanghua@clusterfs.com>
37  */
38
39 #define DEBUG_SUBSYSTEM S_LLITE
40 #include <linux/exportfs.h>
41
42 #include <lustre_fid.h>
43 #include "llite_internal.h"
44
45 u32 get_uuid2int(const char *name, int len)
46 {
47         u32 key0 = 0x12a3fe2d, key1 = 0x37abe8f9;
48
49         while (len--) {
50                 u32 key = key1 + (key0 ^ (*name++ * 7152373));
51
52                 if (key & 0x80000000)
53                         key -= 0x7fffffff;
54
55                 key1 = key0;
56                 key0 = key;
57         }
58         return (key0 << 1);
59 }
60
61 struct inode *search_inode_for_lustre(struct super_block *sb,
62                                       const struct lu_fid *fid)
63 {
64         struct ll_sb_info *sbi = ll_s2sbi(sb);
65         struct ptlrpc_request *req = NULL;
66         struct inode *inode = NULL;
67         int eadatalen = 0;
68         unsigned long hash = cl_fid_build_ino(fid, ll_need_32bit_api(sbi));
69         struct md_op_data *op_data;
70         int rc;
71
72         ENTRY;
73
74         CDEBUG(D_INFO, "searching inode for:(%lu,"DFID")\n", hash, PFID(fid));
75
76         inode = ilookup5(sb, hash, ll_test_inode_by_fid, (void *)fid);
77         if (inode)
78                 RETURN(inode);
79
80         rc = ll_get_default_mdsize(sbi, &eadatalen);
81         if (rc)
82                 RETURN(ERR_PTR(rc));
83
84         /*
85          * Because inode is NULL, ll_prep_md_op_data can not
86          * be used here. So we allocate op_data ourselves
87          */
88         OBD_ALLOC_PTR(op_data);
89         if (!op_data)
90                 return ERR_PTR(-ENOMEM);
91
92         op_data->op_fid1 = *fid;
93         op_data->op_mode = eadatalen;
94         op_data->op_valid = OBD_MD_FLEASIZE;
95
96         /* mds_fid2dentry ignores f_type */
97         rc = md_getattr(sbi->ll_md_exp, op_data, &req);
98         OBD_FREE_PTR(op_data);
99         if (rc) {
100                 /*
101                  * Suppress erroneous/confusing messages when NFS
102                  * is out of sync and requests old data.
103                  */
104                 CDEBUG(D_INFO, "can't get object attrs, fid "DFID", rc %d\n",
105                                 PFID(fid), rc);
106                 RETURN(ERR_PTR(rc));
107         }
108         rc = ll_prep_inode(&inode, &req->rq_pill, sb, NULL);
109         ptlrpc_req_finished(req);
110         if (rc)
111                 RETURN(ERR_PTR(rc));
112
113         RETURN(inode);
114 }
115
116 static struct dentry *
117 ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *parent)
118 {
119         bool is_dot_lustre = fid_is_dot_lustre(fid);
120         struct dentry *result;
121         struct inode *inode;
122
123         ENTRY;
124         if (!fid_is_sane(fid))
125                 RETURN(ERR_PTR(-ESTALE));
126
127         CDEBUG(D_INFO, "Get dentry for fid: "DFID"\n", PFID(fid));
128
129         if (fid_is_root(fid))
130                 RETURN(dget(sb->s_root));
131
132         inode = search_inode_for_lustre(sb, fid);
133         if (IS_ERR(inode))
134                 RETURN(ERR_CAST(inode));
135
136         if (is_bad_inode(inode)) {
137                 /* we didn't find the right inode.. */
138                 iput(inode);
139                 RETURN(ERR_PTR(-ESTALE));
140         }
141
142         /* Both LU_DOT_LUSTRE_FID and LU_OBF_FID are special fids that
143          * don't match to a real searchable file, so they need special
144          * handling.
145          */
146         if (is_dot_lustre || fid_is_obf(fid)) {
147                 struct qstr dot_name = QSTR_INIT(".lustre",
148                                                  strlen(".lustre"));
149                 struct dentry *dot, *obf;
150
151                 inode_lock(d_inode(sb->s_root));
152                 dot = d_lookup(sb->s_root, &dot_name);
153                 if (!dot) {
154                         struct inode *tmp = inode;
155
156                         dot = d_alloc(sb->s_root, &dot_name);
157                         if (!dot) {
158                                 inode_unlock(d_inode(sb->s_root));
159                                 iput(inode);
160                                 RETURN(ERR_PTR(-ENOMEM));
161                         }
162
163                         if (!ll_d_setup(dot, true)) {
164                                 inode_unlock(d_inode(sb->s_root));
165                                 obf = ERR_PTR(-ENOMEM);
166                                 goto free_dot;
167                         }
168
169                         /* We are requesting OBF fid then locate inode of
170                          * .lustre FID
171                          */
172                         if (!is_dot_lustre) {
173                                 tmp = search_inode_for_lustre(sb,
174                                                               &LU_DOT_LUSTRE_FID);
175                                 if (IS_ERR(tmp)) {
176                                         inode_unlock(d_inode(sb->s_root));
177                                         obf = ERR_CAST(tmp);
178                                         goto free_dot;
179                                 }
180                         }
181                         /* Successfully add .lustre dentry to dcache. For future
182                          * failures for the obf case we don't need to iput the
183                          * .lustre inode.
184                          */
185                         d_add(dot, tmp);
186                 }
187                 inode_unlock(d_inode(sb->s_root));
188
189                 if (!is_dot_lustre) {
190                         struct qstr obf_name = QSTR_INIT("fid", strlen("fid"));
191
192                         inode_lock(d_inode(dot));
193                         obf = d_lookup(dot, &obf_name);
194                         if (!obf) {
195                                 obf = d_alloc(dot, &obf_name);
196                                 if (!obf) {
197                                         inode_unlock(d_inode(dot));
198                                         obf = ERR_PTR(-ENOMEM);
199                                         goto free_dot;
200                                 }
201
202                                 if (!ll_d_setup(obf, true)) {
203                                         dput(obf);
204                                         inode_unlock(d_inode(dot));
205                                         obf = ERR_PTR(-ENOMEM);
206                                         goto free_dot;
207                                 }
208                                 d_add(obf, inode);
209                         }
210                         inode_unlock(d_inode(dot));
211 free_dot:
212                         if (IS_ERR(obf))
213                                 iput(inode);
214                         dput(dot);
215                         result = obf;
216                 } else {
217                         result = dot;
218                 }
219                 RETURN(result);
220         }
221
222         /* N.B. d_obtain_alias() drops inode ref on error */
223         result = d_obtain_alias(inode);
224         if (IS_ERR(result))
225                 RETURN(result);
226
227         if (!ll_d_setup(result, true))
228                 RETURN(ERR_PTR(-ENOMEM));
229
230 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)
231         /* If we are called by nfsd kthread set lli_open_thrsh_count
232          * to one. This will force caching the open lock. To be
233          * removed once oldest supported Linux kernel is 5.5
234          */
235         if ((current->flags & PF_KTHREAD) &&
236             strcmp(current->comm, "nfsd") == 0) {
237                 struct ll_inode_info *lli = ll_i2info(inode);
238
239                 lli->lli_open_thrsh_count = 1;
240         }
241 #endif
242         RETURN(result);
243 }
244
245 #ifndef FILEID_INVALID
246 #define FILEID_INVALID 0xff
247 #endif
248 #ifndef FILEID_LUSTRE
249 #define FILEID_LUSTRE  0x97
250 #endif
251
252 /**
253  * \a connectable - is nfsd will connect himself or this should be done
254  *                  at lustre
255  *
256  * The return value is file handle type:
257  * 1 -- contains child file handle;
258  * 2 -- contains child file handle and parent file handle;
259  * 255 -- error.
260  */
261 static int ll_encode_fh(struct inode *inode, u32 *fh, int *plen,
262                         struct inode *parent)
263 {
264         int fileid_len = sizeof(struct lustre_file_handle) / 4;
265         struct lustre_file_handle *lfh = (void *)fh;
266
267         ENTRY;
268
269         CDEBUG(D_INFO, "%s: encoding for ("DFID") maxlen=%d minlen=%d\n",
270                ll_i2sbi(inode)->ll_fsname,
271                PFID(ll_inode2fid(inode)), *plen, fileid_len);
272
273         if (*plen < fileid_len) {
274                 *plen = fileid_len;
275                 RETURN(FILEID_INVALID);
276         }
277
278         lfh->lfh_child = *ll_inode2fid(inode);
279         if (parent)
280                 lfh->lfh_parent = *ll_inode2fid(parent);
281         else
282                 fid_zero(&lfh->lfh_parent);
283         *plen = fileid_len;
284
285         RETURN(FILEID_LUSTRE);
286 }
287
288 static inline int
289 do_nfs_get_name_filldir(struct ll_getname_data *lgd, const char *name,
290                         int namelen, loff_t hash, u64 ino, unsigned int type)
291 {
292         /*
293          * It is hack to access lde_fid for comparison with lgd_fid.
294          * So the input 'name' must be part of the 'lu_dirent', and
295          * so must appear to be a non-const pointer to an empty array.
296          */
297         char (*n)[0] = (void *)name;
298         /* NOTE: This should be container_of().  However container_of() in
299          * kernels earlier than v4.13-rc1~37^2~94 cause this to generate a
300          * warning, which fails when we compile with -Werror.  Those earlier
301          * kernels don't have container_of_safe, calling that instead will use
302          * the lustre-local version which doesn't generate the warning.
303          */
304         struct lu_dirent *lde = container_of_safe(n, struct lu_dirent, lde_name);
305         struct lu_fid fid;
306
307         fid_le_to_cpu(&fid, &lde->lde_fid);
308         if (lu_fid_eq(&fid, &lgd->lgd_fid)) {
309                 memcpy(lgd->lgd_name, name, namelen);
310                 lgd->lgd_name[namelen] = 0;
311                 lgd->lgd_found = 1;
312         }
313         return lgd->lgd_found;
314 }
315
316 #ifdef HAVE_FILLDIR_USE_CTX_RETURN_BOOL
317 static bool
318 ll_nfs_get_name_filldir(struct dir_context *ctx, const char *name, int namelen,
319                         loff_t hash, u64 ino, unsigned int type)
320 {
321         struct ll_getname_data *lgd =
322                 container_of(ctx, struct ll_getname_data, ctx);
323         int err = do_nfs_get_name_filldir(lgd, name, namelen, hash, ino, type);
324
325         return err == 0;
326 }
327 #elif defined(HAVE_FILLDIR_USE_CTX)
328 static int
329 ll_nfs_get_name_filldir(struct dir_context *ctx, const char *name, int namelen,
330                         loff_t hash, u64 ino, unsigned int type)
331 {
332         struct ll_getname_data *lgd =
333                 container_of(ctx, struct ll_getname_data, ctx);
334
335         return do_nfs_get_name_filldir(lgd, name, namelen, hash, ino, type);
336 }
337 #else
338 static int ll_nfs_get_name_filldir(void *cookie, const char *name, int namelen,
339                                    loff_t hash, u64 ino, unsigned int type)
340 {
341         struct ll_getname_data *lgd = cookie;
342
343         return do_nfs_get_name_filldir(lgd, name, namelen, hash, ino, type);
344 }
345 #endif /* HAVE_FILLDIR_USE_CTX */
346
347 static int ll_get_name(struct dentry *dentry, char *name, struct dentry *child)
348 {
349         struct inode *dir = dentry->d_inode;
350         struct ll_getname_data lgd = {
351                 .lgd_name = name,
352                 .lgd_fid = ll_i2info(child->d_inode)->lli_fid,
353 #ifdef HAVE_DIR_CONTEXT
354                 .ctx.actor = (filldir_t)ll_nfs_get_name_filldir,
355 #endif
356                 .lgd_found = 0,
357         };
358         struct md_op_data *op_data;
359         u64 pos = 0;
360         int rc;
361
362         ENTRY;
363
364         if (!dir || !S_ISDIR(dir->i_mode))
365                 GOTO(out, rc = -ENOTDIR);
366
367         if (!dir->i_fop)
368                 GOTO(out, rc = -EINVAL);
369
370         op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
371                                      LUSTRE_OPC_ANY, dir);
372         if (IS_ERR(op_data))
373                 GOTO(out, rc = PTR_ERR(op_data));
374
375         ll_inode_lock(dir);
376 #ifdef HAVE_DIR_CONTEXT
377         rc = ll_dir_read(dir, &pos, op_data, &lgd.ctx, NULL);
378 #else
379         rc = ll_dir_read(dir, &pos, op_data, &lgd, ll_nfs_get_name_filldir,
380                          NULL);
381 #endif
382         ll_inode_unlock(dir);
383         ll_finish_md_op_data(op_data);
384         if (!rc && !lgd.lgd_found)
385                 rc = -ENOENT;
386         EXIT;
387 out:
388         return rc;
389 }
390
391 static struct dentry *ll_fh_to_dentry(struct super_block *sb, struct fid *fid,
392                                       int fh_len, int fh_type)
393 {
394         struct lustre_file_handle *lfh = (struct lustre_file_handle *)fid;
395
396         if (fh_type != FILEID_LUSTRE)
397                 RETURN(ERR_PTR(-EPROTO));
398
399         RETURN(ll_iget_for_nfs(sb, &lfh->lfh_child, &lfh->lfh_parent));
400 }
401
402 static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
403                                       int fh_len, int fh_type)
404 {
405         struct lustre_file_handle *lfh = (struct lustre_file_handle *)fid;
406
407         if (fh_type != FILEID_LUSTRE)
408                 RETURN(ERR_PTR(-EPROTO));
409
410         RETURN(ll_iget_for_nfs(sb, &lfh->lfh_parent, NULL));
411 }
412
413 int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid)
414 {
415         struct ptlrpc_request   *req = NULL;
416         struct ll_sb_info       *sbi;
417         struct mdt_body         *body;
418         static const char       dotdot[] = "..";
419         struct md_op_data       *op_data;
420         int                     rc;
421         int                     lmmsize;
422
423         ENTRY;
424
425         LASSERT(dir && S_ISDIR(dir->i_mode));
426
427         sbi = ll_s2sbi(dir->i_sb);
428
429         CDEBUG(D_INFO, "%s: getting parent for ("DFID")\n",
430                sbi->ll_fsname, PFID(ll_inode2fid(dir)));
431
432         rc = ll_get_default_mdsize(sbi, &lmmsize);
433         if (rc != 0)
434                 RETURN(rc);
435
436         op_data = ll_prep_md_op_data(NULL, dir, NULL, dotdot,
437                                      strlen(dotdot), lmmsize,
438                                      LUSTRE_OPC_ANY, NULL);
439         if (IS_ERR(op_data))
440                 RETURN(PTR_ERR(op_data));
441
442         rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
443         ll_finish_md_op_data(op_data);
444         if (rc != 0) {
445                 CERROR("%s: failure inode "DFID" get parent: rc = %d\n",
446                        sbi->ll_fsname, PFID(ll_inode2fid(dir)), rc);
447                 RETURN(rc);
448         }
449         body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
450
451         /*
452          * LU-3952: MDT may lost the FID of its parent, we should not crash
453          * the NFS server, ll_iget_for_nfs() will handle the error.
454          */
455         if (body->mbo_valid & OBD_MD_FLID) {
456                 CDEBUG(D_INFO, "parent for "DFID" is "DFID"\n",
457                        PFID(ll_inode2fid(dir)), PFID(&body->mbo_fid1));
458                 *parent_fid = body->mbo_fid1;
459         }
460
461         ptlrpc_req_finished(req);
462         RETURN(0);
463 }
464
465 static struct dentry *ll_get_parent(struct dentry *dchild)
466 {
467         struct lu_fid parent_fid = { 0 };
468         int rc;
469         struct dentry *dentry;
470
471         ENTRY;
472
473         rc = ll_dir_get_parent_fid(dchild->d_inode, &parent_fid);
474         if (rc != 0)
475                 RETURN(ERR_PTR(rc));
476
477         dentry = ll_iget_for_nfs(dchild->d_inode->i_sb, &parent_fid, NULL);
478
479         RETURN(dentry);
480 }
481
482 const struct export_operations lustre_export_operations = {
483         .get_parent = ll_get_parent,
484         .encode_fh  = ll_encode_fh,
485         .get_name   = ll_get_name,
486         .fh_to_dentry = ll_fh_to_dentry,
487         .fh_to_parent = ll_fh_to_parent,
488 };