aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/orangefs/orangefs-utils.c77
1 files changed, 36 insertions, 41 deletions
diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c
index 6643a6a87fa1..36ee30d1f0ad 100644
--- a/fs/orangefs/orangefs-utils.c
+++ b/fs/orangefs/orangefs-utils.c
@@ -228,12 +228,35 @@ static int orangefs_inode_type(enum orangefs_ds_type objtype)
228 return -1; 228 return -1;
229} 229}
230 230
231static 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
231int orangefs_inode_getattr(struct inode *inode, int new, int size) 254int orangefs_inode_getattr(struct inode *inode, int new, int size)
232{ 255{
233 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 256 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
234 struct orangefs_kernel_op_s *new_op; 257 struct orangefs_kernel_op_s *new_op;
235 loff_t inode_size, rounded_up_size; 258 loff_t inode_size, rounded_up_size;
236 int ret; 259 int ret, type;
237 260
238 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__, 261 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
239 get_khandle_from_ino(inode)); 262 get_khandle_from_ino(inode));
@@ -250,28 +273,17 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
250 if (ret != 0) 273 if (ret != 0)
251 goto out; 274 goto out;
252 275
253 ret = orangefs_inode_type(new_op-> 276 type = orangefs_inode_type(new_op->
254 downcall.resp.getattr.attributes.objtype); 277 downcall.resp.getattr.attributes.objtype);
255 if (!new) { 278 ret = orangefs_inode_is_stale(inode, new,
256 /* 279 &new_op->downcall.resp.getattr.attributes,
257 * If the inode type or symlink target have changed then this 280 new_op->downcall.resp.getattr.link_target);
258 * inode is stale. 281 if (ret) {
259 */ 282 ret = -ESTALE;
260 if (ret == -1 || !(inode->i_mode & ret)) { 283 goto out;
261 orangefs_make_bad_inode(inode);
262 ret = -ESTALE;
263 goto out;
264 }
265 if (ret == S_IFLNK && strncmp(orangefs_inode->link_target,
266 new_op->downcall.resp.getattr.link_target,
267 ORANGEFS_NAME_MAX)) {
268 orangefs_make_bad_inode(inode);
269 ret = -ESTALE;
270 goto out;
271 }
272 } 284 }
273 285
274 switch (ret) { 286 switch (type) {
275 case S_IFREG: 287 case S_IFREG:
276 inode->i_flags = orangefs_inode_flags(&new_op-> 288 inode->i_flags = orangefs_inode_flags(&new_op->
277 downcall.resp.getattr.attributes); 289 downcall.resp.getattr.attributes);
@@ -325,7 +337,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
325 inode->i_ctime.tv_nsec = 0; 337 inode->i_ctime.tv_nsec = 0;
326 338
327 /* special case: mark the root inode as sticky */ 339 /* special case: mark the root inode as sticky */
328 inode->i_mode = ret | (is_root_handle(inode) ? S_ISVTX : 0) | 340 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
329 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes); 341 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
330 342
331 ret = 0; 343 ret = 0;
@@ -355,26 +367,9 @@ int orangefs_inode_check_changed(struct inode *inode)
355 if (ret != 0) 367 if (ret != 0)
356 goto out; 368 goto out;
357 369
358 ret = orangefs_inode_type(new_op-> 370 ret = orangefs_inode_is_stale(inode, 0,
359 downcall.resp.getattr.attributes.objtype); 371 &new_op->downcall.resp.getattr.attributes,
360 /* 372 new_op->downcall.resp.getattr.link_target);
361 * If the inode type or symlink target have changed then this
362 * inode is stale.
363 */
364 if (ret == -1 || !(inode->i_mode & ret)) {
365 orangefs_make_bad_inode(inode);
366 ret = 1;
367 goto out;
368 }
369 if (ret == S_IFLNK && strncmp(orangefs_inode->link_target,
370 new_op->downcall.resp.getattr.link_target,
371 ORANGEFS_NAME_MAX)) {
372 orangefs_make_bad_inode(inode);
373 ret = 1;
374 goto out;
375 }
376
377 ret = 0;
378out: 373out:
379 op_release(new_op); 374 op_release(new_op);
380 return ret; 375 return ret;