diff options
| -rw-r--r-- | fs/orangefs/orangefs-utils.c | 77 |
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 | ||
| 231 | static 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 | |||
| 231 | int orangefs_inode_getattr(struct inode *inode, int new, int size) | 254 | int 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; | ||
| 378 | out: | 373 | out: |
| 379 | op_release(new_op); | 374 | op_release(new_op); |
| 380 | return ret; | 375 | return ret; |
