diff options
-rw-r--r-- | fs/namei.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c index bbc15c237558..2a40409e3e03 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1486,24 +1486,22 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1486 | if (!inode) | 1486 | if (!inode) |
1487 | return -ENOENT; | 1487 | return -ENOENT; |
1488 | 1488 | ||
1489 | if (S_ISLNK(inode->i_mode)) | 1489 | switch (inode->i_mode & S_IFMT) { |
1490 | case S_IFLNK: | ||
1490 | return -ELOOP; | 1491 | return -ELOOP; |
1491 | 1492 | case S_IFDIR: | |
1492 | if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE)) | 1493 | if (acc_mode & MAY_WRITE) |
1493 | return -EISDIR; | 1494 | return -EISDIR; |
1494 | 1495 | break; | |
1495 | /* | 1496 | case S_IFBLK: |
1496 | * FIFO's, sockets and device files are special: they don't | 1497 | case S_IFCHR: |
1497 | * actually live on the filesystem itself, and as such you | ||
1498 | * can write to them even if the filesystem is read-only. | ||
1499 | */ | ||
1500 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | ||
1501 | flag &= ~O_TRUNC; | ||
1502 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { | ||
1503 | if (path->mnt->mnt_flags & MNT_NODEV) | 1498 | if (path->mnt->mnt_flags & MNT_NODEV) |
1504 | return -EACCES; | 1499 | return -EACCES; |
1505 | 1500 | /*FALLTHRU*/ | |
1501 | case S_IFIFO: | ||
1502 | case S_IFSOCK: | ||
1506 | flag &= ~O_TRUNC; | 1503 | flag &= ~O_TRUNC; |
1504 | break; | ||
1507 | } | 1505 | } |
1508 | 1506 | ||
1509 | error = inode_permission(inode, acc_mode); | 1507 | error = inode_permission(inode, acc_mode); |