diff options
author | Chao Yu <yuchao0@huawei.com> | 2017-07-08 12:13:07 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2017-07-09 02:12:27 -0400 |
commit | 0abd675e97e60d40e61d59532f8118b0e439034e (patch) | |
tree | 4aac496af2e665936486dd067b71a0087e091685 | |
parent | d29460e5cfc9bc2241886f9f60d0650ad745cf10 (diff) |
f2fs: support plain user/group quota
This patch adds to support plain user/group quota.
Change Note by Jaegeuk Kim.
- Use f2fs page cache for quota files in order to consider garbage collection.
so, quota files are not tolerable for sudden power-cuts, so user needs to do
quotacheck.
- setattr() calls dquot_transfer which will transfer inode->i_blocks.
We can't reclaim that during f2fs_evict_inode(). So, we need to count
node blocks as well in order to match i_blocks with dquot's space.
Note that, Chao wrote a patch to count inode->i_blocks without inode block.
(f2fs: don't count inode block in in-memory inode.i_blocks)
- in f2fs_remount, we need to make RW in prior to dquot_resume.
- handle fault_injection case during f2fs_quota_off_umount
- TODO: Project quota
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | Documentation/filesystems/f2fs.txt | 2 | ||||
-rw-r--r-- | fs/f2fs/data.c | 10 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 88 | ||||
-rw-r--r-- | fs/f2fs/file.c | 34 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 5 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 66 | ||||
-rw-r--r-- | fs/f2fs/node.c | 9 | ||||
-rw-r--r-- | fs/f2fs/super.c | 280 |
8 files changed, 454 insertions, 40 deletions
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 8b04a6359530..273ccb26885e 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt | |||
@@ -162,6 +162,8 @@ mode=%s Control block allocation mode which supports "adaptive" | |||
162 | writes towards main area. | 162 | writes towards main area. |
163 | io_bits=%u Set the bit size of write IO requests. It should be set | 163 | io_bits=%u Set the bit size of write IO requests. It should be set |
164 | with "mode=lfs". | 164 | with "mode=lfs". |
165 | usrquota Enable plain user disk quota accounting. | ||
166 | grpquota Enable plain group disk quota accounting. | ||
165 | 167 | ||
166 | ================================================================================ | 168 | ================================================================================ |
167 | DEBUGFS ENTRIES | 169 | DEBUGFS ENTRIES |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 7dd5fb647d43..251356859476 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -491,14 +491,15 @@ void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr) | |||
491 | int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count) | 491 | int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count) |
492 | { | 492 | { |
493 | struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); | 493 | struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); |
494 | int err; | ||
494 | 495 | ||
495 | if (!count) | 496 | if (!count) |
496 | return 0; | 497 | return 0; |
497 | 498 | ||
498 | if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) | 499 | if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) |
499 | return -EPERM; | 500 | return -EPERM; |
500 | if (unlikely(!inc_valid_block_count(sbi, dn->inode, &count))) | 501 | if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count)))) |
501 | return -ENOSPC; | 502 | return err; |
502 | 503 | ||
503 | trace_f2fs_reserve_new_blocks(dn->inode, dn->nid, | 504 | trace_f2fs_reserve_new_blocks(dn->inode, dn->nid, |
504 | dn->ofs_in_node, count); | 505 | dn->ofs_in_node, count); |
@@ -749,6 +750,7 @@ static int __allocate_data_block(struct dnode_of_data *dn) | |||
749 | struct node_info ni; | 750 | struct node_info ni; |
750 | pgoff_t fofs; | 751 | pgoff_t fofs; |
751 | blkcnt_t count = 1; | 752 | blkcnt_t count = 1; |
753 | int err; | ||
752 | 754 | ||
753 | if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) | 755 | if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) |
754 | return -EPERM; | 756 | return -EPERM; |
@@ -757,8 +759,8 @@ static int __allocate_data_block(struct dnode_of_data *dn) | |||
757 | if (dn->data_blkaddr == NEW_ADDR) | 759 | if (dn->data_blkaddr == NEW_ADDR) |
758 | goto alloc; | 760 | goto alloc; |
759 | 761 | ||
760 | if (unlikely(!inc_valid_block_count(sbi, dn->inode, &count))) | 762 | if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count)))) |
761 | return -ENOSPC; | 763 | return err; |
762 | 764 | ||
763 | alloc: | 765 | alloc: |
764 | get_node_info(sbi, dn->nid, &ni); | 766 | get_node_info(sbi, dn->nid, &ni); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ced78035a416..42c39f0bfd88 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
23 | #include <linux/bio.h> | 23 | #include <linux/bio.h> |
24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
25 | #include <linux/quotaops.h> | ||
25 | #ifdef CONFIG_F2FS_FS_ENCRYPTION | 26 | #ifdef CONFIG_F2FS_FS_ENCRYPTION |
26 | #include <linux/fscrypt_supp.h> | 27 | #include <linux/fscrypt_supp.h> |
27 | #else | 28 | #else |
@@ -88,6 +89,8 @@ extern char *fault_name[FAULT_MAX]; | |||
88 | #define F2FS_MOUNT_FAULT_INJECTION 0x00010000 | 89 | #define F2FS_MOUNT_FAULT_INJECTION 0x00010000 |
89 | #define F2FS_MOUNT_ADAPTIVE 0x00020000 | 90 | #define F2FS_MOUNT_ADAPTIVE 0x00020000 |
90 | #define F2FS_MOUNT_LFS 0x00040000 | 91 | #define F2FS_MOUNT_LFS 0x00040000 |
92 | #define F2FS_MOUNT_USRQUOTA 0x00080000 | ||
93 | #define F2FS_MOUNT_GRPQUOTA 0x00100000 | ||
91 | 94 | ||
92 | #define clear_opt(sbi, option) ((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option) | 95 | #define clear_opt(sbi, option) ((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option) |
93 | #define set_opt(sbi, option) ((sbi)->mount_opt.opt |= F2FS_MOUNT_##option) | 96 | #define set_opt(sbi, option) ((sbi)->mount_opt.opt |= F2FS_MOUNT_##option) |
@@ -521,6 +524,12 @@ struct f2fs_inode_info { | |||
521 | nid_t i_xattr_nid; /* node id that contains xattrs */ | 524 | nid_t i_xattr_nid; /* node id that contains xattrs */ |
522 | loff_t last_disk_size; /* lastly written file size */ | 525 | loff_t last_disk_size; /* lastly written file size */ |
523 | 526 | ||
527 | #ifdef CONFIG_QUOTA | ||
528 | struct dquot *i_dquot[MAXQUOTAS]; | ||
529 | |||
530 | /* quota space reservation, managed internally by quota code */ | ||
531 | qsize_t i_reserved_quota; | ||
532 | #endif | ||
524 | struct list_head dirty_list; /* dirty list for dirs and files */ | 533 | struct list_head dirty_list; /* dirty list for dirs and files */ |
525 | struct list_head gdirty_list; /* linked in global dirty list */ | 534 | struct list_head gdirty_list; /* linked in global dirty list */ |
526 | struct list_head inmem_pages; /* inmemory pages managed by f2fs */ | 535 | struct list_head inmem_pages; /* inmemory pages managed by f2fs */ |
@@ -1376,17 +1385,23 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs) | |||
1376 | return ofs == XATTR_NODE_OFFSET; | 1385 | return ofs == XATTR_NODE_OFFSET; |
1377 | } | 1386 | } |
1378 | 1387 | ||
1379 | static inline void f2fs_i_blocks_write(struct inode *, block_t, bool); | 1388 | static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool); |
1380 | static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, | 1389 | static inline int inc_valid_block_count(struct f2fs_sb_info *sbi, |
1381 | struct inode *inode, blkcnt_t *count) | 1390 | struct inode *inode, blkcnt_t *count) |
1382 | { | 1391 | { |
1383 | blkcnt_t diff; | 1392 | blkcnt_t diff = 0, release = 0; |
1384 | block_t avail_user_block_count; | 1393 | block_t avail_user_block_count; |
1394 | int ret; | ||
1395 | |||
1396 | ret = dquot_reserve_block(inode, *count); | ||
1397 | if (ret) | ||
1398 | return ret; | ||
1385 | 1399 | ||
1386 | #ifdef CONFIG_F2FS_FAULT_INJECTION | 1400 | #ifdef CONFIG_F2FS_FAULT_INJECTION |
1387 | if (time_to_inject(sbi, FAULT_BLOCK)) { | 1401 | if (time_to_inject(sbi, FAULT_BLOCK)) { |
1388 | f2fs_show_injection_info(FAULT_BLOCK); | 1402 | f2fs_show_injection_info(FAULT_BLOCK); |
1389 | return false; | 1403 | release = *count; |
1404 | goto enospc; | ||
1390 | } | 1405 | } |
1391 | #endif | 1406 | #endif |
1392 | /* | 1407 | /* |
@@ -1401,17 +1416,24 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, | |||
1401 | if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) { | 1416 | if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) { |
1402 | diff = sbi->total_valid_block_count - avail_user_block_count; | 1417 | diff = sbi->total_valid_block_count - avail_user_block_count; |
1403 | *count -= diff; | 1418 | *count -= diff; |
1419 | release = diff; | ||
1404 | sbi->total_valid_block_count = avail_user_block_count; | 1420 | sbi->total_valid_block_count = avail_user_block_count; |
1405 | if (!*count) { | 1421 | if (!*count) { |
1406 | spin_unlock(&sbi->stat_lock); | 1422 | spin_unlock(&sbi->stat_lock); |
1407 | percpu_counter_sub(&sbi->alloc_valid_block_count, diff); | 1423 | percpu_counter_sub(&sbi->alloc_valid_block_count, diff); |
1408 | return false; | 1424 | goto enospc; |
1409 | } | 1425 | } |
1410 | } | 1426 | } |
1411 | spin_unlock(&sbi->stat_lock); | 1427 | spin_unlock(&sbi->stat_lock); |
1412 | 1428 | ||
1413 | f2fs_i_blocks_write(inode, *count, true); | 1429 | if (release) |
1414 | return true; | 1430 | dquot_release_reservation_block(inode, release); |
1431 | f2fs_i_blocks_write(inode, *count, true, true); | ||
1432 | return 0; | ||
1433 | |||
1434 | enospc: | ||
1435 | dquot_release_reservation_block(inode, release); | ||
1436 | return -ENOSPC; | ||
1415 | } | 1437 | } |
1416 | 1438 | ||
1417 | static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, | 1439 | static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, |
@@ -1425,7 +1447,7 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, | |||
1425 | f2fs_bug_on(sbi, inode->i_blocks < sectors); | 1447 | f2fs_bug_on(sbi, inode->i_blocks < sectors); |
1426 | sbi->total_valid_block_count -= (block_t)count; | 1448 | sbi->total_valid_block_count -= (block_t)count; |
1427 | spin_unlock(&sbi->stat_lock); | 1449 | spin_unlock(&sbi->stat_lock); |
1428 | f2fs_i_blocks_write(inode, count, false); | 1450 | f2fs_i_blocks_write(inode, count, false, true); |
1429 | } | 1451 | } |
1430 | 1452 | ||
1431 | static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type) | 1453 | static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type) |
@@ -1554,11 +1576,18 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi) | |||
1554 | return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum); | 1576 | return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum); |
1555 | } | 1577 | } |
1556 | 1578 | ||
1557 | static inline bool inc_valid_node_count(struct f2fs_sb_info *sbi, | 1579 | static inline int inc_valid_node_count(struct f2fs_sb_info *sbi, |
1558 | struct inode *inode, bool is_inode) | 1580 | struct inode *inode, bool is_inode) |
1559 | { | 1581 | { |
1560 | block_t valid_block_count; | 1582 | block_t valid_block_count; |
1561 | unsigned int valid_node_count; | 1583 | unsigned int valid_node_count; |
1584 | bool quota = inode && !is_inode; | ||
1585 | |||
1586 | if (quota) { | ||
1587 | int ret = dquot_reserve_block(inode, 1); | ||
1588 | if (ret) | ||
1589 | return ret; | ||
1590 | } | ||
1562 | 1591 | ||
1563 | spin_lock(&sbi->stat_lock); | 1592 | spin_lock(&sbi->stat_lock); |
1564 | 1593 | ||
@@ -1566,28 +1595,33 @@ static inline bool inc_valid_node_count(struct f2fs_sb_info *sbi, | |||
1566 | if (unlikely(valid_block_count + sbi->reserved_blocks > | 1595 | if (unlikely(valid_block_count + sbi->reserved_blocks > |
1567 | sbi->user_block_count)) { | 1596 | sbi->user_block_count)) { |
1568 | spin_unlock(&sbi->stat_lock); | 1597 | spin_unlock(&sbi->stat_lock); |
1569 | return false; | 1598 | goto enospc; |
1570 | } | 1599 | } |
1571 | 1600 | ||
1572 | valid_node_count = sbi->total_valid_node_count + 1; | 1601 | valid_node_count = sbi->total_valid_node_count + 1; |
1573 | if (unlikely(valid_node_count > sbi->total_node_count)) { | 1602 | if (unlikely(valid_node_count > sbi->total_node_count)) { |
1574 | spin_unlock(&sbi->stat_lock); | 1603 | spin_unlock(&sbi->stat_lock); |
1575 | return false; | 1604 | goto enospc; |
1576 | } | 1605 | } |
1577 | 1606 | ||
1607 | sbi->total_valid_node_count++; | ||
1608 | sbi->total_valid_block_count++; | ||
1609 | spin_unlock(&sbi->stat_lock); | ||
1610 | |||
1578 | if (inode) { | 1611 | if (inode) { |
1579 | if (is_inode) | 1612 | if (is_inode) |
1580 | f2fs_mark_inode_dirty_sync(inode, true); | 1613 | f2fs_mark_inode_dirty_sync(inode, true); |
1581 | else | 1614 | else |
1582 | f2fs_i_blocks_write(inode, 1, true); | 1615 | f2fs_i_blocks_write(inode, 1, true, true); |
1583 | } | 1616 | } |
1584 | 1617 | ||
1585 | sbi->total_valid_node_count++; | ||
1586 | sbi->total_valid_block_count++; | ||
1587 | spin_unlock(&sbi->stat_lock); | ||
1588 | |||
1589 | percpu_counter_inc(&sbi->alloc_valid_block_count); | 1618 | percpu_counter_inc(&sbi->alloc_valid_block_count); |
1590 | return true; | 1619 | return 0; |
1620 | |||
1621 | enospc: | ||
1622 | if (quota) | ||
1623 | dquot_release_reservation_block(inode, 1); | ||
1624 | return -ENOSPC; | ||
1591 | } | 1625 | } |
1592 | 1626 | ||
1593 | static inline void dec_valid_node_count(struct f2fs_sb_info *sbi, | 1627 | static inline void dec_valid_node_count(struct f2fs_sb_info *sbi, |
@@ -1599,12 +1633,13 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi, | |||
1599 | f2fs_bug_on(sbi, !sbi->total_valid_node_count); | 1633 | f2fs_bug_on(sbi, !sbi->total_valid_node_count); |
1600 | f2fs_bug_on(sbi, !is_inode && !inode->i_blocks); | 1634 | f2fs_bug_on(sbi, !is_inode && !inode->i_blocks); |
1601 | 1635 | ||
1602 | if (!is_inode) | ||
1603 | f2fs_i_blocks_write(inode, 1, false); | ||
1604 | sbi->total_valid_node_count--; | 1636 | sbi->total_valid_node_count--; |
1605 | sbi->total_valid_block_count--; | 1637 | sbi->total_valid_block_count--; |
1606 | 1638 | ||
1607 | spin_unlock(&sbi->stat_lock); | 1639 | spin_unlock(&sbi->stat_lock); |
1640 | |||
1641 | if (!is_inode) | ||
1642 | f2fs_i_blocks_write(inode, 1, false, true); | ||
1608 | } | 1643 | } |
1609 | 1644 | ||
1610 | static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi) | 1645 | static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi) |
@@ -1879,14 +1914,21 @@ static inline void f2fs_i_links_write(struct inode *inode, bool inc) | |||
1879 | } | 1914 | } |
1880 | 1915 | ||
1881 | static inline void f2fs_i_blocks_write(struct inode *inode, | 1916 | static inline void f2fs_i_blocks_write(struct inode *inode, |
1882 | block_t diff, bool add) | 1917 | block_t diff, bool add, bool claim) |
1883 | { | 1918 | { |
1884 | bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); | 1919 | bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE); |
1885 | bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); | 1920 | bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER); |
1886 | blkcnt_t sectors = diff << F2FS_LOG_SECTORS_PER_BLOCK; | ||
1887 | 1921 | ||
1888 | inode->i_blocks = add ? inode->i_blocks + sectors : | 1922 | /* add = 1, claim = 1 should be dquot_reserve_block in pair */ |
1889 | inode->i_blocks - sectors; | 1923 | if (add) { |
1924 | if (claim) | ||
1925 | dquot_claim_block(inode, diff); | ||
1926 | else | ||
1927 | dquot_alloc_block_nofail(inode, diff); | ||
1928 | } else { | ||
1929 | dquot_free_block(inode, diff); | ||
1930 | } | ||
1931 | |||
1890 | f2fs_mark_inode_dirty_sync(inode, true); | 1932 | f2fs_mark_inode_dirty_sync(inode, true); |
1891 | if (clean || recover) | 1933 | if (clean || recover) |
1892 | set_inode_flag(inode, FI_AUTO_RECOVER); | 1934 | set_inode_flag(inode, FI_AUTO_RECOVER); |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3f56b27e761b..527c9f36d971 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -442,11 +442,10 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
442 | 442 | ||
443 | static int f2fs_file_open(struct inode *inode, struct file *filp) | 443 | static int f2fs_file_open(struct inode *inode, struct file *filp) |
444 | { | 444 | { |
445 | int ret = generic_file_open(inode, filp); | ||
446 | struct dentry *dir; | 445 | struct dentry *dir; |
447 | 446 | ||
448 | if (!ret && f2fs_encrypted_inode(inode)) { | 447 | if (f2fs_encrypted_inode(inode)) { |
449 | ret = fscrypt_get_encryption_info(inode); | 448 | int ret = fscrypt_get_encryption_info(inode); |
450 | if (ret) | 449 | if (ret) |
451 | return -EACCES; | 450 | return -EACCES; |
452 | if (!fscrypt_has_encryption_key(inode)) | 451 | if (!fscrypt_has_encryption_key(inode)) |
@@ -459,7 +458,7 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) | |||
459 | return -EPERM; | 458 | return -EPERM; |
460 | } | 459 | } |
461 | dput(dir); | 460 | dput(dir); |
462 | return ret; | 461 | return dquot_file_open(inode, filp); |
463 | } | 462 | } |
464 | 463 | ||
465 | int truncate_data_blocks_range(struct dnode_of_data *dn, int count) | 464 | int truncate_data_blocks_range(struct dnode_of_data *dn, int count) |
@@ -710,6 +709,20 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) | |||
710 | if (err) | 709 | if (err) |
711 | return err; | 710 | return err; |
712 | 711 | ||
712 | if (is_quota_modification(inode, attr)) { | ||
713 | err = dquot_initialize(inode); | ||
714 | if (err) | ||
715 | return err; | ||
716 | } | ||
717 | if ((attr->ia_valid & ATTR_UID && | ||
718 | !uid_eq(attr->ia_uid, inode->i_uid)) || | ||
719 | (attr->ia_valid & ATTR_GID && | ||
720 | !gid_eq(attr->ia_gid, inode->i_gid))) { | ||
721 | err = dquot_transfer(inode, attr); | ||
722 | if (err) | ||
723 | return err; | ||
724 | } | ||
725 | |||
713 | if (attr->ia_valid & ATTR_SIZE) { | 726 | if (attr->ia_valid & ATTR_SIZE) { |
714 | if (f2fs_encrypted_inode(inode)) { | 727 | if (f2fs_encrypted_inode(inode)) { |
715 | err = fscrypt_get_encryption_info(inode); | 728 | err = fscrypt_get_encryption_info(inode); |
@@ -996,9 +1009,9 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, | |||
996 | 1009 | ||
997 | if (do_replace[i]) { | 1010 | if (do_replace[i]) { |
998 | f2fs_i_blocks_write(src_inode, | 1011 | f2fs_i_blocks_write(src_inode, |
999 | 1, false); | 1012 | 1, false, false); |
1000 | f2fs_i_blocks_write(dst_inode, | 1013 | f2fs_i_blocks_write(dst_inode, |
1001 | 1, true); | 1014 | 1, true, false); |
1002 | f2fs_replace_block(sbi, &dn, dn.data_blkaddr, | 1015 | f2fs_replace_block(sbi, &dn, dn.data_blkaddr, |
1003 | blkaddr[i], ni.version, true, false); | 1016 | blkaddr[i], ni.version, true, false); |
1004 | 1017 | ||
@@ -1523,6 +1536,13 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) | |||
1523 | 1536 | ||
1524 | inode_lock(inode); | 1537 | inode_lock(inode); |
1525 | 1538 | ||
1539 | /* Is it quota file? Do not allow user to mess with it */ | ||
1540 | if (IS_NOQUOTA(inode)) { | ||
1541 | inode_unlock(inode); | ||
1542 | ret = -EPERM; | ||
1543 | goto unlock_out; | ||
1544 | } | ||
1545 | |||
1526 | flags = f2fs_mask_flags(inode->i_mode, flags); | 1546 | flags = f2fs_mask_flags(inode->i_mode, flags); |
1527 | 1547 | ||
1528 | oldflags = fi->i_flags; | 1548 | oldflags = fi->i_flags; |
@@ -1542,7 +1562,7 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) | |||
1542 | inode->i_ctime = current_time(inode); | 1562 | inode->i_ctime = current_time(inode); |
1543 | f2fs_set_inode_flags(inode); | 1563 | f2fs_set_inode_flags(inode); |
1544 | f2fs_mark_inode_dirty_sync(inode, false); | 1564 | f2fs_mark_inode_dirty_sync(inode, false); |
1545 | 1565 | unlock_out: | |
1546 | inode_unlock(inode); | 1566 | inode_unlock(inode); |
1547 | out: | 1567 | out: |
1548 | mnt_drop_write_file(filp); | 1568 | mnt_drop_write_file(filp); |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index e42a7a8805dc..6cd312a17c69 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -373,6 +373,8 @@ void f2fs_evict_inode(struct inode *inode) | |||
373 | if (inode->i_nlink || is_bad_inode(inode)) | 373 | if (inode->i_nlink || is_bad_inode(inode)) |
374 | goto no_delete; | 374 | goto no_delete; |
375 | 375 | ||
376 | dquot_initialize(inode); | ||
377 | |||
376 | remove_ino_entry(sbi, inode->i_ino, APPEND_INO); | 378 | remove_ino_entry(sbi, inode->i_ino, APPEND_INO); |
377 | remove_ino_entry(sbi, inode->i_ino, UPDATE_INO); | 379 | remove_ino_entry(sbi, inode->i_ino, UPDATE_INO); |
378 | 380 | ||
@@ -405,8 +407,11 @@ retry: | |||
405 | 407 | ||
406 | if (err) | 408 | if (err) |
407 | update_inode_page(inode); | 409 | update_inode_page(inode); |
410 | dquot_free_inode(inode); | ||
408 | sb_end_intwrite(inode->i_sb); | 411 | sb_end_intwrite(inode->i_sb); |
409 | no_delete: | 412 | no_delete: |
413 | dquot_drop(inode); | ||
414 | |||
410 | stat_dec_inline_xattr(inode); | 415 | stat_dec_inline_xattr(inode); |
411 | stat_dec_inline_dir(inode); | 416 | stat_dec_inline_dir(inode); |
412 | stat_dec_inline_inode(inode); | 417 | stat_dec_inline_inode(inode); |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index b75dc2f4ad57..760d85223c81 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/dcache.h> | 16 | #include <linux/dcache.h> |
17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
18 | #include <linux/quotaops.h> | ||
18 | 19 | ||
19 | #include "f2fs.h" | 20 | #include "f2fs.h" |
20 | #include "node.h" | 21 | #include "node.h" |
@@ -42,6 +43,8 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) | |||
42 | } | 43 | } |
43 | f2fs_unlock_op(sbi); | 44 | f2fs_unlock_op(sbi); |
44 | 45 | ||
46 | nid_free = true; | ||
47 | |||
45 | inode_init_owner(inode, dir, mode); | 48 | inode_init_owner(inode, dir, mode); |
46 | 49 | ||
47 | inode->i_ino = ino; | 50 | inode->i_ino = ino; |
@@ -52,10 +55,17 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) | |||
52 | err = insert_inode_locked(inode); | 55 | err = insert_inode_locked(inode); |
53 | if (err) { | 56 | if (err) { |
54 | err = -EINVAL; | 57 | err = -EINVAL; |
55 | nid_free = true; | ||
56 | goto fail; | 58 | goto fail; |
57 | } | 59 | } |
58 | 60 | ||
61 | err = dquot_initialize(inode); | ||
62 | if (err) | ||
63 | goto fail_drop; | ||
64 | |||
65 | err = dquot_alloc_inode(inode); | ||
66 | if (err) | ||
67 | goto fail_drop; | ||
68 | |||
59 | /* If the directory encrypted, then we should encrypt the inode. */ | 69 | /* If the directory encrypted, then we should encrypt the inode. */ |
60 | if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) | 70 | if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) |
61 | f2fs_set_encrypted_inode(inode); | 71 | f2fs_set_encrypted_inode(inode); |
@@ -85,6 +95,16 @@ fail: | |||
85 | set_inode_flag(inode, FI_FREE_NID); | 95 | set_inode_flag(inode, FI_FREE_NID); |
86 | iput(inode); | 96 | iput(inode); |
87 | return ERR_PTR(err); | 97 | return ERR_PTR(err); |
98 | fail_drop: | ||
99 | trace_f2fs_new_inode(inode, err); | ||
100 | dquot_drop(inode); | ||
101 | inode->i_flags |= S_NOQUOTA; | ||
102 | if (nid_free) | ||
103 | set_inode_flag(inode, FI_FREE_NID); | ||
104 | clear_nlink(inode); | ||
105 | unlock_new_inode(inode); | ||
106 | iput(inode); | ||
107 | return ERR_PTR(err); | ||
88 | } | 108 | } |
89 | 109 | ||
90 | static int is_multimedia_file(const unsigned char *s, const char *sub) | 110 | static int is_multimedia_file(const unsigned char *s, const char *sub) |
@@ -136,6 +156,10 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
136 | nid_t ino = 0; | 156 | nid_t ino = 0; |
137 | int err; | 157 | int err; |
138 | 158 | ||
159 | err = dquot_initialize(dir); | ||
160 | if (err) | ||
161 | return err; | ||
162 | |||
139 | inode = f2fs_new_inode(dir, mode); | 163 | inode = f2fs_new_inode(dir, mode); |
140 | if (IS_ERR(inode)) | 164 | if (IS_ERR(inode)) |
141 | return PTR_ERR(inode); | 165 | return PTR_ERR(inode); |
@@ -180,6 +204,10 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, | |||
180 | !fscrypt_has_permitted_context(dir, inode)) | 204 | !fscrypt_has_permitted_context(dir, inode)) |
181 | return -EPERM; | 205 | return -EPERM; |
182 | 206 | ||
207 | err = dquot_initialize(dir); | ||
208 | if (err) | ||
209 | return err; | ||
210 | |||
183 | f2fs_balance_fs(sbi, true); | 211 | f2fs_balance_fs(sbi, true); |
184 | 212 | ||
185 | inode->i_ctime = current_time(inode); | 213 | inode->i_ctime = current_time(inode); |
@@ -347,6 +375,10 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) | |||
347 | 375 | ||
348 | trace_f2fs_unlink_enter(dir, dentry); | 376 | trace_f2fs_unlink_enter(dir, dentry); |
349 | 377 | ||
378 | err = dquot_initialize(dir); | ||
379 | if (err) | ||
380 | return err; | ||
381 | |||
350 | de = f2fs_find_entry(dir, &dentry->d_name, &page); | 382 | de = f2fs_find_entry(dir, &dentry->d_name, &page); |
351 | if (!de) { | 383 | if (!de) { |
352 | if (IS_ERR(page)) | 384 | if (IS_ERR(page)) |
@@ -413,6 +445,10 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
413 | if (disk_link.len > dir->i_sb->s_blocksize) | 445 | if (disk_link.len > dir->i_sb->s_blocksize) |
414 | return -ENAMETOOLONG; | 446 | return -ENAMETOOLONG; |
415 | 447 | ||
448 | err = dquot_initialize(dir); | ||
449 | if (err) | ||
450 | return err; | ||
451 | |||
416 | inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 452 | inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
417 | if (IS_ERR(inode)) | 453 | if (IS_ERR(inode)) |
418 | return PTR_ERR(inode); | 454 | return PTR_ERR(inode); |
@@ -500,6 +536,10 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
500 | struct inode *inode; | 536 | struct inode *inode; |
501 | int err; | 537 | int err; |
502 | 538 | ||
539 | err = dquot_initialize(dir); | ||
540 | if (err) | ||
541 | return err; | ||
542 | |||
503 | inode = f2fs_new_inode(dir, S_IFDIR | mode); | 543 | inode = f2fs_new_inode(dir, S_IFDIR | mode); |
504 | if (IS_ERR(inode)) | 544 | if (IS_ERR(inode)) |
505 | return PTR_ERR(inode); | 545 | return PTR_ERR(inode); |
@@ -548,6 +588,10 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, | |||
548 | struct inode *inode; | 588 | struct inode *inode; |
549 | int err = 0; | 589 | int err = 0; |
550 | 590 | ||
591 | err = dquot_initialize(dir); | ||
592 | if (err) | ||
593 | return err; | ||
594 | |||
551 | inode = f2fs_new_inode(dir, mode); | 595 | inode = f2fs_new_inode(dir, mode); |
552 | if (IS_ERR(inode)) | 596 | if (IS_ERR(inode)) |
553 | return PTR_ERR(inode); | 597 | return PTR_ERR(inode); |
@@ -583,6 +627,10 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, | |||
583 | struct inode *inode; | 627 | struct inode *inode; |
584 | int err; | 628 | int err; |
585 | 629 | ||
630 | err = dquot_initialize(dir); | ||
631 | if (err) | ||
632 | return err; | ||
633 | |||
586 | inode = f2fs_new_inode(dir, mode); | 634 | inode = f2fs_new_inode(dir, mode); |
587 | if (IS_ERR(inode)) | 635 | if (IS_ERR(inode)) |
588 | return PTR_ERR(inode); | 636 | return PTR_ERR(inode); |
@@ -676,6 +724,14 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
676 | goto out; | 724 | goto out; |
677 | } | 725 | } |
678 | 726 | ||
727 | err = dquot_initialize(old_dir); | ||
728 | if (err) | ||
729 | goto out; | ||
730 | |||
731 | err = dquot_initialize(new_dir); | ||
732 | if (err) | ||
733 | goto out; | ||
734 | |||
679 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 735 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
680 | if (!old_entry) { | 736 | if (!old_entry) { |
681 | if (IS_ERR(old_page)) | 737 | if (IS_ERR(old_page)) |
@@ -856,6 +912,14 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
856 | !fscrypt_has_permitted_context(old_dir, new_inode))) | 912 | !fscrypt_has_permitted_context(old_dir, new_inode))) |
857 | return -EPERM; | 913 | return -EPERM; |
858 | 914 | ||
915 | err = dquot_initialize(old_dir); | ||
916 | if (err) | ||
917 | goto out; | ||
918 | |||
919 | err = dquot_initialize(new_dir); | ||
920 | if (err) | ||
921 | goto out; | ||
922 | |||
859 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 923 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
860 | if (!old_entry) { | 924 | if (!old_entry) { |
861 | if (IS_ERR(old_page)) | 925 | if (IS_ERR(old_page)) |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index b9f14ba6441f..3ed2f947f5da 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -1040,10 +1040,9 @@ struct page *new_node_page(struct dnode_of_data *dn, | |||
1040 | if (!page) | 1040 | if (!page) |
1041 | return ERR_PTR(-ENOMEM); | 1041 | return ERR_PTR(-ENOMEM); |
1042 | 1042 | ||
1043 | if (unlikely(!inc_valid_node_count(sbi, dn->inode, !ofs))) { | 1043 | if (unlikely((err = inc_valid_node_count(sbi, dn->inode, !ofs)))) |
1044 | err = -ENOSPC; | ||
1045 | goto fail; | 1044 | goto fail; |
1046 | } | 1045 | |
1047 | #ifdef CONFIG_F2FS_CHECK_FS | 1046 | #ifdef CONFIG_F2FS_CHECK_FS |
1048 | get_node_info(sbi, dn->nid, &new_ni); | 1047 | get_node_info(sbi, dn->nid, &new_ni); |
1049 | f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR); | 1048 | f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR); |
@@ -2210,7 +2209,7 @@ recover_xnid: | |||
2210 | /* 2: update xattr nid in inode */ | 2209 | /* 2: update xattr nid in inode */ |
2211 | remove_free_nid(sbi, new_xnid); | 2210 | remove_free_nid(sbi, new_xnid); |
2212 | f2fs_i_xnid_write(inode, new_xnid); | 2211 | f2fs_i_xnid_write(inode, new_xnid); |
2213 | if (unlikely(!inc_valid_node_count(sbi, inode, false))) | 2212 | if (unlikely(inc_valid_node_count(sbi, inode, false))) |
2214 | f2fs_bug_on(sbi, 1); | 2213 | f2fs_bug_on(sbi, 1); |
2215 | update_inode_page(inode); | 2214 | update_inode_page(inode); |
2216 | 2215 | ||
@@ -2268,7 +2267,7 @@ retry: | |||
2268 | new_ni = old_ni; | 2267 | new_ni = old_ni; |
2269 | new_ni.ino = ino; | 2268 | new_ni.ino = ino; |
2270 | 2269 | ||
2271 | if (unlikely(!inc_valid_node_count(sbi, NULL, true))) | 2270 | if (unlikely(inc_valid_node_count(sbi, NULL, true))) |
2272 | WARN_ON(1); | 2271 | WARN_ON(1); |
2273 | set_node_addr(sbi, &new_ni, NEW_ADDR, false); | 2272 | set_node_addr(sbi, &new_ni, NEW_ADDR, false); |
2274 | inc_valid_inode_count(sbi); | 2273 | inc_valid_inode_count(sbi); |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index af472f7968d0..dd92170e0d6d 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
23 | #include <linux/exportfs.h> | 23 | #include <linux/exportfs.h> |
24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
25 | #include <linux/quotaops.h> | ||
25 | #include <linux/f2fs_fs.h> | 26 | #include <linux/f2fs_fs.h> |
26 | #include <linux/sysfs.h> | 27 | #include <linux/sysfs.h> |
27 | 28 | ||
@@ -106,6 +107,8 @@ enum { | |||
106 | Opt_fault_injection, | 107 | Opt_fault_injection, |
107 | Opt_lazytime, | 108 | Opt_lazytime, |
108 | Opt_nolazytime, | 109 | Opt_nolazytime, |
110 | Opt_usrquota, | ||
111 | Opt_grpquota, | ||
109 | Opt_err, | 112 | Opt_err, |
110 | }; | 113 | }; |
111 | 114 | ||
@@ -141,6 +144,8 @@ static match_table_t f2fs_tokens = { | |||
141 | {Opt_fault_injection, "fault_injection=%u"}, | 144 | {Opt_fault_injection, "fault_injection=%u"}, |
142 | {Opt_lazytime, "lazytime"}, | 145 | {Opt_lazytime, "lazytime"}, |
143 | {Opt_nolazytime, "nolazytime"}, | 146 | {Opt_nolazytime, "nolazytime"}, |
147 | {Opt_usrquota, "usrquota"}, | ||
148 | {Opt_grpquota, "grpquota"}, | ||
144 | {Opt_err, NULL}, | 149 | {Opt_err, NULL}, |
145 | }; | 150 | }; |
146 | 151 | ||
@@ -380,6 +385,20 @@ static int parse_options(struct super_block *sb, char *options) | |||
380 | case Opt_nolazytime: | 385 | case Opt_nolazytime: |
381 | sb->s_flags &= ~MS_LAZYTIME; | 386 | sb->s_flags &= ~MS_LAZYTIME; |
382 | break; | 387 | break; |
388 | #ifdef CONFIG_QUOTA | ||
389 | case Opt_usrquota: | ||
390 | set_opt(sbi, USRQUOTA); | ||
391 | break; | ||
392 | case Opt_grpquota: | ||
393 | set_opt(sbi, GRPQUOTA); | ||
394 | break; | ||
395 | #else | ||
396 | case Opt_usrquota: | ||
397 | case Opt_grpquota: | ||
398 | f2fs_msg(sb, KERN_INFO, | ||
399 | "quota operations not supported"); | ||
400 | break; | ||
401 | #endif | ||
383 | default: | 402 | default: |
384 | f2fs_msg(sb, KERN_ERR, | 403 | f2fs_msg(sb, KERN_ERR, |
385 | "Unrecognized mount option \"%s\" or missing value", | 404 | "Unrecognized mount option \"%s\" or missing value", |
@@ -421,6 +440,10 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) | |||
421 | init_rwsem(&fi->dio_rwsem[WRITE]); | 440 | init_rwsem(&fi->dio_rwsem[WRITE]); |
422 | init_rwsem(&fi->i_mmap_sem); | 441 | init_rwsem(&fi->i_mmap_sem); |
423 | 442 | ||
443 | #ifdef CONFIG_QUOTA | ||
444 | memset(&fi->i_dquot, 0, sizeof(fi->i_dquot)); | ||
445 | fi->i_reserved_quota = 0; | ||
446 | #endif | ||
424 | /* Will be used by directory only */ | 447 | /* Will be used by directory only */ |
425 | fi->i_dir_level = F2FS_SB(sb)->dir_level; | 448 | fi->i_dir_level = F2FS_SB(sb)->dir_level; |
426 | return &fi->vfs_inode; | 449 | return &fi->vfs_inode; |
@@ -561,11 +584,14 @@ static void destroy_device_list(struct f2fs_sb_info *sbi) | |||
561 | kfree(sbi->devs); | 584 | kfree(sbi->devs); |
562 | } | 585 | } |
563 | 586 | ||
587 | static void f2fs_quota_off_umount(struct super_block *sb); | ||
564 | static void f2fs_put_super(struct super_block *sb) | 588 | static void f2fs_put_super(struct super_block *sb) |
565 | { | 589 | { |
566 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 590 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
567 | int i; | 591 | int i; |
568 | 592 | ||
593 | f2fs_quota_off_umount(sb); | ||
594 | |||
569 | /* prevent remaining shrinker jobs */ | 595 | /* prevent remaining shrinker jobs */ |
570 | mutex_lock(&sbi->umount_mutex); | 596 | mutex_lock(&sbi->umount_mutex); |
571 | 597 | ||
@@ -782,6 +808,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) | |||
782 | seq_printf(seq, ",fault_injection=%u", | 808 | seq_printf(seq, ",fault_injection=%u", |
783 | sbi->fault_info.inject_rate); | 809 | sbi->fault_info.inject_rate); |
784 | #endif | 810 | #endif |
811 | #ifdef CONFIG_QUOTA | ||
812 | if (test_opt(sbi, USRQUOTA)) | ||
813 | seq_puts(seq, ",usrquota"); | ||
814 | if (test_opt(sbi, GRPQUOTA)) | ||
815 | seq_puts(seq, ",grpquota"); | ||
816 | #endif | ||
785 | 817 | ||
786 | return 0; | 818 | return 0; |
787 | } | 819 | } |
@@ -822,6 +854,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) | |||
822 | { | 854 | { |
823 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 855 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
824 | struct f2fs_mount_info org_mount_opt; | 856 | struct f2fs_mount_info org_mount_opt; |
857 | unsigned long old_sb_flags; | ||
825 | int err, active_logs; | 858 | int err, active_logs; |
826 | bool need_restart_gc = false; | 859 | bool need_restart_gc = false; |
827 | bool need_stop_gc = false; | 860 | bool need_stop_gc = false; |
@@ -835,6 +868,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) | |||
835 | * need to restore them. | 868 | * need to restore them. |
836 | */ | 869 | */ |
837 | org_mount_opt = sbi->mount_opt; | 870 | org_mount_opt = sbi->mount_opt; |
871 | old_sb_flags = sb->s_flags; | ||
838 | active_logs = sbi->active_logs; | 872 | active_logs = sbi->active_logs; |
839 | 873 | ||
840 | /* recover superblocks we couldn't write due to previous RO mount */ | 874 | /* recover superblocks we couldn't write due to previous RO mount */ |
@@ -860,6 +894,16 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) | |||
860 | if (f2fs_readonly(sb) && (*flags & MS_RDONLY)) | 894 | if (f2fs_readonly(sb) && (*flags & MS_RDONLY)) |
861 | goto skip; | 895 | goto skip; |
862 | 896 | ||
897 | if (!f2fs_readonly(sb) && (*flags & MS_RDONLY)) { | ||
898 | err = dquot_suspend(sb, -1); | ||
899 | if (err < 0) | ||
900 | goto restore_opts; | ||
901 | } else { | ||
902 | /* dquot_resume needs RW */ | ||
903 | sb->s_flags &= ~MS_RDONLY; | ||
904 | dquot_resume(sb, -1); | ||
905 | } | ||
906 | |||
863 | /* disallow enable/disable extent_cache dynamically */ | 907 | /* disallow enable/disable extent_cache dynamically */ |
864 | if (no_extent_cache == !!test_opt(sbi, EXTENT_CACHE)) { | 908 | if (no_extent_cache == !!test_opt(sbi, EXTENT_CACHE)) { |
865 | err = -EINVAL; | 909 | err = -EINVAL; |
@@ -924,12 +968,237 @@ restore_gc: | |||
924 | restore_opts: | 968 | restore_opts: |
925 | sbi->mount_opt = org_mount_opt; | 969 | sbi->mount_opt = org_mount_opt; |
926 | sbi->active_logs = active_logs; | 970 | sbi->active_logs = active_logs; |
971 | sb->s_flags = old_sb_flags; | ||
927 | #ifdef CONFIG_F2FS_FAULT_INJECTION | 972 | #ifdef CONFIG_F2FS_FAULT_INJECTION |
928 | sbi->fault_info = ffi; | 973 | sbi->fault_info = ffi; |
929 | #endif | 974 | #endif |
930 | return err; | 975 | return err; |
931 | } | 976 | } |
932 | 977 | ||
978 | #ifdef CONFIG_QUOTA | ||
979 | /* Read data from quotafile */ | ||
980 | static ssize_t f2fs_quota_read(struct super_block *sb, int type, char *data, | ||
981 | size_t len, loff_t off) | ||
982 | { | ||
983 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
984 | struct address_space *mapping = inode->i_mapping; | ||
985 | block_t blkidx = F2FS_BYTES_TO_BLK(off); | ||
986 | int offset = off & (sb->s_blocksize - 1); | ||
987 | int tocopy; | ||
988 | size_t toread; | ||
989 | loff_t i_size = i_size_read(inode); | ||
990 | struct page *page; | ||
991 | char *kaddr; | ||
992 | |||
993 | if (off > i_size) | ||
994 | return 0; | ||
995 | |||
996 | if (off + len > i_size) | ||
997 | len = i_size - off; | ||
998 | toread = len; | ||
999 | while (toread > 0) { | ||
1000 | tocopy = min_t(unsigned long, sb->s_blocksize - offset, toread); | ||
1001 | repeat: | ||
1002 | page = read_mapping_page(mapping, blkidx, NULL); | ||
1003 | if (IS_ERR(page)) | ||
1004 | return PTR_ERR(page); | ||
1005 | |||
1006 | lock_page(page); | ||
1007 | |||
1008 | if (unlikely(page->mapping != mapping)) { | ||
1009 | f2fs_put_page(page, 1); | ||
1010 | goto repeat; | ||
1011 | } | ||
1012 | if (unlikely(!PageUptodate(page))) { | ||
1013 | f2fs_put_page(page, 1); | ||
1014 | return -EIO; | ||
1015 | } | ||
1016 | |||
1017 | kaddr = kmap_atomic(page); | ||
1018 | memcpy(data, kaddr + offset, tocopy); | ||
1019 | kunmap_atomic(kaddr); | ||
1020 | f2fs_put_page(page, 1); | ||
1021 | |||
1022 | offset = 0; | ||
1023 | toread -= tocopy; | ||
1024 | data += tocopy; | ||
1025 | blkidx++; | ||
1026 | } | ||
1027 | return len; | ||
1028 | } | ||
1029 | |||
1030 | /* Write to quotafile */ | ||
1031 | static ssize_t f2fs_quota_write(struct super_block *sb, int type, | ||
1032 | const char *data, size_t len, loff_t off) | ||
1033 | { | ||
1034 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
1035 | struct address_space *mapping = inode->i_mapping; | ||
1036 | const struct address_space_operations *a_ops = mapping->a_ops; | ||
1037 | int offset = off & (sb->s_blocksize - 1); | ||
1038 | size_t towrite = len; | ||
1039 | struct page *page; | ||
1040 | char *kaddr; | ||
1041 | int err = 0; | ||
1042 | int tocopy; | ||
1043 | |||
1044 | while (towrite > 0) { | ||
1045 | tocopy = min_t(unsigned long, sb->s_blocksize - offset, | ||
1046 | towrite); | ||
1047 | |||
1048 | err = a_ops->write_begin(NULL, mapping, off, tocopy, 0, | ||
1049 | &page, NULL); | ||
1050 | if (unlikely(err)) | ||
1051 | break; | ||
1052 | |||
1053 | kaddr = kmap_atomic(page); | ||
1054 | memcpy(kaddr + offset, data, tocopy); | ||
1055 | kunmap_atomic(kaddr); | ||
1056 | flush_dcache_page(page); | ||
1057 | |||
1058 | a_ops->write_end(NULL, mapping, off, tocopy, tocopy, | ||
1059 | page, NULL); | ||
1060 | offset = 0; | ||
1061 | towrite -= tocopy; | ||
1062 | off += tocopy; | ||
1063 | data += tocopy; | ||
1064 | cond_resched(); | ||
1065 | } | ||
1066 | |||
1067 | if (len == towrite) | ||
1068 | return err; | ||
1069 | inode->i_version++; | ||
1070 | inode->i_mtime = inode->i_ctime = current_time(inode); | ||
1071 | f2fs_mark_inode_dirty_sync(inode, false); | ||
1072 | return len - towrite; | ||
1073 | } | ||
1074 | |||
1075 | static struct dquot **f2fs_get_dquots(struct inode *inode) | ||
1076 | { | ||
1077 | return F2FS_I(inode)->i_dquot; | ||
1078 | } | ||
1079 | |||
1080 | static qsize_t *f2fs_get_reserved_space(struct inode *inode) | ||
1081 | { | ||
1082 | return &F2FS_I(inode)->i_reserved_quota; | ||
1083 | } | ||
1084 | |||
1085 | static int f2fs_quota_sync(struct super_block *sb, int type) | ||
1086 | { | ||
1087 | struct quota_info *dqopt = sb_dqopt(sb); | ||
1088 | int cnt; | ||
1089 | int ret; | ||
1090 | |||
1091 | ret = dquot_writeback_dquots(sb, type); | ||
1092 | if (ret) | ||
1093 | return ret; | ||
1094 | |||
1095 | /* | ||
1096 | * Now when everything is written we can discard the pagecache so | ||
1097 | * that userspace sees the changes. | ||
1098 | */ | ||
1099 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
1100 | if (type != -1 && cnt != type) | ||
1101 | continue; | ||
1102 | if (!sb_has_quota_active(sb, cnt)) | ||
1103 | continue; | ||
1104 | |||
1105 | ret = filemap_write_and_wait(dqopt->files[cnt]->i_mapping); | ||
1106 | if (ret) | ||
1107 | return ret; | ||
1108 | |||
1109 | inode_lock(dqopt->files[cnt]); | ||
1110 | truncate_inode_pages(&dqopt->files[cnt]->i_data, 0); | ||
1111 | inode_unlock(dqopt->files[cnt]); | ||
1112 | } | ||
1113 | return 0; | ||
1114 | } | ||
1115 | |||
1116 | static int f2fs_quota_on(struct super_block *sb, int type, int format_id, | ||
1117 | const struct path *path) | ||
1118 | { | ||
1119 | struct inode *inode; | ||
1120 | int err; | ||
1121 | |||
1122 | err = f2fs_quota_sync(sb, -1); | ||
1123 | if (err) | ||
1124 | return err; | ||
1125 | |||
1126 | err = dquot_quota_on(sb, type, format_id, path); | ||
1127 | if (err) | ||
1128 | return err; | ||
1129 | |||
1130 | inode = d_inode(path->dentry); | ||
1131 | |||
1132 | inode_lock(inode); | ||
1133 | F2FS_I(inode)->i_flags |= FS_NOATIME_FL | FS_IMMUTABLE_FL; | ||
1134 | inode_set_flags(inode, S_NOATIME | S_IMMUTABLE, | ||
1135 | S_NOATIME | S_IMMUTABLE); | ||
1136 | inode_unlock(inode); | ||
1137 | f2fs_mark_inode_dirty_sync(inode, false); | ||
1138 | |||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | static int f2fs_quota_off(struct super_block *sb, int type) | ||
1143 | { | ||
1144 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
1145 | int err; | ||
1146 | |||
1147 | if (!inode || !igrab(inode)) | ||
1148 | return dquot_quota_off(sb, type); | ||
1149 | |||
1150 | f2fs_quota_sync(sb, -1); | ||
1151 | |||
1152 | err = dquot_quota_off(sb, type); | ||
1153 | if (err) | ||
1154 | goto out_put; | ||
1155 | |||
1156 | inode_lock(inode); | ||
1157 | F2FS_I(inode)->i_flags &= ~(FS_NOATIME_FL | FS_IMMUTABLE_FL); | ||
1158 | inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE); | ||
1159 | inode_unlock(inode); | ||
1160 | f2fs_mark_inode_dirty_sync(inode, false); | ||
1161 | out_put: | ||
1162 | iput(inode); | ||
1163 | return err; | ||
1164 | } | ||
1165 | |||
1166 | static void f2fs_quota_off_umount(struct super_block *sb) | ||
1167 | { | ||
1168 | int type; | ||
1169 | |||
1170 | for (type = 0; type < MAXQUOTAS; type++) | ||
1171 | f2fs_quota_off(sb, type); | ||
1172 | } | ||
1173 | |||
1174 | static const struct dquot_operations f2fs_quota_operations = { | ||
1175 | .get_reserved_space = f2fs_get_reserved_space, | ||
1176 | .write_dquot = dquot_commit, | ||
1177 | .acquire_dquot = dquot_acquire, | ||
1178 | .release_dquot = dquot_release, | ||
1179 | .mark_dirty = dquot_mark_dquot_dirty, | ||
1180 | .write_info = dquot_commit_info, | ||
1181 | .alloc_dquot = dquot_alloc, | ||
1182 | .destroy_dquot = dquot_destroy, | ||
1183 | .get_next_id = dquot_get_next_id, | ||
1184 | }; | ||
1185 | |||
1186 | static const struct quotactl_ops f2fs_quotactl_ops = { | ||
1187 | .quota_on = f2fs_quota_on, | ||
1188 | .quota_off = f2fs_quota_off, | ||
1189 | .quota_sync = f2fs_quota_sync, | ||
1190 | .get_state = dquot_get_state, | ||
1191 | .set_info = dquot_set_dqinfo, | ||
1192 | .get_dqblk = dquot_get_dqblk, | ||
1193 | .set_dqblk = dquot_set_dqblk, | ||
1194 | .get_nextdqblk = dquot_get_next_dqblk, | ||
1195 | }; | ||
1196 | #else | ||
1197 | static inline void f2fs_quota_off_umount(struct super_block *sb) | ||
1198 | { | ||
1199 | } | ||
1200 | #endif | ||
1201 | |||
933 | static struct super_operations f2fs_sops = { | 1202 | static struct super_operations f2fs_sops = { |
934 | .alloc_inode = f2fs_alloc_inode, | 1203 | .alloc_inode = f2fs_alloc_inode, |
935 | .drop_inode = f2fs_drop_inode, | 1204 | .drop_inode = f2fs_drop_inode, |
@@ -937,6 +1206,11 @@ static struct super_operations f2fs_sops = { | |||
937 | .write_inode = f2fs_write_inode, | 1206 | .write_inode = f2fs_write_inode, |
938 | .dirty_inode = f2fs_dirty_inode, | 1207 | .dirty_inode = f2fs_dirty_inode, |
939 | .show_options = f2fs_show_options, | 1208 | .show_options = f2fs_show_options, |
1209 | #ifdef CONFIG_QUOTA | ||
1210 | .quota_read = f2fs_quota_read, | ||
1211 | .quota_write = f2fs_quota_write, | ||
1212 | .get_dquots = f2fs_get_dquots, | ||
1213 | #endif | ||
940 | .evict_inode = f2fs_evict_inode, | 1214 | .evict_inode = f2fs_evict_inode, |
941 | .put_super = f2fs_put_super, | 1215 | .put_super = f2fs_put_super, |
942 | .sync_fs = f2fs_sync_fs, | 1216 | .sync_fs = f2fs_sync_fs, |
@@ -1679,6 +1953,12 @@ try_onemore: | |||
1679 | sb->s_max_links = F2FS_LINK_MAX; | 1953 | sb->s_max_links = F2FS_LINK_MAX; |
1680 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 1954 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
1681 | 1955 | ||
1956 | #ifdef CONFIG_QUOTA | ||
1957 | sb->dq_op = &f2fs_quota_operations; | ||
1958 | sb->s_qcop = &f2fs_quotactl_ops; | ||
1959 | sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; | ||
1960 | #endif | ||
1961 | |||
1682 | sb->s_op = &f2fs_sops; | 1962 | sb->s_op = &f2fs_sops; |
1683 | sb->s_cop = &f2fs_cryptops; | 1963 | sb->s_cop = &f2fs_cryptops; |
1684 | sb->s_xattr = f2fs_xattr_handlers; | 1964 | sb->s_xattr = f2fs_xattr_handlers; |