Skip to content

Commit 0abd675

Browse files
chaseyuJaegeuk Kim
authored andcommitted
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>
1 parent d29460e commit 0abd675

File tree

8 files changed

+454
-40
lines changed

8 files changed

+454
-40
lines changed

Documentation/filesystems/f2fs.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ mode=%s Control block allocation mode which supports "adaptive"
162162
writes towards main area.
163163
io_bits=%u Set the bit size of write IO requests. It should be set
164164
with "mode=lfs".
165+
usrquota Enable plain user disk quota accounting.
166+
grpquota Enable plain group disk quota accounting.
165167

166168
================================================================================
167169
DEBUGFS ENTRIES

fs/f2fs/data.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,14 +491,15 @@ void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
491491
int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
492492
{
493493
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
494+
int err;
494495

495496
if (!count)
496497
return 0;
497498

498499
if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
499500
return -EPERM;
500-
if (unlikely(!inc_valid_block_count(sbi, dn->inode, &count)))
501-
return -ENOSPC;
501+
if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
502+
return err;
502503

503504
trace_f2fs_reserve_new_blocks(dn->inode, dn->nid,
504505
dn->ofs_in_node, count);
@@ -749,6 +750,7 @@ static int __allocate_data_block(struct dnode_of_data *dn)
749750
struct node_info ni;
750751
pgoff_t fofs;
751752
blkcnt_t count = 1;
753+
int err;
752754

753755
if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
754756
return -EPERM;
@@ -757,8 +759,8 @@ static int __allocate_data_block(struct dnode_of_data *dn)
757759
if (dn->data_blkaddr == NEW_ADDR)
758760
goto alloc;
759761

760-
if (unlikely(!inc_valid_block_count(sbi, dn->inode, &count)))
761-
return -ENOSPC;
762+
if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
763+
return err;
762764

763765
alloc:
764766
get_node_info(sbi, dn->nid, &ni);

fs/f2fs/f2fs.h

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/vmalloc.h>
2323
#include <linux/bio.h>
2424
#include <linux/blkdev.h>
25+
#include <linux/quotaops.h>
2526
#ifdef CONFIG_F2FS_FS_ENCRYPTION
2627
#include <linux/fscrypt_supp.h>
2728
#else
@@ -88,6 +89,8 @@ extern char *fault_name[FAULT_MAX];
8889
#define F2FS_MOUNT_FAULT_INJECTION 0x00010000
8990
#define F2FS_MOUNT_ADAPTIVE 0x00020000
9091
#define F2FS_MOUNT_LFS 0x00040000
92+
#define F2FS_MOUNT_USRQUOTA 0x00080000
93+
#define F2FS_MOUNT_GRPQUOTA 0x00100000
9194

9295
#define clear_opt(sbi, option) ((sbi)->mount_opt.opt &= ~F2FS_MOUNT_##option)
9396
#define set_opt(sbi, option) ((sbi)->mount_opt.opt |= F2FS_MOUNT_##option)
@@ -521,6 +524,12 @@ struct f2fs_inode_info {
521524
nid_t i_xattr_nid; /* node id that contains xattrs */
522525
loff_t last_disk_size; /* lastly written file size */
523526

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
524533
struct list_head dirty_list; /* dirty list for dirs and files */
525534
struct list_head gdirty_list; /* linked in global dirty list */
526535
struct list_head inmem_pages; /* inmemory pages managed by f2fs */
@@ -1376,17 +1385,23 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs)
13761385
return ofs == XATTR_NODE_OFFSET;
13771386
}
13781387

