| 6391 | } |
| 6392 | |
| 6393 | int Client::may_open(const InodeRef& in, int flags, const UserPerm& perms) |
| 6394 | { |
| 6395 | ldout(cct, 20) << __func__ << " " << *in << "; " << perms << dendl; |
| 6396 | unsigned want = 0; |
| 6397 | |
| 6398 | #if defined(__linux__) |
| 6399 | if (!in->is_dir() && is_inode_locked(in) && fscrypt_as) |
| 6400 | return -ENOKEY; |
| 6401 | #endif |
| 6402 | |
| 6403 | if ((flags & O_ACCMODE) == O_WRONLY) |
| 6404 | want = CLIENT_MAY_WRITE; |
| 6405 | else if ((flags & O_ACCMODE) == O_RDWR) |
| 6406 | want = CLIENT_MAY_READ | CLIENT_MAY_WRITE; |
| 6407 | else if ((flags & O_ACCMODE) == O_RDONLY) |
| 6408 | want = CLIENT_MAY_READ; |
| 6409 | if (flags & O_TRUNC) |
| 6410 | want |= CLIENT_MAY_WRITE; |
| 6411 | |
| 6412 | int r = 0; |
| 6413 | switch (in->mode & S_IFMT) { |
| 6414 | case S_IFLNK: |
| 6415 | #if defined(__linux__) && defined(O_PATH) |
| 6416 | if (flags & O_PATH) |
| 6417 | break; |
| 6418 | #endif |
| 6419 | r = -ELOOP; |
| 6420 | goto out; |
| 6421 | case S_IFDIR: |
| 6422 | if (want & CLIENT_MAY_WRITE) { |
| 6423 | r = -EISDIR; |
| 6424 | goto out; |
| 6425 | } |
| 6426 | break; |
| 6427 | } |
| 6428 | |
| 6429 | r = _getattr_for_perm(in, perms); |
| 6430 | if (r < 0) |
| 6431 | goto out; |
| 6432 | |
| 6433 | r = inode_permission(in, perms, want); |
| 6434 | out: |
| 6435 | ldout(cct, 3) << __func__ << " " << in << " = " << r << dendl; |
| 6436 | return r; |
| 6437 | } |
| 6438 | |
| 6439 | int Client::may_lookup(const InodeRef& dir, const UserPerm& perms) |
| 6440 | { |