diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/fs/namei.c b/fs/namei.c index 199317642ad6..d040ce11785d 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1473,7 +1473,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1473 | error = security_inode_create(dir, dentry, mode); | 1473 | error = security_inode_create(dir, dentry, mode); |
1474 | if (error) | 1474 | if (error) |
1475 | return error; | 1475 | return error; |
1476 | DQUOT_INIT(dir); | 1476 | vfs_dq_init(dir); |
1477 | error = dir->i_op->create(dir, dentry, mode, nd); | 1477 | error = dir->i_op->create(dir, dentry, mode, nd); |
1478 | if (!error) | 1478 | if (!error) |
1479 | fsnotify_create(dir, dentry); | 1479 | fsnotify_create(dir, dentry); |
@@ -1489,24 +1489,22 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1489 | if (!inode) | 1489 | if (!inode) |
1490 | return -ENOENT; | 1490 | return -ENOENT; |
1491 | 1491 | ||
1492 | if (S_ISLNK(inode->i_mode)) | 1492 | switch (inode->i_mode & S_IFMT) { |
1493 | case S_IFLNK: | ||
1493 | return -ELOOP; | 1494 | return -ELOOP; |
1494 | 1495 | case S_IFDIR: | |
1495 | if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE)) | 1496 | if (acc_mode & MAY_WRITE) |
1496 | return -EISDIR; | 1497 | return -EISDIR; |
1497 | 1498 | break; | |
1498 | /* | 1499 | case S_IFBLK: |
1499 | * FIFO's, sockets and device files are special: they don't | 1500 | case S_IFCHR: |
1500 | * actually live on the filesystem itself, and as such you | ||
1501 | * can write to them even if the filesystem is read-only. | ||
1502 | */ | ||
1503 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | ||
1504 | flag &= ~O_TRUNC; | ||
1505 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { | ||
1506 | if (path->mnt->mnt_flags & MNT_NODEV) | 1501 | if (path->mnt->mnt_flags & MNT_NODEV) |
1507 | return -EACCES; | 1502 | return -EACCES; |
1508 | 1503 | /*FALLTHRU*/ | |
1504 | case S_IFIFO: | ||
1505 | case S_IFSOCK: | ||
1509 | flag &= ~O_TRUNC; | 1506 | flag &= ~O_TRUNC; |
1507 | break; | ||
1510 | } | 1508 | } |
1511 | 1509 | ||
1512 | error = inode_permission(inode, acc_mode); | 1510 | error = inode_permission(inode, acc_mode); |
@@ -1552,7 +1550,7 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1552 | error = security_path_truncate(path, 0, | 1550 | error = security_path_truncate(path, 0, |
1553 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); | 1551 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); |
1554 | if (!error) { | 1552 | if (!error) { |
1555 | DQUOT_INIT(inode); | 1553 | vfs_dq_init(inode); |
1556 | 1554 | ||
1557 | error = do_truncate(dentry, 0, | 1555 | error = do_truncate(dentry, 0, |
1558 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, | 1556 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, |
@@ -1563,7 +1561,7 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1563 | return error; | 1561 | return error; |
1564 | } else | 1562 | } else |
1565 | if (flag & FMODE_WRITE) | 1563 | if (flag & FMODE_WRITE) |
1566 | DQUOT_INIT(inode); | 1564 | vfs_dq_init(inode); |
1567 | 1565 | ||
1568 | return 0; | 1566 | return 0; |
1569 | } | 1567 | } |
@@ -1946,7 +1944,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1946 | if (error) | 1944 | if (error) |
1947 | return error; | 1945 | return error; |
1948 | 1946 | ||
1949 | DQUOT_INIT(dir); | 1947 | vfs_dq_init(dir); |
1950 | error = dir->i_op->mknod(dir, dentry, mode, dev); | 1948 | error = dir->i_op->mknod(dir, dentry, mode, dev); |
1951 | if (!error) | 1949 | if (!error) |
1952 | fsnotify_create(dir, dentry); | 1950 | fsnotify_create(dir, dentry); |
@@ -2045,7 +2043,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
2045 | if (error) | 2043 | if (error) |
2046 | return error; | 2044 | return error; |
2047 | 2045 | ||
2048 | DQUOT_INIT(dir); | 2046 | vfs_dq_init(dir); |
2049 | error = dir->i_op->mkdir(dir, dentry, mode); | 2047 | error = dir->i_op->mkdir(dir, dentry, mode); |
2050 | if (!error) | 2048 | if (!error) |
2051 | fsnotify_mkdir(dir, dentry); | 2049 | fsnotify_mkdir(dir, dentry); |
@@ -2131,7 +2129,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2131 | if (!dir->i_op->rmdir) | 2129 | if (!dir->i_op->rmdir) |
2132 | return -EPERM; | 2130 | return -EPERM; |
2133 | 2131 | ||
2134 | DQUOT_INIT(dir); | 2132 | vfs_dq_init(dir); |
2135 | 2133 | ||
2136 | mutex_lock(&dentry->d_inode->i_mutex); | 2134 | mutex_lock(&dentry->d_inode->i_mutex); |
2137 | dentry_unhash(dentry); | 2135 | dentry_unhash(dentry); |
@@ -2218,7 +2216,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2218 | if (!dir->i_op->unlink) | 2216 | if (!dir->i_op->unlink) |
2219 | return -EPERM; | 2217 | return -EPERM; |
2220 | 2218 | ||
2221 | DQUOT_INIT(dir); | 2219 | vfs_dq_init(dir); |
2222 | 2220 | ||
2223 | mutex_lock(&dentry->d_inode->i_mutex); | 2221 | mutex_lock(&dentry->d_inode->i_mutex); |
2224 | if (d_mountpoint(dentry)) | 2222 | if (d_mountpoint(dentry)) |
@@ -2329,7 +2327,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) | |||
2329 | if (error) | 2327 | if (error) |
2330 | return error; | 2328 | return error; |
2331 | 2329 | ||
2332 | DQUOT_INIT(dir); | 2330 | vfs_dq_init(dir); |
2333 | error = dir->i_op->symlink(dir, dentry, oldname); | 2331 | error = dir->i_op->symlink(dir, dentry, oldname); |
2334 | if (!error) | 2332 | if (!error) |
2335 | fsnotify_create(dir, dentry); | 2333 | fsnotify_create(dir, dentry); |
@@ -2413,7 +2411,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2413 | return error; | 2411 | return error; |
2414 | 2412 | ||
2415 | mutex_lock(&inode->i_mutex); | 2413 | mutex_lock(&inode->i_mutex); |
2416 | DQUOT_INIT(dir); | 2414 | vfs_dq_init(dir); |
2417 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2415 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2418 | mutex_unlock(&inode->i_mutex); | 2416 | mutex_unlock(&inode->i_mutex); |
2419 | if (!error) | 2417 | if (!error) |
@@ -2612,8 +2610,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2612 | if (!old_dir->i_op->rename) | 2610 | if (!old_dir->i_op->rename) |
2613 | return -EPERM; | 2611 | return -EPERM; |
2614 | 2612 | ||
2615 | DQUOT_INIT(old_dir); | 2613 | vfs_dq_init(old_dir); |
2616 | DQUOT_INIT(new_dir); | 2614 | vfs_dq_init(new_dir); |
2617 | 2615 | ||
2618 | old_name = fsnotify_oldname_init(old_dentry->d_name.name); | 2616 | old_name = fsnotify_oldname_init(old_dentry->d_name.name); |
2619 | 2617 | ||