1379-
static inline void f2fs_i_blocks_write(struct inode *, block_t, bool);
1380-
static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
1388+
static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
1389+
static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
13811390
struct inode *inode, blkcnt_t *count)
13821391
{
1383-
blkcnt_t diff;
1392+
blkcnt_t diff = 0, release = 0;
13841393
block_t avail_user_block_count;
1394+
int ret;
1395+
1396+
ret = dquot_reserve_block(inode, *count);
1397+
if (ret)
1398+
return ret;
13851399

13861400
#ifdef CONFIG_F2FS_FAULT_INJECTION
13871401
if (time_to_inject(sbi, FAULT_BLOCK)) {
13881402
f2fs_show_injection_info(FAULT_BLOCK);
1389-
return false;
1403+
release = *count;
1404+
goto enospc;
13901405
}
13911406
#endif
13921407
/*
@@ -1401,17 +1416,24 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
14011416
if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
14021417
diff = sbi->total_valid_block_count - avail_user_block_count;
14031418
*count -= diff;
1419+
release = diff;
14041420
sbi->total_valid_block_count = avail_user_block_count;
14051421
if (!*count) {
14061422
spin_unlock(&sbi->stat_lock);
14071423
percpu_counter_sub(&sbi->alloc_valid_block_count, diff);
1408-
return false;
1424+
goto enospc;
14091425
}
14101426
}
14111427
spin_unlock(&sbi->stat_lock);
14121428

1413-
f2fs_i_blocks_write(inode, *count, true);
1414-
return true;
1429+
if (release)
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;
14151437
}
14161438

14171439
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,
14251447
f2fs_bug_on(sbi, inode->i_blocks < sectors);
14261448
sbi->total_valid_block_count -= (block_t)count;
14271449
spin_unlock(&sbi->stat_lock);
1428-
f2fs_i_blocks_write(inode, count, false);
1450+
f2fs_i_blocks_write(inode, count, false, true);
14291451
}
14301452

14311453
static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
@@ -1554,40 +1576,52 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi)
15541576
return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum);
15551577
}
15561578

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,
15581580
struct inode *inode, bool is_inode)
15591581
{
15601582
block_t valid_block_count;
15611583
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+
}
15621591

15631592
spin_lock(&sbi->stat_lock);
15641593

15651594
valid_block_count = sbi->total_valid_block_count + 1;
15661595
if (unlikely(valid_block_count + sbi->reserved_blocks >
15671596
sbi->user_block_count)) {
15681597
spin_unlock(&sbi->stat_lock);
1569-
return false;
1598+
goto enospc;
15701599
}
15711600

15721601
valid_node_count = sbi->total_valid_node_count + 1;
15731602
if (unlikely(valid_node_count > sbi->total_node_count)) {
15741603
spin_unlock(&sbi->stat_lock);
1575-
return false;
1604+
goto enospc;
15761605
}
15771606

1607+
sbi->total_valid_node_count++;
1608+
sbi->total_valid_block_count++;
1609+
spin_unlock(&sbi->stat_lock);
1610+
15781611
if (inode) {
15791612
if (is_inode)
15801613
f2fs_mark_inode_dirty_sync(inode, true);
15811614
else
1582-
f2fs_i_blocks_write(inode, 1, true);
1615+
f2fs_i_blocks_write(inode, 1, true, true);
15831616
}
15841617

1585-
sbi->total_valid_node_count++;
1586-
sbi->total_valid_block_count++;
1587-
spin_unlock(&sbi->stat_lock);
1588-
15891618
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;
15911625
}
15921626

15931627
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,
15991633
f2fs_bug_on(sbi, !sbi->total_valid_node_count);
16001634
f2fs_bug_on(sbi, !is_inode && !inode->i_blocks);
16011635

1602-
if (!is_inode)
1603-
f2fs_i_blocks_write(inode, 1, false);
16041636
sbi->total_valid_node_count--;
16051637
sbi->total_valid_block_count--;
16061638

16071639
spin_unlock(&sbi->stat_lock);
1640+
1641+
if (!is_inode)
1642+
f2fs_i_blocks_write(inode, 1, false, true);
16081643
}
16091644

16101645
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)
18791914
}
18801915

18811916
static inline void f2fs_i_blocks_write(struct inode *inode,
1882-
block_t diff, bool add)
1917+
block_t diff, bool add, bool claim)
18831918
{
18841919
bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE);
18851920
bool recover = is_inode_flag_set(inode, FI_AUTO_RECOVER);
1886-
blkcnt_t sectors = diff << F2FS_LOG_SECTORS_PER_BLOCK;
18871921

1888-
inode->i_blocks = add ? inode->i_blocks + sectors :
1889-
inode->i_blocks - sectors;
1922+
/* add = 1, claim = 1 should be dquot_reserve_block in pair */
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+
18901932
f2fs_mark_inode_dirty_sync(inode, true);
18911933
if (clean || recover)
18921934
set_inode_flag(inode, FI_AUTO_RECOVER);

fs/f2fs/file.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,10 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
442442

443443
static int f2fs_file_open(struct inode *inode, struct file *filp)
444444
{
445-
int ret = generic_file_open(inode, filp);
446445
struct dentry *dir;
447446

448-
if (!ret && f2fs_encrypted_inode(inode)) {
449-
ret = fscrypt_get_encryption_info(inode);
447+
if (f2fs_encrypted_inode(inode)) {
448+
int ret = fscrypt_get_encryption_info(inode);
450449
if (ret)
451450
return -EACCES;
452451
if (!fscrypt_has_encryption_key(inode))
@@ -459,7 +458,7 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
459458
return -EPERM;
460459
}
461460
dput(dir);
462-
return ret;
461+
return dquot_file_open(inode, filp);
463462
}
464463

465464
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)
710709
if (err)
711710
return err;
712711

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+
713726
if (attr->ia_valid & ATTR_SIZE) {
714727
if (f2fs_encrypted_inode(inode)) {
715728
err = fscrypt_get_encryption_info(inode);
@@ -996,9 +1009,9 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
9961009

9971010
if (do_replace[i]) {
9981011
f2fs_i_blocks_write(src_inode,
999-
1, false);
1012+
1, false, false);
10001013
f2fs_i_blocks_write(dst_inode,
1001-
1, true);
1014+
1, true, false);
10021015
f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
10031016
blkaddr[i], ni.version, true, false);
10041017

@@ -1523,6 +1536,13 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
15231536

15241537
inode_lock(inode);
15251538

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+
15261546
flags = f2fs_mask_flags(inode->i_mode, flags);
15271547

15281548
oldflags = fi->i_flags;
@@ -1542,7 +1562,7 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
15421562
inode->i_ctime = current_time(inode);
15431563
f2fs_set_inode_flags(inode);
15441564
f2fs_mark_inode_dirty_sync(inode, false);
1545-
1565+
unlock_out:
15461566
inode_unlock(inode);
15471567
out:
15481568
mnt_drop_write_file(filp);

fs/f2fs/inode.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ void f2fs_evict_inode(struct inode *inode)
373373
if (inode->i_nlink || is_bad_inode(inode))
374374
goto no_delete;
375375

376+
dquot_initialize(inode);
377+
376378
remove_ino_entry(sbi, inode->i_ino, APPEND_INO);
377379
remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
378380

@@ -405,8 +407,11 @@ void f2fs_evict_inode(struct inode *inode)
405407

406408
if (err)
407409
update_inode_page(inode);
410+
dquot_free_inode(inode);
408411
sb_end_intwrite(inode->i_sb);
409412
no_delete:
413+
dquot_drop(inode);
414+
410415
stat_dec_inline_xattr(inode);
411416
stat_dec_inline_dir(inode);
412417
stat_dec_inline_inode(inode);

0 commit comments

Comments
 (0)