| 17481 | } |
| 17482 | |
| 17483 | int Client::_fallocate(Fh *fh, int mode, int64_t offset, int64_t length) |
| 17484 | { |
| 17485 | ceph_assert(ceph_mutex_is_locked_by_me(client_lock)); |
| 17486 | |
| 17487 | if (offset < 0 || length <= 0) |
| 17488 | return -EINVAL; |
| 17489 | |
| 17490 | if (mode == 0 || (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))) |
| 17491 | return -EOPNOTSUPP; |
| 17492 | |
| 17493 | if ((mode & FALLOC_FL_PUNCH_HOLE) && !(mode & FALLOC_FL_KEEP_SIZE)) |
| 17494 | return -EOPNOTSUPP; |
| 17495 | |
| 17496 | Inode *in = fh->inode.get(); |
| 17497 | |
| 17498 | if (objecter->osdmap_pool_full(in->layout.pool_id) && |
| 17499 | !(mode & FALLOC_FL_PUNCH_HOLE)) { |
| 17500 | return -ENOSPC; |
| 17501 | } |
| 17502 | |
| 17503 | if (in->snapid != CEPH_NOSNAP) |
| 17504 | return -EROFS; |
| 17505 | |
| 17506 | if ((fh->mode & CEPH_FILE_MODE_WR) == 0) |
| 17507 | return -EBADF; |
| 17508 | |
| 17509 | uint64_t size = offset + length; |
| 17510 | if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) && |
| 17511 | size > in->size && |
| 17512 | is_quota_bytes_exceeded(in, size - in->size, fh->actor_perms)) { |
| 17513 | return -EDQUOT; |
| 17514 | } |
| 17515 | |
| 17516 | int have; |
| 17517 | int r = get_caps(fh, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, &have, -1); |
| 17518 | if (r < 0) |
| 17519 | return r; |
| 17520 | |
| 17521 | r = clear_suid_sgid(in, fh->actor_perms); |
| 17522 | if (r < 0) { |
| 17523 | put_cap_ref(in, CEPH_CAP_FILE_WR); |
| 17524 | return r; |
| 17525 | } |
| 17526 | |
| 17527 | std::unique_ptr<C_SaferCond> onuninline = nullptr; |
| 17528 | if (mode & FALLOC_FL_PUNCH_HOLE) { |
| 17529 | if (in->inline_version < CEPH_INLINE_NONE && |
| 17530 | (have & CEPH_CAP_FILE_BUFFER)) { |
| 17531 | bufferlist bl; |
| 17532 | auto inline_iter = in->inline_data.cbegin(); |
| 17533 | int len = in->inline_data.length(); |
| 17534 | if (offset < len) { |
| 17535 | if (offset > 0) |
| 17536 | inline_iter.copy(offset, bl); |
| 17537 | int size = length; |
| 17538 | if (offset + size > len) |
| 17539 | size = len - offset; |
| 17540 | if (size > 0) |
nothing calls this directly
no test coverage detected