blob: cd512a3a9c528f0ccf13e811113408a3611ac721 [file] [log] [blame]
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6#include "protocol.h"
Mike Marshall575e9462015-12-04 12:56:14 -05007#include "orangefs-kernel.h"
8#include "orangefs-dev-proto.h"
9#include "orangefs-bufmap.h"
Mike Marshallf7be4ee2015-07-17 10:38:14 -040010
Yi Liu8bb8aef2015-11-24 15:12:14 -050011__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040012{
Yi Liu8bb8aef2015-11-24 15:12:14 -050013 __s32 fsid = ORANGEFS_FS_ID_NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040014
15 if (op) {
16 switch (op->upcall.type) {
Yi Liu8bb8aef2015-11-24 15:12:14 -050017 case ORANGEFS_VFS_OP_FILE_IO:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040018 fsid = op->upcall.req.io.refn.fs_id;
19 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050020 case ORANGEFS_VFS_OP_LOOKUP:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040021 fsid = op->upcall.req.lookup.parent_refn.fs_id;
22 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050023 case ORANGEFS_VFS_OP_CREATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040024 fsid = op->upcall.req.create.parent_refn.fs_id;
25 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050026 case ORANGEFS_VFS_OP_GETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040027 fsid = op->upcall.req.getattr.refn.fs_id;
28 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050029 case ORANGEFS_VFS_OP_REMOVE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040030 fsid = op->upcall.req.remove.parent_refn.fs_id;
31 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050032 case ORANGEFS_VFS_OP_MKDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040033 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
34 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050035 case ORANGEFS_VFS_OP_READDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040036 fsid = op->upcall.req.readdir.refn.fs_id;
37 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050038 case ORANGEFS_VFS_OP_SETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040039 fsid = op->upcall.req.setattr.refn.fs_id;
40 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050041 case ORANGEFS_VFS_OP_SYMLINK:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040042 fsid = op->upcall.req.sym.parent_refn.fs_id;
43 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050044 case ORANGEFS_VFS_OP_RENAME:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040045 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
46 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050047 case ORANGEFS_VFS_OP_STATFS:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040048 fsid = op->upcall.req.statfs.fs_id;
49 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050050 case ORANGEFS_VFS_OP_TRUNCATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040051 fsid = op->upcall.req.truncate.refn.fs_id;
52 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050053 case ORANGEFS_VFS_OP_MMAP_RA_FLUSH:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040054 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
55 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050056 case ORANGEFS_VFS_OP_FS_UMOUNT:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040057 fsid = op->upcall.req.fs_umount.fs_id;
58 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050059 case ORANGEFS_VFS_OP_GETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040060 fsid = op->upcall.req.getxattr.refn.fs_id;
61 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050062 case ORANGEFS_VFS_OP_SETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040063 fsid = op->upcall.req.setxattr.refn.fs_id;
64 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050065 case ORANGEFS_VFS_OP_LISTXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040066 fsid = op->upcall.req.listxattr.refn.fs_id;
67 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050068 case ORANGEFS_VFS_OP_REMOVEXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040069 fsid = op->upcall.req.removexattr.refn.fs_id;
70 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050071 case ORANGEFS_VFS_OP_FSYNC:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040072 fsid = op->upcall.req.fsync.refn.fs_id;
73 break;
74 default:
75 break;
76 }
77 }
78 return fsid;
79}
80
Martin Brandenburg394f6472016-01-25 15:33:39 -050081static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040082{
Martin Brandenburg394f6472016-01-25 15:33:39 -050083 int flags = 0;
Yi Liu8bb8aef2015-11-24 15:12:14 -050084 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050085 flags |= S_IMMUTABLE;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040086 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050087 flags &= ~S_IMMUTABLE;
Yi Liu8bb8aef2015-11-24 15:12:14 -050088 if (attrs->flags & ORANGEFS_APPEND_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050089 flags |= S_APPEND;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040090 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050091 flags &= ~S_APPEND;
Yi Liu8bb8aef2015-11-24 15:12:14 -050092 if (attrs->flags & ORANGEFS_NOATIME_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050093 flags |= S_NOATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040094 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050095 flags &= ~S_NOATIME;
96 return flags;
97}
Mike Marshallf7be4ee2015-07-17 10:38:14 -040098
Martin Brandenburg394f6472016-01-25 15:33:39 -050099static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs)
100{
101 int perm_mode = 0;
102
103 if (attrs->perms & ORANGEFS_O_EXECUTE)
104 perm_mode |= S_IXOTH;
105 if (attrs->perms & ORANGEFS_O_WRITE)
106 perm_mode |= S_IWOTH;
107 if (attrs->perms & ORANGEFS_O_READ)
108 perm_mode |= S_IROTH;
109
110 if (attrs->perms & ORANGEFS_G_EXECUTE)
111 perm_mode |= S_IXGRP;
112 if (attrs->perms & ORANGEFS_G_WRITE)
113 perm_mode |= S_IWGRP;
114 if (attrs->perms & ORANGEFS_G_READ)
115 perm_mode |= S_IRGRP;
116
117 if (attrs->perms & ORANGEFS_U_EXECUTE)
118 perm_mode |= S_IXUSR;
119 if (attrs->perms & ORANGEFS_U_WRITE)
120 perm_mode |= S_IWUSR;
121 if (attrs->perms & ORANGEFS_U_READ)
122 perm_mode |= S_IRUSR;
123
124 if (attrs->perms & ORANGEFS_G_SGID)
125 perm_mode |= S_ISGID;
126 if (attrs->perms & ORANGEFS_U_SUID)
127 perm_mode |= S_ISUID;
128
129 return perm_mode;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400130}
131
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400132/*
133 * NOTE: in kernel land, we never use the sys_attr->link_target for
134 * anything, so don't bother copying it into the sys_attr object here.
135 */
136static inline int copy_attributes_from_inode(struct inode *inode,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500137 struct ORANGEFS_sys_attr_s *attrs,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400138 struct iattr *iattr)
139{
140 umode_t tmp_mode;
141
142 if (!iattr || !inode || !attrs) {
143 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
144 "in copy_attributes_from_inode!\n",
145 iattr,
146 inode,
147 attrs);
148 return -EINVAL;
149 }
150 /*
151 * We need to be careful to only copy the attributes out of the
152 * iattr object that we know are valid.
153 */
154 attrs->mask = 0;
155 if (iattr->ia_valid & ATTR_UID) {
Jann Horn78fee0b2016-06-25 01:51:52 +0200156 attrs->owner = from_kuid(&init_user_ns, iattr->ia_uid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500157 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400158 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
159 }
160 if (iattr->ia_valid & ATTR_GID) {
Jann Horn78fee0b2016-06-25 01:51:52 +0200161 attrs->group = from_kgid(&init_user_ns, iattr->ia_gid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500162 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400163 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
164 }
165
166 if (iattr->ia_valid & ATTR_ATIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500167 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400168 if (iattr->ia_valid & ATTR_ATIME_SET) {
Arnd Bergmannbe81ce42016-02-26 13:54:10 +0100169 attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500170 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400171 }
172 }
173 if (iattr->ia_valid & ATTR_MTIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500174 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400175 if (iattr->ia_valid & ATTR_MTIME_SET) {
Arnd Bergmannbe81ce42016-02-26 13:54:10 +0100176 attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500177 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400178 }
179 }
180 if (iattr->ia_valid & ATTR_CTIME)
Yi Liu8bb8aef2015-11-24 15:12:14 -0500181 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400182
183 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500184 * ORANGEFS cannot set size with a setattr operation. Probably not likely
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400185 * to be requested through the VFS, but just in case, don't worry about
186 * ATTR_SIZE
187 */
188
189 if (iattr->ia_valid & ATTR_MODE) {
190 tmp_mode = iattr->ia_mode;
191 if (tmp_mode & (S_ISVTX)) {
192 if (is_root_handle(inode)) {
193 /*
194 * allow sticky bit to be set on root (since
195 * it shows up that way by default anyhow),
196 * but don't show it to the server
197 */
198 tmp_mode -= S_ISVTX;
199 } else {
200 gossip_debug(GOSSIP_UTILS_DEBUG,
201 "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
202 return -EINVAL;
203 }
204 }
205
206 if (tmp_mode & (S_ISUID)) {
207 gossip_debug(GOSSIP_UTILS_DEBUG,
208 "Attempting to set setuid bit (not supported); returning EINVAL.\n");
209 return -EINVAL;
210 }
211
Yi Liu8bb8aef2015-11-24 15:12:14 -0500212 attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
213 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400214 }
215
216 return 0;
217}
218
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400219static int orangefs_inode_type(enum orangefs_ds_type objtype)
220{
221 if (objtype == ORANGEFS_TYPE_METAFILE)
222 return S_IFREG;
223 else if (objtype == ORANGEFS_TYPE_DIRECTORY)
224 return S_IFDIR;
225 else if (objtype == ORANGEFS_TYPE_SYMLINK)
226 return S_IFLNK;
227 else
228 return -1;
229}
230
Martin Brandenburg26662632016-03-17 16:01:52 -0400231static int orangefs_inode_is_stale(struct inode *inode, int new,
232 struct ORANGEFS_sys_attr_s *attrs, char *link_target)
233{
234 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
235 int type = orangefs_inode_type(attrs->objtype);
236 if (!new) {
237 /*
238 * If the inode type or symlink target have changed then this
239 * inode is stale.
240 */
241 if (type == -1 || !(inode->i_mode & type)) {
242 orangefs_make_bad_inode(inode);
243 return 1;
244 }
245 if (type == S_IFLNK && strncmp(orangefs_inode->link_target,
246 link_target, ORANGEFS_NAME_MAX)) {
247 orangefs_make_bad_inode(inode);
248 return 1;
249 }
250 }
251 return 0;
252}
253
Martin Brandenburg71680c12016-06-09 16:32:38 -0400254int orangefs_inode_getattr(struct inode *inode, int new, int bypass)
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400255{
256 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
257 struct orangefs_kernel_op_s *new_op;
258 loff_t inode_size, rounded_up_size;
Martin Brandenburg26662632016-03-17 16:01:52 -0400259 int ret, type;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400260
261 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
262 get_khandle_from_ino(inode));
263
Martin Brandenburg71680c12016-06-09 16:32:38 -0400264 if (!new && !bypass) {
265 if (orangefs_inode->getattr_time > jiffies)
266 return 0;
267 }
268
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400269 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
270 if (!new_op)
271 return -ENOMEM;
272 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
Martin Brandenburg71680c12016-06-09 16:32:38 -0400273 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400274
275 ret = service_operation(new_op, __func__,
276 get_interruptible_flag(inode));
277 if (ret != 0)
278 goto out;
279
Martin Brandenburg26662632016-03-17 16:01:52 -0400280 type = orangefs_inode_type(new_op->
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400281 downcall.resp.getattr.attributes.objtype);
Martin Brandenburg26662632016-03-17 16:01:52 -0400282 ret = orangefs_inode_is_stale(inode, new,
283 &new_op->downcall.resp.getattr.attributes,
284 new_op->downcall.resp.getattr.link_target);
285 if (ret) {
286 ret = -ESTALE;
287 goto out;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400288 }
289
Martin Brandenburg26662632016-03-17 16:01:52 -0400290 switch (type) {
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400291 case S_IFREG:
292 inode->i_flags = orangefs_inode_flags(&new_op->
293 downcall.resp.getattr.attributes);
Martin Brandenburg71680c12016-06-09 16:32:38 -0400294 inode_size = (loff_t)new_op->
295 downcall.resp.getattr.attributes.size;
296 rounded_up_size =
297 (inode_size + (4096 - (inode_size % 4096)));
298 inode->i_size = inode_size;
299 orangefs_inode->blksize =
300 new_op->downcall.resp.getattr.attributes.blksize;
301 spin_lock(&inode->i_lock);
302 inode->i_bytes = inode_size;
303 inode->i_blocks =
304 (unsigned long)(rounded_up_size / 512);
305 spin_unlock(&inode->i_lock);
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400306 break;
307 case S_IFDIR:
Kirill A. Shutemov09cbfea2016-04-01 15:29:47 +0300308 inode->i_size = PAGE_SIZE;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400309 orangefs_inode->blksize = (1 << inode->i_blkbits);
310 spin_lock(&inode->i_lock);
311 inode_set_bytes(inode, inode->i_size);
312 spin_unlock(&inode->i_lock);
313 set_nlink(inode, 1);
314 break;
315 case S_IFLNK:
316 if (new) {
317 inode->i_size = (loff_t)strlen(new_op->
318 downcall.resp.getattr.link_target);
319 orangefs_inode->blksize = (1 << inode->i_blkbits);
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400320 ret = strscpy(orangefs_inode->link_target,
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400321 new_op->downcall.resp.getattr.link_target,
322 ORANGEFS_NAME_MAX);
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400323 if (ret == -E2BIG) {
324 ret = -EIO;
325 goto out;
326 }
Martin Brandenburge8da2542016-03-18 14:20:15 -0400327 inode->i_link = orangefs_inode->link_target;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400328 }
329 break;
330 }
331
332 inode->i_uid = make_kuid(&init_user_ns, new_op->
333 downcall.resp.getattr.attributes.owner);
334 inode->i_gid = make_kgid(&init_user_ns, new_op->
335 downcall.resp.getattr.attributes.group);
336 inode->i_atime.tv_sec = (time64_t)new_op->
337 downcall.resp.getattr.attributes.atime;
338 inode->i_mtime.tv_sec = (time64_t)new_op->
339 downcall.resp.getattr.attributes.mtime;
340 inode->i_ctime.tv_sec = (time64_t)new_op->
341 downcall.resp.getattr.attributes.ctime;
342 inode->i_atime.tv_nsec = 0;
343 inode->i_mtime.tv_nsec = 0;
344 inode->i_ctime.tv_nsec = 0;
345
346 /* special case: mark the root inode as sticky */
Martin Brandenburg26662632016-03-17 16:01:52 -0400347 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400348 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
349
Martin Brandenburg4cd8f312016-07-25 13:58:24 -0400350 orangefs_inode->getattr_time = jiffies + getattr_timeout_msecs*HZ/1000;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400351 ret = 0;
352out:
353 op_release(new_op);
354 return ret;
355}
356
Martin Brandenburg5859d772016-03-17 15:15:16 -0400357int orangefs_inode_check_changed(struct inode *inode)
358{
359 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
360 struct orangefs_kernel_op_s *new_op;
361 int ret;
362
363 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
364 get_khandle_from_ino(inode));
365
366 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
367 if (!new_op)
368 return -ENOMEM;
369 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
370 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
371 ORANGEFS_ATTR_SYS_LNK_TARGET;
372
373 ret = service_operation(new_op, __func__,
374 get_interruptible_flag(inode));
375 if (ret != 0)
376 goto out;
377
Martin Brandenburg26662632016-03-17 16:01:52 -0400378 ret = orangefs_inode_is_stale(inode, 0,
379 &new_op->downcall.resp.getattr.attributes,
380 new_op->downcall.resp.getattr.link_target);
Martin Brandenburg5859d772016-03-17 15:15:16 -0400381out:
382 op_release(new_op);
383 return ret;
384}
385
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400386/*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500387 * issues a orangefs setattr request to make sure the new attribute values
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400388 * take effect if successful. returns 0 on success; -errno otherwise
389 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500390int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400391{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500392 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
393 struct orangefs_kernel_op_s *new_op;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400394 int ret;
395
Yi Liu8bb8aef2015-11-24 15:12:14 -0500396 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400397 if (!new_op)
398 return -ENOMEM;
399
Yi Liu8bb8aef2015-11-24 15:12:14 -0500400 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400401 ret = copy_attributes_from_inode(inode,
402 &new_op->upcall.req.setattr.attributes,
403 iattr);
Al Viroed42fe02016-01-22 19:47:47 -0500404 if (ret >= 0) {
405 ret = service_operation(new_op, __func__,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400406 get_interruptible_flag(inode));
407
Al Viroed42fe02016-01-22 19:47:47 -0500408 gossip_debug(GOSSIP_UTILS_DEBUG,
409 "orangefs_inode_setattr: returning %d\n",
410 ret);
411 }
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400412
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400413 op_release(new_op);
414
415 /*
416 * successful setattr should clear the atime, mtime and
417 * ctime flags.
418 */
419 if (ret == 0) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500420 ClearAtimeFlag(orangefs_inode);
421 ClearMtimeFlag(orangefs_inode);
422 ClearCtimeFlag(orangefs_inode);
423 ClearModeFlag(orangefs_inode);
Martin Brandenburg71680c12016-06-09 16:32:38 -0400424 orangefs_inode->getattr_time = 0;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400425 }
426
427 return ret;
428}
429
Yi Liu8bb8aef2015-11-24 15:12:14 -0500430int orangefs_flush_inode(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400431{
432 /*
433 * If it is a dirty inode, this function gets called.
434 * Gather all the information that needs to be setattr'ed
435 * Right now, this will only be used for mode, atime, mtime
436 * and/or ctime.
437 */
438 struct iattr wbattr;
439 int ret;
440 int mtime_flag;
441 int ctime_flag;
442 int atime_flag;
443 int mode_flag;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500444 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400445
446 memset(&wbattr, 0, sizeof(wbattr));
447
448 /*
449 * check inode flags up front, and clear them if they are set. This
450 * will prevent multiple processes from all trying to flush the same
451 * inode if they call close() simultaneously
452 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500453 mtime_flag = MtimeFlag(orangefs_inode);
454 ClearMtimeFlag(orangefs_inode);
455 ctime_flag = CtimeFlag(orangefs_inode);
456 ClearCtimeFlag(orangefs_inode);
457 atime_flag = AtimeFlag(orangefs_inode);
458 ClearAtimeFlag(orangefs_inode);
459 mode_flag = ModeFlag(orangefs_inode);
460 ClearModeFlag(orangefs_inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400461
462 /* -- Lazy atime,mtime and ctime update --
463 * Note: all times are dictated by server in the new scheme
464 * and not by the clients
465 *
466 * Also mode updates are being handled now..
467 */
468
469 if (mtime_flag)
470 wbattr.ia_valid |= ATTR_MTIME;
471 if (ctime_flag)
472 wbattr.ia_valid |= ATTR_CTIME;
473 if (atime_flag)
474 wbattr.ia_valid |= ATTR_ATIME;
475
476 if (mode_flag) {
477 wbattr.ia_mode = inode->i_mode;
478 wbattr.ia_valid |= ATTR_MODE;
479 }
480
481 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500482 "*********** orangefs_flush_inode: %pU "
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400483 "(ia_valid %d)\n",
484 get_khandle_from_ino(inode),
485 wbattr.ia_valid);
486 if (wbattr.ia_valid == 0) {
487 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500488 "orangefs_flush_inode skipping setattr()\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400489 return 0;
490 }
491
492 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500493 "orangefs_flush_inode (%pU) writing mode %o\n",
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400494 get_khandle_from_ino(inode),
495 inode->i_mode);
496
Yi Liu8bb8aef2015-11-24 15:12:14 -0500497 ret = orangefs_inode_setattr(inode, &wbattr);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400498
499 return ret;
500}
501
Yi Liu8bb8aef2015-11-24 15:12:14 -0500502int orangefs_unmount_sb(struct super_block *sb)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400503{
504 int ret = -EINVAL;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500505 struct orangefs_kernel_op_s *new_op = NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400506
507 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500508 "orangefs_unmount_sb called on sb %p\n",
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400509 sb);
510
Yi Liu8bb8aef2015-11-24 15:12:14 -0500511 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400512 if (!new_op)
513 return -ENOMEM;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500514 new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id;
515 new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id;
516 strncpy(new_op->upcall.req.fs_umount.orangefs_config_server,
517 ORANGEFS_SB(sb)->devname,
518 ORANGEFS_MAX_SERVER_ADDR_LEN);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400519
520 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500521 "Attempting ORANGEFS Unmount via host %s\n",
522 new_op->upcall.req.fs_umount.orangefs_config_server);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400523
Yi Liu8bb8aef2015-11-24 15:12:14 -0500524 ret = service_operation(new_op, "orangefs_fs_umount", 0);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400525
526 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500527 "orangefs_unmount: got return value of %d\n", ret);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400528 if (ret)
529 sb = ERR_PTR(ret);
530 else
Yi Liu8bb8aef2015-11-24 15:12:14 -0500531 ORANGEFS_SB(sb)->mount_pending = 1;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400532
533 op_release(new_op);
534 return ret;
535}
536
Yi Liu8bb8aef2015-11-24 15:12:14 -0500537void orangefs_make_bad_inode(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400538{
539 if (is_root_handle(inode)) {
540 /*
541 * if this occurs, the pvfs2-client-core was killed but we
542 * can't afford to lose the inode operations and such
543 * associated with the root handle in any case.
544 */
545 gossip_debug(GOSSIP_UTILS_DEBUG,
546 "*** NOT making bad root inode %pU\n",
547 get_khandle_from_ino(inode));
548 } else {
549 gossip_debug(GOSSIP_UTILS_DEBUG,
550 "*** making bad inode %pU\n",
551 get_khandle_from_ino(inode));
552 make_bad_inode(inode);
553 }
554}
555
Mike Marshall54804942015-10-05 13:44:24 -0400556/*
557 * The following is a very dirty hack that is now a permanent part of the
Yi Liu8bb8aef2015-11-24 15:12:14 -0500558 * ORANGEFS protocol. See protocol.h for more error definitions.
Mike Marshall54804942015-10-05 13:44:24 -0400559 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400560
Yi Liu8bb8aef2015-11-24 15:12:14 -0500561/* The order matches include/orangefs-types.h in the OrangeFS source. */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400562static int PINT_errno_mapping[] = {
Mike Marshall54804942015-10-05 13:44:24 -0400563 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
564 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
565 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
566 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
567 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
568 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
569 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
570 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
571 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
572 EACCES, ECONNRESET, ERANGE
Martin Brandenburg894ac432015-10-02 12:11:19 -0400573};
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400574
Yi Liu8bb8aef2015-11-24 15:12:14 -0500575int orangefs_normalize_to_errno(__s32 error_code)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400576{
Mike Marshall54804942015-10-05 13:44:24 -0400577 __u32 i;
578
Martin Brandenburg894ac432015-10-02 12:11:19 -0400579 /* Success */
580 if (error_code == 0) {
581 return 0;
Mike Marshall54804942015-10-05 13:44:24 -0400582 /*
583 * This shouldn't ever happen. If it does it should be fixed on the
584 * server.
585 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400586 } else if (error_code > 0) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500587 gossip_err("orangefs: error status receieved.\n");
588 gossip_err("orangefs: assuming error code is inverted.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400589 error_code = -error_code;
590 }
591
Mike Marshall54804942015-10-05 13:44:24 -0400592 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500593 * XXX: This is very bad since error codes from ORANGEFS may not be
Mike Marshall54804942015-10-05 13:44:24 -0400594 * suitable for return into userspace.
595 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400596
Mike Marshall54804942015-10-05 13:44:24 -0400597 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500598 * Convert ORANGEFS error values into errno values suitable for return
Mike Marshall54804942015-10-05 13:44:24 -0400599 * from the kernel.
600 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500601 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
Martin Brandenburg894ac432015-10-02 12:11:19 -0400602 if (((-error_code) &
Yi Liu8bb8aef2015-11-24 15:12:14 -0500603 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
604 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400605 /*
606 * cancellation error codes generally correspond to
607 * a timeout from the client's perspective
608 */
609 error_code = -ETIMEDOUT;
610 } else {
611 /* assume a default error code */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500612 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400613 error_code = -EINVAL;
614 }
Martin Brandenburg894ac432015-10-02 12:11:19 -0400615
Yi Liu8bb8aef2015-11-24 15:12:14 -0500616 /* Convert ORANGEFS encoded errno values into regular errno values. */
617 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
618 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
Mike Marshall54804942015-10-05 13:44:24 -0400619 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
Martin Brandenburg894ac432015-10-02 12:11:19 -0400620 error_code = -PINT_errno_mapping[i];
621 else
622 error_code = -EINVAL;
623
Mike Marshall54804942015-10-05 13:44:24 -0400624 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500625 * Only ORANGEFS protocol error codes should ever come here. Otherwise
Mike Marshall54804942015-10-05 13:44:24 -0400626 * there is a bug somewhere.
627 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400628 } else {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500629 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400630 }
631 return error_code;
632}
633
634#define NUM_MODES 11
Yi Liu8bb8aef2015-11-24 15:12:14 -0500635__s32 ORANGEFS_util_translate_mode(int mode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400636{
637 int ret = 0;
638 int i = 0;
639 static int modes[NUM_MODES] = {
640 S_IXOTH, S_IWOTH, S_IROTH,
641 S_IXGRP, S_IWGRP, S_IRGRP,
642 S_IXUSR, S_IWUSR, S_IRUSR,
643 S_ISGID, S_ISUID
644 };
Yi Liu8bb8aef2015-11-24 15:12:14 -0500645 static int orangefs_modes[NUM_MODES] = {
646 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
647 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
648 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
649 ORANGEFS_G_SGID, ORANGEFS_U_SUID
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400650 };
651
652 for (i = 0; i < NUM_MODES; i++)
653 if (mode & modes[i])
Yi Liu8bb8aef2015-11-24 15:12:14 -0500654 ret |= orangefs_modes[i];
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400655
656 return ret;
657}
658#undef NUM_MODES
659
660/*
661 * After obtaining a string representation of the client's debug
662 * keywords and their associated masks, this function is called to build an
663 * array of these values.
664 */
665int orangefs_prepare_cdm_array(char *debug_array_string)
666{
667 int i;
668 int rc = -EINVAL;
669 char *cds_head = NULL;
670 char *cds_delimiter = NULL;
671 int keyword_len = 0;
672
673 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
674
675 /*
676 * figure out how many elements the cdm_array needs.
677 */
678 for (i = 0; i < strlen(debug_array_string); i++)
679 if (debug_array_string[i] == '\n')
680 cdm_element_count++;
681
682 if (!cdm_element_count) {
683 pr_info("No elements in client debug array string!\n");
684 goto out;
685 }
686
687 cdm_array =
688 kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
689 GFP_KERNEL);
690 if (!cdm_array) {
691 pr_info("malloc failed for cdm_array!\n");
692 rc = -ENOMEM;
693 goto out;
694 }
695
696 cds_head = debug_array_string;
697
698 for (i = 0; i < cdm_element_count; i++) {
699 cds_delimiter = strchr(cds_head, '\n');
700 *cds_delimiter = '\0';
701
702 keyword_len = strcspn(cds_head, " ");
703
704 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
705 if (!cdm_array[i].keyword) {
706 rc = -ENOMEM;
707 goto out;
708 }
709
710 sscanf(cds_head,
711 "%s %llx %llx",
712 cdm_array[i].keyword,
713 (unsigned long long *)&(cdm_array[i].mask1),
714 (unsigned long long *)&(cdm_array[i].mask2));
715
Yi Liu8bb8aef2015-11-24 15:12:14 -0500716 if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE))
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400717 client_verbose_index = i;
718
Yi Liu8bb8aef2015-11-24 15:12:14 -0500719 if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL))
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400720 client_all_index = i;
721
722 cds_head = cds_delimiter + 1;
723 }
724
725 rc = cdm_element_count;
726
727 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
728
729out:
730
731 return rc;
732
733}
734
735/*
736 * /sys/kernel/debug/orangefs/debug-help can be catted to
737 * see all the available kernel and client debug keywords.
738 *
739 * When the kernel boots, we have no idea what keywords the
740 * client supports, nor their associated masks.
741 *
742 * We pass through this function once at boot and stamp a
743 * boilerplate "we don't know" message for the client in the
744 * debug-help file. We pass through here again when the client
745 * starts and then we can fill out the debug-help file fully.
746 *
747 * The client might be restarted any number of times between
748 * reboots, we only build the debug-help file the first time.
749 */
750int orangefs_prepare_debugfs_help_string(int at_boot)
751{
752 int rc = -EINVAL;
753 int i;
754 int byte_count = 0;
755 char *client_title = "Client Debug Keywords:\n";
756 char *kernel_title = "Kernel Debug Keywords:\n";
757
758 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
759
760 if (at_boot) {
761 byte_count += strlen(HELP_STRING_UNINITIALIZED);
762 client_title = HELP_STRING_UNINITIALIZED;
763 } else {
764 /*
765 * fill the client keyword/mask array and remember
766 * how many elements there were.
767 */
768 cdm_element_count =
769 orangefs_prepare_cdm_array(client_debug_array_string);
770 if (cdm_element_count <= 0)
771 goto out;
772
773 /* Count the bytes destined for debug_help_string. */
774 byte_count += strlen(client_title);
775
776 for (i = 0; i < cdm_element_count; i++) {
777 byte_count += strlen(cdm_array[i].keyword + 2);
778 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
779 pr_info("%s: overflow 1!\n", __func__);
780 goto out;
781 }
782 }
783
784 gossip_debug(GOSSIP_UTILS_DEBUG,
785 "%s: cdm_element_count:%d:\n",
786 __func__,
787 cdm_element_count);
788 }
789
790 byte_count += strlen(kernel_title);
791 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
792 byte_count +=
793 strlen(s_kmod_keyword_mask_map[i].keyword + 2);
794 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
795 pr_info("%s: overflow 2!\n", __func__);
796 goto out;
797 }
798 }
799
800 /* build debug_help_string. */
801 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
802 if (!debug_help_string) {
803 rc = -ENOMEM;
804 goto out;
805 }
806
807 strcat(debug_help_string, client_title);
808
809 if (!at_boot) {
810 for (i = 0; i < cdm_element_count; i++) {
811 strcat(debug_help_string, "\t");
812 strcat(debug_help_string, cdm_array[i].keyword);
813 strcat(debug_help_string, "\n");
814 }
815 }
816
817 strcat(debug_help_string, "\n");
818 strcat(debug_help_string, kernel_title);
819
820 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
821 strcat(debug_help_string, "\t");
822 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
823 strcat(debug_help_string, "\n");
824 }
825
826 rc = 0;
827
828out:
829
830 return rc;
831
832}
833
834/*
835 * kernel = type 0
836 * client = type 1
837 */
838void debug_mask_to_string(void *mask, int type)
839{
840 int i;
841 int len = 0;
842 char *debug_string;
843 int element_count = 0;
844
845 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
846
847 if (type) {
848 debug_string = client_debug_string;
849 element_count = cdm_element_count;
850 } else {
851 debug_string = kernel_debug_string;
852 element_count = num_kmod_keyword_mask_map;
853 }
854
Yi Liu8bb8aef2015-11-24 15:12:14 -0500855 memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400856
857 /*
858 * Some keywords, like "all" or "verbose", are amalgams of
859 * numerous other keywords. Make a special check for those
860 * before grinding through the whole mask only to find out
861 * later...
862 */
863 if (check_amalgam_keyword(mask, type))
864 goto out;
865
866 /* Build the debug string. */
867 for (i = 0; i < element_count; i++)
868 if (type)
869 do_c_string(mask, i);
870 else
871 do_k_string(mask, i);
872
873 len = strlen(debug_string);
874
875 if ((len) && (type))
876 client_debug_string[len - 1] = '\0';
877 else if (len)
878 kernel_debug_string[len - 1] = '\0';
879 else if (type)
880 strcpy(client_debug_string, "none");
881 else
882 strcpy(kernel_debug_string, "none");
883
884out:
885gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
886
887 return;
888
889}
890
891void do_k_string(void *k_mask, int index)
892{
893 __u64 *mask = (__u64 *) k_mask;
894
895 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
Mike Marshall54804942015-10-05 13:44:24 -0400896 goto out;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400897
898 if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
899 if ((strlen(kernel_debug_string) +
900 strlen(s_kmod_keyword_mask_map[index].keyword))
Yi Liu8bb8aef2015-11-24 15:12:14 -0500901 < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400902 strcat(kernel_debug_string,
903 s_kmod_keyword_mask_map[index].keyword);
904 strcat(kernel_debug_string, ",");
905 } else {
906 gossip_err("%s: overflow!\n", __func__);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500907 strcpy(kernel_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400908 goto out;
909 }
910 }
911
912out:
913
914 return;
915}
916
917void do_c_string(void *c_mask, int index)
918{
919 struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
920
921 if (keyword_is_amalgam(cdm_array[index].keyword))
922 goto out;
923
924 if ((mask->mask1 & cdm_array[index].mask1) ||
925 (mask->mask2 & cdm_array[index].mask2)) {
926 if ((strlen(client_debug_string) +
927 strlen(cdm_array[index].keyword) + 1)
Yi Liu8bb8aef2015-11-24 15:12:14 -0500928 < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400929 strcat(client_debug_string,
930 cdm_array[index].keyword);
931 strcat(client_debug_string, ",");
932 } else {
933 gossip_err("%s: overflow!\n", __func__);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500934 strcpy(client_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400935 goto out;
936 }
937 }
938out:
939 return;
940}
941
942int keyword_is_amalgam(char *keyword)
943{
944 int rc = 0;
945
Yi Liu8bb8aef2015-11-24 15:12:14 -0500946 if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE)))
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400947 rc = 1;
948
949 return rc;
950}
951
952/*
953 * kernel = type 0
954 * client = type 1
955 *
956 * return 1 if we found an amalgam.
957 */
958int check_amalgam_keyword(void *mask, int type)
959{
960 __u64 *k_mask;
961 struct client_debug_mask *c_mask;
962 int k_all_index = num_kmod_keyword_mask_map - 1;
963 int rc = 0;
964
965 if (type) {
966 c_mask = (struct client_debug_mask *) mask;
967
968 if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
969 (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500970 strcpy(client_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400971 rc = 1;
972 goto out;
973 }
974
975 if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
976 (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500977 strcpy(client_debug_string, ORANGEFS_VERBOSE);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400978 rc = 1;
979 goto out;
980 }
981
982 } else {
983 k_mask = (__u64 *) mask;
984
985 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500986 strcpy(kernel_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400987 rc = 1;
988 goto out;
989 }
990 }
991
992out:
993
994 return rc;
995}
996
997/*
998 * kernel = type 0
999 * client = type 1
1000 */
1001void debug_string_to_mask(char *debug_string, void *mask, int type)
1002{
1003 char *unchecked_keyword;
1004 int i;
1005 char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
Mike Marshalleeaa3d42015-07-29 13:36:37 -04001006 char *original_pointer;
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001007 int element_count = 0;
1008 struct client_debug_mask *c_mask;
1009 __u64 *k_mask;
1010
1011 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
1012
1013 if (type) {
1014 c_mask = (struct client_debug_mask *)mask;
1015 element_count = cdm_element_count;
1016 } else {
1017 k_mask = (__u64 *)mask;
1018 *k_mask = 0;
1019 element_count = num_kmod_keyword_mask_map;
1020 }
1021
Mike Marshalleeaa3d42015-07-29 13:36:37 -04001022 original_pointer = strsep_fodder;
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001023 while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
1024 if (strlen(unchecked_keyword)) {
1025 for (i = 0; i < element_count; i++)
1026 if (type)
1027 do_c_mask(i,
1028 unchecked_keyword,
1029 &c_mask);
1030 else
1031 do_k_mask(i,
1032 unchecked_keyword,
1033 &k_mask);
1034 }
1035
Mike Marshalleeaa3d42015-07-29 13:36:37 -04001036 kfree(original_pointer);
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001037}
1038
1039void do_c_mask(int i,
1040 char *unchecked_keyword,
1041 struct client_debug_mask **sane_mask)
1042{
1043
1044 if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
1045 (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
1046 (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
1047 }
1048}
1049
1050void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
1051{
1052
1053 if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
1054 **sane_mask = (**sane_mask) |
1055 s_kmod_keyword_mask_map[i].mask_val;
1056}