hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/fs/orangefs/orangefs-utils.c
....@@ -1,6 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
33 * (C) 2001 Clemson University and The University of Chicago
4
+ * Copyright 2018 Omnibond Systems, L.L.C.
45 *
56 * See COPYING in top-level directory.
67 */
....@@ -135,51 +136,37 @@
135136 * NOTE: in kernel land, we never use the sys_attr->link_target for
136137 * anything, so don't bother copying it into the sys_attr object here.
137138 */
138
-static inline int copy_attributes_from_inode(struct inode *inode,
139
- struct ORANGEFS_sys_attr_s *attrs,
140
- struct iattr *iattr)
139
+static inline void copy_attributes_from_inode(struct inode *inode,
140
+ struct ORANGEFS_sys_attr_s *attrs)
141141 {
142
- umode_t tmp_mode;
143
-
144
- if (!iattr || !inode || !attrs) {
145
- gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
146
- "in copy_attributes_from_inode!\n",
147
- iattr,
148
- inode,
149
- attrs);
150
- return -EINVAL;
151
- }
152
- /*
153
- * We need to be careful to only copy the attributes out of the
154
- * iattr object that we know are valid.
155
- */
142
+ struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
156143 attrs->mask = 0;
157
- if (iattr->ia_valid & ATTR_UID) {
158
- attrs->owner = from_kuid(&init_user_ns, iattr->ia_uid);
144
+ if (orangefs_inode->attr_valid & ATTR_UID) {
145
+ attrs->owner = from_kuid(&init_user_ns, inode->i_uid);
159146 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
160147 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
161148 }
162
- if (iattr->ia_valid & ATTR_GID) {
163
- attrs->group = from_kgid(&init_user_ns, iattr->ia_gid);
149
+ if (orangefs_inode->attr_valid & ATTR_GID) {
150
+ attrs->group = from_kgid(&init_user_ns, inode->i_gid);
164151 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
165152 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
166153 }
167154
168
- if (iattr->ia_valid & ATTR_ATIME) {
155
+ if (orangefs_inode->attr_valid & ATTR_ATIME) {
169156 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
170
- if (iattr->ia_valid & ATTR_ATIME_SET) {
171
- attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
157
+ if (orangefs_inode->attr_valid & ATTR_ATIME_SET) {
158
+ attrs->atime = (time64_t)inode->i_atime.tv_sec;
172159 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
173160 }
174161 }
175
- if (iattr->ia_valid & ATTR_MTIME) {
162
+ if (orangefs_inode->attr_valid & ATTR_MTIME) {
176163 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
177
- if (iattr->ia_valid & ATTR_MTIME_SET) {
178
- attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
164
+ if (orangefs_inode->attr_valid & ATTR_MTIME_SET) {
165
+ attrs->mtime = (time64_t)inode->i_mtime.tv_sec;
179166 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
180167 }
181168 }
182
- if (iattr->ia_valid & ATTR_CTIME)
169
+ if (orangefs_inode->attr_valid & ATTR_CTIME)
183170 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
184171
185172 /*
....@@ -188,36 +175,10 @@
188175 * worry about ATTR_SIZE
189176 */
190177
191
- if (iattr->ia_valid & ATTR_MODE) {
192
- tmp_mode = iattr->ia_mode;
193
- if (tmp_mode & (S_ISVTX)) {
194
- if (is_root_handle(inode)) {
195
- /*
196
- * allow sticky bit to be set on root (since
197
- * it shows up that way by default anyhow),
198
- * but don't show it to the server
199
- */
200
- tmp_mode -= S_ISVTX;
201
- } else {
202
- gossip_debug(GOSSIP_UTILS_DEBUG,
203
- "%s: setting sticky bit not supported.\n",
204
- __func__);
205
- return -EINVAL;
206
- }
207
- }
208
-
209
- if (tmp_mode & (S_ISUID)) {
210
- gossip_debug(GOSSIP_UTILS_DEBUG,
211
- "%s: setting setuid bit not supported.\n",
212
- __func__);
213
- return -EINVAL;
214
- }
215
-
216
- attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
178
+ if (orangefs_inode->attr_valid & ATTR_MODE) {
179
+ attrs->perms = ORANGEFS_util_translate_mode(inode->i_mode);
217180 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
218181 }
219
-
220
- return 0;
221182 }
222183
223184 static int orangefs_inode_type(enum orangefs_ds_type objtype)
....@@ -272,27 +233,30 @@
272233 return 0;
273234 }
274235
275
-int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
276
- u32 request_mask)
236
+int orangefs_inode_getattr(struct inode *inode, int flags)
277237 {
278238 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
279239 struct orangefs_kernel_op_s *new_op;
280240 loff_t inode_size;
281241 int ret, type;
282242
283
- gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
284
- get_khandle_from_ino(inode));
243
+ gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU flags %d\n",
244
+ __func__, get_khandle_from_ino(inode), flags);
285245
286
- if (!new && !bypass) {
287
- /*
288
- * Must have all the attributes in the mask and be within cache
289
- * time.
290
- */
291
- if ((request_mask & orangefs_inode->getattr_mask) ==
292
- request_mask &&
293
- time_before(jiffies, orangefs_inode->getattr_time))
294
- return 0;
246
+again:
247
+ spin_lock(&inode->i_lock);
248
+ /* Must have all the attributes in the mask and be within cache time. */
249
+ if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) ||
250
+ orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) {
251
+ if (orangefs_inode->attr_valid) {
252
+ spin_unlock(&inode->i_lock);
253
+ write_inode_now(inode, 1);
254
+ goto again;
255
+ }
256
+ spin_unlock(&inode->i_lock);
257
+ return 0;
295258 }
259
+ spin_unlock(&inode->i_lock);
296260
297261 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
298262 if (!new_op)
....@@ -302,7 +266,7 @@
302266 * Size is the hardest attribute to get. The incremental cost of any
303267 * other attribute is essentially zero.
304268 */
305
- if (request_mask & STATX_SIZE || new)
269
+ if (flags)
306270 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
307271 else
308272 new_op->upcall.req.getattr.mask =
....@@ -313,13 +277,33 @@
313277 if (ret != 0)
314278 goto out;
315279
316
- if (!new) {
280
+again2:
281
+ spin_lock(&inode->i_lock);
282
+ /* Must have all the attributes in the mask and be within cache time. */
283
+ if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) ||
284
+ orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) {
285
+ if (orangefs_inode->attr_valid) {
286
+ spin_unlock(&inode->i_lock);
287
+ write_inode_now(inode, 1);
288
+ goto again2;
289
+ }
290
+ if (inode->i_state & I_DIRTY_PAGES) {
291
+ ret = 0;
292
+ goto out_unlock;
293
+ }
294
+ gossip_debug(GOSSIP_UTILS_DEBUG, "%s: in cache or dirty\n",
295
+ __func__);
296
+ ret = 0;
297
+ goto out_unlock;
298
+ }
299
+
300
+ if (!(flags & ORANGEFS_GETATTR_NEW)) {
317301 ret = orangefs_inode_is_stale(inode,
318302 &new_op->downcall.resp.getattr.attributes,
319303 new_op->downcall.resp.getattr.link_target);
320304 if (ret) {
321305 ret = -ESTALE;
322
- goto out;
306
+ goto out_unlock;
323307 }
324308 }
325309
....@@ -329,30 +313,26 @@
329313 case S_IFREG:
330314 inode->i_flags = orangefs_inode_flags(&new_op->
331315 downcall.resp.getattr.attributes);
332
- if (request_mask & STATX_SIZE || new) {
316
+ if (flags) {
333317 inode_size = (loff_t)new_op->
334318 downcall.resp.getattr.attributes.size;
335319 inode->i_size = inode_size;
336320 inode->i_blkbits = ffs(new_op->downcall.resp.getattr.
337321 attributes.blksize);
338
- spin_lock(&inode->i_lock);
339322 inode->i_bytes = inode_size;
340323 inode->i_blocks =
341324 (inode_size + 512 - inode_size % 512)/512;
342
- spin_unlock(&inode->i_lock);
343325 }
344326 break;
345327 case S_IFDIR:
346
- if (request_mask & STATX_SIZE || new) {
328
+ if (flags) {
347329 inode->i_size = PAGE_SIZE;
348
- spin_lock(&inode->i_lock);
349330 inode_set_bytes(inode, inode->i_size);
350
- spin_unlock(&inode->i_lock);
351331 }
352332 set_nlink(inode, 1);
353333 break;
354334 case S_IFLNK:
355
- if (new) {
335
+ if (flags & ORANGEFS_GETATTR_NEW) {
356336 inode->i_size = (loff_t)strlen(new_op->
357337 downcall.resp.getattr.link_target);
358338 ret = strscpy(orangefs_inode->link_target,
....@@ -360,7 +340,7 @@
360340 ORANGEFS_NAME_MAX);
361341 if (ret == -E2BIG) {
362342 ret = -EIO;
363
- goto out;
343
+ goto out_unlock;
364344 }
365345 inode->i_link = orangefs_inode->link_target;
366346 }
....@@ -370,7 +350,7 @@
370350 /* XXX: ESTALE? This is what is done if it is not new. */
371351 orangefs_make_bad_inode(inode);
372352 ret = -ESTALE;
373
- goto out;
353
+ goto out_unlock;
374354 }
375355
376356 inode->i_uid = make_kuid(&init_user_ns, new_op->
....@@ -393,11 +373,9 @@
393373
394374 orangefs_inode->getattr_time = jiffies +
395375 orangefs_getattr_timeout_msecs*HZ/1000;
396
- if (request_mask & STATX_SIZE || new)
397
- orangefs_inode->getattr_mask = STATX_BASIC_STATS;
398
- else
399
- orangefs_inode->getattr_mask = STATX_BASIC_STATS & ~STATX_SIZE;
400376 ret = 0;
377
+out_unlock:
378
+ spin_unlock(&inode->i_lock);
401379 out:
402380 op_release(new_op);
403381 return ret;
....@@ -436,7 +414,7 @@
436414 * issues a orangefs setattr request to make sure the new attribute values
437415 * take effect if successful. returns 0 on success; -errno otherwise
438416 */
439
-int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
417
+int orangefs_inode_setattr(struct inode *inode)
440418 {
441419 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
442420 struct orangefs_kernel_op_s *new_op;
....@@ -446,24 +424,31 @@
446424 if (!new_op)
447425 return -ENOMEM;
448426
427
+ spin_lock(&inode->i_lock);
428
+ new_op->upcall.uid = from_kuid(&init_user_ns, orangefs_inode->attr_uid);
429
+ new_op->upcall.gid = from_kgid(&init_user_ns, orangefs_inode->attr_gid);
449430 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
450
- ret = copy_attributes_from_inode(inode,
451
- &new_op->upcall.req.setattr.attributes,
452
- iattr);
453
- if (ret >= 0) {
454
- ret = service_operation(new_op, __func__,
455
- get_interruptible_flag(inode));
456
-
457
- gossip_debug(GOSSIP_UTILS_DEBUG,
458
- "orangefs_inode_setattr: returning %d\n",
459
- ret);
431
+ copy_attributes_from_inode(inode,
432
+ &new_op->upcall.req.setattr.attributes);
433
+ orangefs_inode->attr_valid = 0;
434
+ if (!new_op->upcall.req.setattr.attributes.mask) {
435
+ spin_unlock(&inode->i_lock);
436
+ op_release(new_op);
437
+ return 0;
460438 }
439
+ spin_unlock(&inode->i_lock);
440
+
441
+ ret = service_operation(new_op, __func__,
442
+ get_interruptible_flag(inode) | ORANGEFS_OP_WRITEBACK);
443
+ gossip_debug(GOSSIP_UTILS_DEBUG,
444
+ "orangefs_inode_setattr: returning %d\n", ret);
445
+ if (ret)
446
+ orangefs_make_bad_inode(inode);
461447
462448 op_release(new_op);
463449
464450 if (ret == 0)
465451 orangefs_inode->getattr_time = jiffies - 1;
466
-
467452 return ret;
468453 }
469454