blob: 9b96b99539d62501718bd752f26d059900095864 [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;
Martin Brandenburg6eaff8c2016-08-02 14:31:05 -040053 case ORANGEFS_VFS_OP_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) {
Martin Brandenburg8bbb20a2016-07-28 14:46:36 -0400265 if (time_before(jiffies, orangefs_inode->getattr_time))
Martin Brandenburg71680c12016-06-09 16:32:38 -0400266 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;
Fabian Frederick61604a22017-02-27 14:28:32 -0800309 orangefs_inode->blksize = i_blocksize(inode);
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400310 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);
Fabian Frederick61604a22017-02-27 14:28:32 -0800319 orangefs_inode->blksize = i_blocksize(inode);
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 Brandenburg1d503612016-08-16 11:38:14 -0400350 orangefs_inode->getattr_time = jiffies +
351 orangefs_getattr_timeout_msecs*HZ/1000;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400352 ret = 0;
353out:
354 op_release(new_op);
355 return ret;
356}
357
Martin Brandenburg5859d772016-03-17 15:15:16 -0400358int orangefs_inode_check_changed(struct inode *inode)
359{
360 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
361 struct orangefs_kernel_op_s *new_op;
362 int ret;
363
364 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
365 get_khandle_from_ino(inode));
366
367 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
368 if (!new_op)
369 return -ENOMEM;
370 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
371 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
372 ORANGEFS_ATTR_SYS_LNK_TARGET;
373
374 ret = service_operation(new_op, __func__,
375 get_interruptible_flag(inode));
376 if (ret != 0)
377 goto out;
378
Martin Brandenburg26662632016-03-17 16:01:52 -0400379 ret = orangefs_inode_is_stale(inode, 0,
380 &new_op->downcall.resp.getattr.attributes,
381 new_op->downcall.resp.getattr.link_target);
Martin Brandenburg5859d772016-03-17 15:15:16 -0400382out:
383 op_release(new_op);
384 return ret;
385}
386
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400387/*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500388 * issues a orangefs setattr request to make sure the new attribute values
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400389 * take effect if successful. returns 0 on success; -errno otherwise
390 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500391int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400392{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500393 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
394 struct orangefs_kernel_op_s *new_op;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400395 int ret;
396
Yi Liu8bb8aef2015-11-24 15:12:14 -0500397 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400398 if (!new_op)
399 return -ENOMEM;
400
Yi Liu8bb8aef2015-11-24 15:12:14 -0500401 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400402 ret = copy_attributes_from_inode(inode,
403 &new_op->upcall.req.setattr.attributes,
404 iattr);
Al Viroed42fe02016-01-22 19:47:47 -0500405 if (ret >= 0) {
406 ret = service_operation(new_op, __func__,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400407 get_interruptible_flag(inode));
408
Al Viroed42fe02016-01-22 19:47:47 -0500409 gossip_debug(GOSSIP_UTILS_DEBUG,
410 "orangefs_inode_setattr: returning %d\n",
411 ret);
412 }
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400413
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400414 op_release(new_op);
415
416 /*
417 * successful setattr should clear the atime, mtime and
418 * ctime flags.
419 */
420 if (ret == 0) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500421 ClearAtimeFlag(orangefs_inode);
422 ClearMtimeFlag(orangefs_inode);
423 ClearCtimeFlag(orangefs_inode);
424 ClearModeFlag(orangefs_inode);
Martin Brandenburg8bbb20a2016-07-28 14:46:36 -0400425 orangefs_inode->getattr_time = jiffies - 1;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400426 }
427
428 return ret;
429}
430
Yi Liu8bb8aef2015-11-24 15:12:14 -0500431int orangefs_flush_inode(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400432{
433 /*
434 * If it is a dirty inode, this function gets called.
435 * Gather all the information that needs to be setattr'ed
436 * Right now, this will only be used for mode, atime, mtime
437 * and/or ctime.
438 */
439 struct iattr wbattr;
440 int ret;
441 int mtime_flag;
442 int ctime_flag;
443 int atime_flag;
444 int mode_flag;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500445 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400446
447 memset(&wbattr, 0, sizeof(wbattr));
448
449 /*
450 * check inode flags up front, and clear them if they are set. This
451 * will prevent multiple processes from all trying to flush the same
452 * inode if they call close() simultaneously
453 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500454 mtime_flag = MtimeFlag(orangefs_inode);
455 ClearMtimeFlag(orangefs_inode);
456 ctime_flag = CtimeFlag(orangefs_inode);
457 ClearCtimeFlag(orangefs_inode);
458 atime_flag = AtimeFlag(orangefs_inode);
459 ClearAtimeFlag(orangefs_inode);
460 mode_flag = ModeFlag(orangefs_inode);
461 ClearModeFlag(orangefs_inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400462
463 /* -- Lazy atime,mtime and ctime update --
464 * Note: all times are dictated by server in the new scheme
465 * and not by the clients
466 *
467 * Also mode updates are being handled now..
468 */
469
470 if (mtime_flag)
471 wbattr.ia_valid |= ATTR_MTIME;
472 if (ctime_flag)
473 wbattr.ia_valid |= ATTR_CTIME;
474 if (atime_flag)
475 wbattr.ia_valid |= ATTR_ATIME;
476
477 if (mode_flag) {
478 wbattr.ia_mode = inode->i_mode;
479 wbattr.ia_valid |= ATTR_MODE;
480 }
481
482 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500483 "*********** orangefs_flush_inode: %pU "
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400484 "(ia_valid %d)\n",
485 get_khandle_from_ino(inode),
486 wbattr.ia_valid);
487 if (wbattr.ia_valid == 0) {
488 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500489 "orangefs_flush_inode skipping setattr()\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400490 return 0;
491 }
492
493 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500494 "orangefs_flush_inode (%pU) writing mode %o\n",
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400495 get_khandle_from_ino(inode),
496 inode->i_mode);
497
Yi Liu8bb8aef2015-11-24 15:12:14 -0500498 ret = orangefs_inode_setattr(inode, &wbattr);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400499
500 return ret;
501}
502
Yi Liu8bb8aef2015-11-24 15:12:14 -0500503int orangefs_unmount_sb(struct super_block *sb)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400504{
505 int ret = -EINVAL;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500506 struct orangefs_kernel_op_s *new_op = NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400507
508 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500509 "orangefs_unmount_sb called on sb %p\n",
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400510 sb);
511
Yi Liu8bb8aef2015-11-24 15:12:14 -0500512 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400513 if (!new_op)
514 return -ENOMEM;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500515 new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id;
516 new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id;
517 strncpy(new_op->upcall.req.fs_umount.orangefs_config_server,
518 ORANGEFS_SB(sb)->devname,
519 ORANGEFS_MAX_SERVER_ADDR_LEN);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400520
521 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500522 "Attempting ORANGEFS Unmount via host %s\n",
523 new_op->upcall.req.fs_umount.orangefs_config_server);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400524
Yi Liu8bb8aef2015-11-24 15:12:14 -0500525 ret = service_operation(new_op, "orangefs_fs_umount", 0);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400526
527 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500528 "orangefs_unmount: got return value of %d\n", ret);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400529 if (ret)
530 sb = ERR_PTR(ret);
531 else
Yi Liu8bb8aef2015-11-24 15:12:14 -0500532 ORANGEFS_SB(sb)->mount_pending = 1;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400533
534 op_release(new_op);
535 return ret;
536}
537
Yi Liu8bb8aef2015-11-24 15:12:14 -0500538void orangefs_make_bad_inode(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400539{
540 if (is_root_handle(inode)) {
541 /*
542 * if this occurs, the pvfs2-client-core was killed but we
543 * can't afford to lose the inode operations and such
544 * associated with the root handle in any case.
545 */
546 gossip_debug(GOSSIP_UTILS_DEBUG,
547 "*** NOT making bad root inode %pU\n",
548 get_khandle_from_ino(inode));
549 } else {
550 gossip_debug(GOSSIP_UTILS_DEBUG,
551 "*** making bad inode %pU\n",
552 get_khandle_from_ino(inode));
553 make_bad_inode(inode);
554 }
555}
556
Mike Marshall54804942015-10-05 13:44:24 -0400557/*
558 * The following is a very dirty hack that is now a permanent part of the
Yi Liu8bb8aef2015-11-24 15:12:14 -0500559 * ORANGEFS protocol. See protocol.h for more error definitions.
Mike Marshall54804942015-10-05 13:44:24 -0400560 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400561
Yi Liu8bb8aef2015-11-24 15:12:14 -0500562/* The order matches include/orangefs-types.h in the OrangeFS source. */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400563static int PINT_errno_mapping[] = {
Mike Marshall54804942015-10-05 13:44:24 -0400564 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
565 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
566 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
567 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
568 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
569 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
570 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
571 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
572 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
573 EACCES, ECONNRESET, ERANGE
Martin Brandenburg894ac432015-10-02 12:11:19 -0400574};
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400575
Yi Liu8bb8aef2015-11-24 15:12:14 -0500576int orangefs_normalize_to_errno(__s32 error_code)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400577{
Mike Marshall54804942015-10-05 13:44:24 -0400578 __u32 i;
579
Martin Brandenburg894ac432015-10-02 12:11:19 -0400580 /* Success */
581 if (error_code == 0) {
582 return 0;
Mike Marshall54804942015-10-05 13:44:24 -0400583 /*
584 * This shouldn't ever happen. If it does it should be fixed on the
585 * server.
586 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400587 } else if (error_code > 0) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500588 gossip_err("orangefs: error status receieved.\n");
589 gossip_err("orangefs: assuming error code is inverted.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400590 error_code = -error_code;
591 }
592
Mike Marshall54804942015-10-05 13:44:24 -0400593 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500594 * XXX: This is very bad since error codes from ORANGEFS may not be
Mike Marshall54804942015-10-05 13:44:24 -0400595 * suitable for return into userspace.
596 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400597
Mike Marshall54804942015-10-05 13:44:24 -0400598 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500599 * Convert ORANGEFS error values into errno values suitable for return
Mike Marshall54804942015-10-05 13:44:24 -0400600 * from the kernel.
601 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500602 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
Martin Brandenburg894ac432015-10-02 12:11:19 -0400603 if (((-error_code) &
Yi Liu8bb8aef2015-11-24 15:12:14 -0500604 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
605 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400606 /*
607 * cancellation error codes generally correspond to
608 * a timeout from the client's perspective
609 */
610 error_code = -ETIMEDOUT;
611 } else {
612 /* assume a default error code */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500613 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400614 error_code = -EINVAL;
615 }
Martin Brandenburg894ac432015-10-02 12:11:19 -0400616
Yi Liu8bb8aef2015-11-24 15:12:14 -0500617 /* Convert ORANGEFS encoded errno values into regular errno values. */
618 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
619 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
Mike Marshall54804942015-10-05 13:44:24 -0400620 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
Martin Brandenburg894ac432015-10-02 12:11:19 -0400621 error_code = -PINT_errno_mapping[i];
622 else
623 error_code = -EINVAL;
624
Mike Marshall54804942015-10-05 13:44:24 -0400625 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500626 * Only ORANGEFS protocol error codes should ever come here. Otherwise
Mike Marshall54804942015-10-05 13:44:24 -0400627 * there is a bug somewhere.
628 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400629 } else {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500630 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400631 }
632 return error_code;
633}
634
635#define NUM_MODES 11
Yi Liu8bb8aef2015-11-24 15:12:14 -0500636__s32 ORANGEFS_util_translate_mode(int mode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400637{
638 int ret = 0;
639 int i = 0;
640 static int modes[NUM_MODES] = {
641 S_IXOTH, S_IWOTH, S_IROTH,
642 S_IXGRP, S_IWGRP, S_IRGRP,
643 S_IXUSR, S_IWUSR, S_IRUSR,
644 S_ISGID, S_ISUID
645 };
Yi Liu8bb8aef2015-11-24 15:12:14 -0500646 static int orangefs_modes[NUM_MODES] = {
647 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
648 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
649 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
650 ORANGEFS_G_SGID, ORANGEFS_U_SUID
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400651 };
652
653 for (i = 0; i < NUM_MODES; i++)
654 if (mode & modes[i])
Yi Liu8bb8aef2015-11-24 15:12:14 -0500655 ret |= orangefs_modes[i];
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400656
657 return ret;
658}
659#undef NUM_MODES