1 /*
2    Copyright 2017 Skytechnology sp. z o.o.
3 
4    This file is part of LizardFS.
5 
6    LizardFS is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, version 3.
9 
10    LizardFS is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with LizardFS. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "fsal.h"
20 #include "fsal_convert.h"
21 #include "pnfs_utils.h"
22 
23 #include "lzfs_internal.h"
24 
lizardfs2fsal_error(int ec)25 fsal_status_t lizardfs2fsal_error(int ec) {
26 	fsal_status_t status;
27 
28 	if (!ec) {
29 		LogWarn(COMPONENT_FSAL, "appropriate errno not set");
30 		ec = EINVAL;
31 	}
32 
33 	status.minor = ec;
34 	status.major = posix2fsal_error(liz_error_conv(ec));
35 
36 	return status;
37 }
38 
lizardfs2nfs4_error(int ec)39 nfsstat4 lizardfs2nfs4_error(int ec) {
40 	if (!ec) {
41 		LogWarn(COMPONENT_FSAL, "appropriate errno not set");
42 		ec = EINVAL;
43 	}
44 	return posix2nfs4_error(liz_error_conv(ec));
45 }
46 
lzfs_fsal_last_err()47 fsal_status_t lzfs_fsal_last_err() {
48 	return lizardfs2fsal_error(liz_last_err());
49 }
50 
lzfs_nfs4_last_err()51 nfsstat4 lzfs_nfs4_last_err() {
52 	return lizardfs2nfs4_error(liz_last_err());
53 }
54 
lzfs_fsal_create_context(liz_t * instance,struct user_cred * cred)55 liz_context_t *lzfs_fsal_create_context(liz_t *instance, struct user_cred *cred) {
56 	static const int kLocalGArraySize = 64;
57 
58 	if (cred == NULL) {
59 		liz_context_t *ctx = liz_create_user_context(0, 0, 0, 0);
60 		return ctx;
61 	}
62 
63 	liz_context_t *ctx;
64 	uid_t uid = (cred->caller_uid == op_ctx->export_perms->anonymous_uid) ? 0 : cred->caller_uid;
65 	gid_t gid = (cred->caller_gid == op_ctx->export_perms->anonymous_gid) ? 0 : cred->caller_gid;
66 
67 	ctx = liz_create_user_context(uid, gid, 0, 0);
68 	if (!ctx) {
69 		return NULL;
70 	}
71 
72 	if (cred->caller_glen > 0) {
73 		if (cred->caller_glen > kLocalGArraySize) {
74 			gid_t *garray = malloc((cred->caller_glen + 1) * sizeof(gid_t));
75 			if (garray != NULL) {
76 				garray[0] = gid;
77 				memcpy(garray + 1, cred->caller_garray, sizeof(gid_t) * cred->caller_glen);
78 				liz_update_groups(instance, ctx, garray, cred->caller_glen + 1);
79 				free(garray);
80 				return ctx;
81 			}
82 		}
83 
84 		gid_t garray[kLocalGArraySize + 1];
85 		garray[0] = gid;
86 		int count = MIN(cred->caller_glen, kLocalGArraySize);
87 		memcpy(garray + 1, cred->caller_garray, sizeof(gid_t) * count);
88 		liz_update_groups(instance, ctx, garray, count + 1);
89 	}
90 
91 	return ctx;
92 }
93 
lzfs_fsal_staticinfo(struct fsal_module * module_hdl)94 fsal_staticfsinfo_t *lzfs_fsal_staticinfo(struct fsal_module *module_hdl) {
95 	struct lzfs_fsal_module *lzfs_module = container_of(module_hdl, struct lzfs_fsal_module, fsal);
96 	return &lzfs_module->fs_info;
97 }
98 
lzfs_fsal_new_handle(const struct stat * attr,struct lzfs_fsal_export * lzfs_export)99 struct lzfs_fsal_handle *lzfs_fsal_new_handle(const struct stat *attr,
100                                               struct lzfs_fsal_export *lzfs_export) {
101 	struct lzfs_fsal_handle *result = NULL;
102 
103 	result = gsh_calloc(1, sizeof(struct lzfs_fsal_handle));
104 
105 	result->inode = attr->st_ino;
106 	result->unique_key.module_id = FSAL_ID_EXPERIMENTAL;
107 	result->unique_key.export_id = lzfs_export->export.export_id;
108 	result->unique_key.inode = attr->st_ino;
109 
110 	fsal_obj_handle_init(&result->handle, &lzfs_export->export, posix2fsal_type(attr->st_mode));
111 	lzfs_fsal_handle_ops_init(lzfs_export, &result->handle.obj_ops);
112 	result->handle.fsid = posix2fsal_fsid(attr->st_dev);
113 	result->handle.fileid = attr->st_ino;
114 	result->export = lzfs_export;
115 
116 	return result;
117 }
118 
lzfs_fsal_delete_handle(struct lzfs_fsal_handle * obj)119 void lzfs_fsal_delete_handle(struct lzfs_fsal_handle *obj) {
120 	fsal_obj_handle_fini(&obj->handle);
121 	gsh_free(obj);
122 }
123