diff options
-rw-r--r-- | fs/gfs2/aops.c | 2 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 10 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 13 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 18 | ||||
-rw-r--r-- | fs/gfs2/main.c | 11 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 105 | ||||
-rw-r--r-- | fs/gfs2/quota.h | 2 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 17 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 4 | ||||
-rw-r--r-- | fs/gfs2/super.c | 2 | ||||
-rw-r--r-- | fs/gfs2/util.c | 1 | ||||
-rw-r--r-- | fs/gfs2/util.h | 1 |
13 files changed, 125 insertions, 63 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 1caee0534587..93f07465e5a6 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -914,7 +914,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
914 | failed: | 914 | failed: |
915 | gfs2_trans_end(sdp); | 915 | gfs2_trans_end(sdp); |
916 | gfs2_inplace_release(ip); | 916 | gfs2_inplace_release(ip); |
917 | if (ip->i_res->rs_qa_qd_num) | 917 | if (ip->i_qadata && ip->i_qadata->qa_qd_num) |
918 | gfs2_quota_unlock(ip); | 918 | gfs2_quota_unlock(ip); |
919 | if (inode == sdp->sd_rindex) { | 919 | if (inode == sdp->sd_rindex) { |
920 | gfs2_glock_dq(&m_ip->i_gh); | 920 | gfs2_glock_dq(&m_ip->i_gh); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 61296ecbd0e2..8d46ae4fa873 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -1297,7 +1297,7 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) | |||
1297 | 1297 | ||
1298 | inode_dio_wait(inode); | 1298 | inode_dio_wait(inode); |
1299 | 1299 | ||
1300 | ret = gfs2_rs_alloc(ip); | 1300 | ret = gfs2_rsqa_alloc(ip); |
1301 | if (ret) | 1301 | if (ret) |
1302 | goto out; | 1302 | goto out; |
1303 | 1303 | ||
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 201282046693..de001eb27bed 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -401,7 +401,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
401 | if (ret) | 401 | if (ret) |
402 | goto out; | 402 | goto out; |
403 | 403 | ||
404 | ret = gfs2_rs_alloc(ip); | 404 | ret = gfs2_rsqa_alloc(ip); |
405 | if (ret) | 405 | if (ret) |
406 | goto out_write_access; | 406 | goto out_write_access; |
407 | 407 | ||
@@ -623,7 +623,7 @@ static int gfs2_release(struct inode *inode, struct file *file) | |||
623 | if (!(file->f_mode & FMODE_WRITE)) | 623 | if (!(file->f_mode & FMODE_WRITE)) |
624 | return 0; | 624 | return 0; |
625 | 625 | ||
626 | gfs2_rs_delete(ip, &inode->i_writecount); | 626 | gfs2_rsqa_delete(ip, &inode->i_writecount); |
627 | return 0; | 627 | return 0; |
628 | } | 628 | } |
629 | 629 | ||
@@ -703,7 +703,7 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
703 | struct gfs2_inode *ip = GFS2_I(file_inode(file)); | 703 | struct gfs2_inode *ip = GFS2_I(file_inode(file)); |
704 | int ret; | 704 | int ret; |
705 | 705 | ||
706 | ret = gfs2_rs_alloc(ip); | 706 | ret = gfs2_rsqa_alloc(ip); |
707 | if (ret) | 707 | if (ret) |
708 | return ret; | 708 | return ret; |
709 | 709 | ||
@@ -938,7 +938,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t le | |||
938 | if (ret) | 938 | if (ret) |
939 | goto out_unlock; | 939 | goto out_unlock; |
940 | 940 | ||
941 | ret = gfs2_rs_alloc(ip); | 941 | ret = gfs2_rsqa_alloc(ip); |
942 | if (ret) | 942 | if (ret) |
943 | goto out_putw; | 943 | goto out_putw; |
944 | 944 | ||
@@ -962,7 +962,7 @@ static ssize_t gfs2_file_splice_write(struct pipe_inode_info *pipe, | |||
962 | int error; | 962 | int error; |
963 | struct gfs2_inode *ip = GFS2_I(out->f_mapping->host); | 963 | struct gfs2_inode *ip = GFS2_I(out->f_mapping->host); |
964 | 964 | ||
965 | error = gfs2_rs_alloc(ip); | 965 | error = gfs2_rsqa_alloc(ip); |
966 | if (error) | 966 | if (error) |
967 | return (ssize_t)error; | 967 | return (ssize_t)error; |
968 | 968 | ||
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 77e778496903..6a22f66f058d 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -270,6 +270,13 @@ struct gfs2_holder { | |||
270 | /* Number of quota types we support */ | 270 | /* Number of quota types we support */ |
271 | #define GFS2_MAXQUOTAS 2 | 271 | #define GFS2_MAXQUOTAS 2 |
272 | 272 | ||
273 | struct gfs2_qadata { /* quota allocation data */ | ||
274 | /* Quota stuff */ | ||
275 | struct gfs2_quota_data *qa_qd[2 * GFS2_MAXQUOTAS]; | ||
276 | struct gfs2_holder qa_qd_ghs[2 * GFS2_MAXQUOTAS]; | ||
277 | unsigned int qa_qd_num; | ||
278 | }; | ||
279 | |||
273 | /* Resource group multi-block reservation, in order of appearance: | 280 | /* Resource group multi-block reservation, in order of appearance: |
274 | 281 | ||
275 | Step 1. Function prepares to write, allocates a mb, sets the size hint. | 282 | Step 1. Function prepares to write, allocates a mb, sets the size hint. |
@@ -288,11 +295,6 @@ struct gfs2_blkreserv { | |||
288 | struct gfs2_rbm rs_rbm; /* Start of reservation */ | 295 | struct gfs2_rbm rs_rbm; /* Start of reservation */ |
289 | u32 rs_free; /* how many blocks are still free */ | 296 | u32 rs_free; /* how many blocks are still free */ |
290 | u64 rs_inum; /* Inode number for reservation */ | 297 | u64 rs_inum; /* Inode number for reservation */ |
291 | |||
292 | /* ancillary quota stuff */ | ||
293 | struct gfs2_quota_data *rs_qa_qd[2 * GFS2_MAXQUOTAS]; | ||
294 | struct gfs2_holder rs_qa_qd_ghs[2 * GFS2_MAXQUOTAS]; | ||
295 | unsigned int rs_qa_qd_num; | ||
296 | }; | 298 | }; |
297 | 299 | ||
298 | /* | 300 | /* |
@@ -391,6 +393,7 @@ struct gfs2_inode { | |||
391 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 393 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
392 | struct gfs2_holder i_iopen_gh; | 394 | struct gfs2_holder i_iopen_gh; |
393 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ | 395 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ |
396 | struct gfs2_qadata *i_qadata; /* quota allocation data */ | ||
394 | struct gfs2_blkreserv *i_res; /* rgrp multi-block reservation */ | 397 | struct gfs2_blkreserv *i_res; /* rgrp multi-block reservation */ |
395 | struct gfs2_rgrpd *i_rgd; | 398 | struct gfs2_rgrpd *i_rgd; |
396 | u64 i_goal; /* goal block for allocations */ | 399 | u64 i_goal; /* goal block for allocations */ |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 2c05bc3d1947..c37e6bf2958e 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -601,7 +601,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
601 | if (!name->len || name->len > GFS2_FNAMESIZE) | 601 | if (!name->len || name->len > GFS2_FNAMESIZE) |
602 | return -ENAMETOOLONG; | 602 | return -ENAMETOOLONG; |
603 | 603 | ||
604 | error = gfs2_rs_alloc(dip); | 604 | error = gfs2_rsqa_alloc(dip); |
605 | if (error) | 605 | if (error) |
606 | return error; | 606 | return error; |
607 | 607 | ||
@@ -653,7 +653,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
653 | goto fail_free_vfs_inode; | 653 | goto fail_free_vfs_inode; |
654 | 654 | ||
655 | ip = GFS2_I(inode); | 655 | ip = GFS2_I(inode); |
656 | error = gfs2_rs_alloc(ip); | 656 | error = gfs2_rsqa_alloc(ip); |
657 | if (error) | 657 | if (error) |
658 | goto fail_free_acls; | 658 | goto fail_free_acls; |
659 | 659 | ||
@@ -781,7 +781,7 @@ fail_gunlock2: | |||
781 | fail_free_inode: | 781 | fail_free_inode: |
782 | if (ip->i_gl) | 782 | if (ip->i_gl) |
783 | gfs2_glock_put(ip->i_gl); | 783 | gfs2_glock_put(ip->i_gl); |
784 | gfs2_rs_delete(ip, NULL); | 784 | gfs2_rsqa_delete(ip, NULL); |
785 | fail_free_acls: | 785 | fail_free_acls: |
786 | if (default_acl) | 786 | if (default_acl) |
787 | posix_acl_release(default_acl); | 787 | posix_acl_release(default_acl); |
@@ -903,7 +903,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
903 | if (S_ISDIR(inode->i_mode)) | 903 | if (S_ISDIR(inode->i_mode)) |
904 | return -EPERM; | 904 | return -EPERM; |
905 | 905 | ||
906 | error = gfs2_rs_alloc(dip); | 906 | error = gfs2_rsqa_alloc(dip); |
907 | if (error) | 907 | if (error) |
908 | return error; | 908 | return error; |
909 | 909 | ||
@@ -1376,7 +1376,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1376 | if (error) | 1376 | if (error) |
1377 | return error; | 1377 | return error; |
1378 | 1378 | ||
1379 | error = gfs2_rs_alloc(ndip); | 1379 | error = gfs2_rsqa_alloc(ndip); |
1380 | if (error) | 1380 | if (error) |
1381 | return error; | 1381 | return error; |
1382 | 1382 | ||
@@ -1863,7 +1863,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1863 | if (error) | 1863 | if (error) |
1864 | return error; | 1864 | return error; |
1865 | 1865 | ||
1866 | error = gfs2_rs_alloc(ip); | 1866 | error = gfs2_rsqa_alloc(ip); |
1867 | if (error) | 1867 | if (error) |
1868 | goto out; | 1868 | goto out; |
1869 | 1869 | ||
@@ -1925,7 +1925,7 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1925 | struct gfs2_holder i_gh; | 1925 | struct gfs2_holder i_gh; |
1926 | int error; | 1926 | int error; |
1927 | 1927 | ||
1928 | error = gfs2_rs_alloc(ip); | 1928 | error = gfs2_rsqa_alloc(ip); |
1929 | if (error) | 1929 | if (error) |
1930 | return error; | 1930 | return error; |
1931 | 1931 | ||
@@ -2007,7 +2007,7 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name, | |||
2007 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 2007 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
2008 | ret = gfs2_glock_nq(&gh); | 2008 | ret = gfs2_glock_nq(&gh); |
2009 | if (ret == 0) { | 2009 | if (ret == 0) { |
2010 | ret = gfs2_rs_alloc(ip); | 2010 | ret = gfs2_rsqa_alloc(ip); |
2011 | if (ret == 0) | 2011 | if (ret == 0) |
2012 | ret = generic_setxattr(dentry, name, data, size, flags); | 2012 | ret = generic_setxattr(dentry, name, data, size, flags); |
2013 | gfs2_glock_dq(&gh); | 2013 | gfs2_glock_dq(&gh); |
@@ -2048,7 +2048,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
2048 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 2048 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
2049 | ret = gfs2_glock_nq(&gh); | 2049 | ret = gfs2_glock_nq(&gh); |
2050 | if (ret == 0) { | 2050 | if (ret == 0) { |
2051 | ret = gfs2_rs_alloc(ip); | 2051 | ret = gfs2_rsqa_alloc(ip); |
2052 | if (ret == 0) | 2052 | if (ret == 0) |
2053 | ret = generic_removexattr(dentry, name); | 2053 | ret = generic_removexattr(dentry, name); |
2054 | gfs2_glock_dq(&gh); | 2054 | gfs2_glock_dq(&gh); |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index fb2b42cf46b5..cde5c73c42df 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -41,6 +41,7 @@ static void gfs2_init_inode_once(void *foo) | |||
41 | inode_init_once(&ip->i_inode); | 41 | inode_init_once(&ip->i_inode); |
42 | init_rwsem(&ip->i_rw_mutex); | 42 | init_rwsem(&ip->i_rw_mutex); |
43 | INIT_LIST_HEAD(&ip->i_trunc_list); | 43 | INIT_LIST_HEAD(&ip->i_trunc_list); |
44 | ip->i_qadata = NULL; | ||
44 | ip->i_res = NULL; | 45 | ip->i_res = NULL; |
45 | ip->i_hash_cache = NULL; | 46 | ip->i_hash_cache = NULL; |
46 | } | 47 | } |
@@ -135,6 +136,12 @@ static int __init init_gfs2_fs(void) | |||
135 | if (!gfs2_quotad_cachep) | 136 | if (!gfs2_quotad_cachep) |
136 | goto fail; | 137 | goto fail; |
137 | 138 | ||
139 | gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata", | ||
140 | sizeof(struct gfs2_qadata), | ||
141 | 0, 0, NULL); | ||
142 | if (!gfs2_qadata_cachep) | ||
143 | goto fail; | ||
144 | |||
138 | gfs2_rsrv_cachep = kmem_cache_create("gfs2_mblk", | 145 | gfs2_rsrv_cachep = kmem_cache_create("gfs2_mblk", |
139 | sizeof(struct gfs2_blkreserv), | 146 | sizeof(struct gfs2_blkreserv), |
140 | 0, 0, NULL); | 147 | 0, 0, NULL); |
@@ -196,6 +203,9 @@ fail_lru: | |||
196 | if (gfs2_rsrv_cachep) | 203 | if (gfs2_rsrv_cachep) |
197 | kmem_cache_destroy(gfs2_rsrv_cachep); | 204 | kmem_cache_destroy(gfs2_rsrv_cachep); |
198 | 205 | ||
206 | if (gfs2_qadata_cachep) | ||
207 | kmem_cache_destroy(gfs2_qadata_cachep); | ||
208 | |||
199 | if (gfs2_quotad_cachep) | 209 | if (gfs2_quotad_cachep) |
200 | kmem_cache_destroy(gfs2_quotad_cachep); | 210 | kmem_cache_destroy(gfs2_quotad_cachep); |
201 | 211 | ||
@@ -239,6 +249,7 @@ static void __exit exit_gfs2_fs(void) | |||
239 | 249 | ||
240 | mempool_destroy(gfs2_page_pool); | 250 | mempool_destroy(gfs2_page_pool); |
241 | kmem_cache_destroy(gfs2_rsrv_cachep); | 251 | kmem_cache_destroy(gfs2_rsrv_cachep); |
252 | kmem_cache_destroy(gfs2_qadata_cachep); | ||
242 | kmem_cache_destroy(gfs2_quotad_cachep); | 253 | kmem_cache_destroy(gfs2_quotad_cachep); |
243 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 254 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
244 | kmem_cache_destroy(gfs2_bufdata_cachep); | 255 | kmem_cache_destroy(gfs2_bufdata_cachep); |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index e01298d922c0..b845efdb5e3a 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -527,37 +527,70 @@ static void qdsb_put(struct gfs2_quota_data *qd) | |||
527 | qd_put(qd); | 527 | qd_put(qd); |
528 | } | 528 | } |
529 | 529 | ||
530 | /** | ||
531 | * gfs2_qa_alloc - make sure we have a quota allocations data structure, | ||
532 | * if necessary | ||
533 | * @ip: the inode for this reservation | ||
534 | */ | ||
535 | int gfs2_qa_alloc(struct gfs2_inode *ip) | ||
536 | { | ||
537 | int error = 0; | ||
538 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
539 | |||
540 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | ||
541 | return 0; | ||
542 | |||
543 | down_write(&ip->i_rw_mutex); | ||
544 | if (ip->i_qadata == NULL) { | ||
545 | ip->i_qadata = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS); | ||
546 | if (!ip->i_qadata) | ||
547 | error = -ENOMEM; | ||
548 | } | ||
549 | up_write(&ip->i_rw_mutex); | ||
550 | return error; | ||
551 | } | ||
552 | |||
553 | void gfs2_qa_delete(struct gfs2_inode *ip) | ||
554 | { | ||
555 | down_write(&ip->i_rw_mutex); | ||
556 | if (ip->i_qadata) { | ||
557 | kmem_cache_free(gfs2_qadata_cachep, ip->i_qadata); | ||
558 | ip->i_qadata = NULL; | ||
559 | } | ||
560 | up_write(&ip->i_rw_mutex); | ||
561 | } | ||
562 | |||
530 | int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | 563 | int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) |
531 | { | 564 | { |
532 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 565 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
533 | struct gfs2_quota_data **qd; | 566 | struct gfs2_quota_data **qd; |
534 | int error; | 567 | int error; |
535 | 568 | ||
536 | if (ip->i_res == NULL) { | 569 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
537 | error = gfs2_rs_alloc(ip); | 570 | return 0; |
571 | |||
572 | if (ip->i_qadata == NULL) { | ||
573 | error = gfs2_rsqa_alloc(ip); | ||
538 | if (error) | 574 | if (error) |
539 | return error; | 575 | return error; |
540 | } | 576 | } |
541 | 577 | ||
542 | qd = ip->i_res->rs_qa_qd; | 578 | qd = ip->i_qadata->qa_qd; |
543 | 579 | ||
544 | if (gfs2_assert_warn(sdp, !ip->i_res->rs_qa_qd_num) || | 580 | if (gfs2_assert_warn(sdp, !ip->i_qadata->qa_qd_num) || |
545 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) | 581 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) |
546 | return -EIO; | 582 | return -EIO; |
547 | 583 | ||
548 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | ||
549 | return 0; | ||
550 | |||
551 | error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd); | 584 | error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd); |
552 | if (error) | 585 | if (error) |
553 | goto out; | 586 | goto out; |
554 | ip->i_res->rs_qa_qd_num++; | 587 | ip->i_qadata->qa_qd_num++; |
555 | qd++; | 588 | qd++; |
556 | 589 | ||
557 | error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd); | 590 | error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd); |
558 | if (error) | 591 | if (error) |
559 | goto out; | 592 | goto out; |
560 | ip->i_res->rs_qa_qd_num++; | 593 | ip->i_qadata->qa_qd_num++; |
561 | qd++; | 594 | qd++; |
562 | 595 | ||
563 | if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) && | 596 | if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) && |
@@ -565,7 +598,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
565 | error = qdsb_get(sdp, make_kqid_uid(uid), qd); | 598 | error = qdsb_get(sdp, make_kqid_uid(uid), qd); |
566 | if (error) | 599 | if (error) |
567 | goto out; | 600 | goto out; |
568 | ip->i_res->rs_qa_qd_num++; | 601 | ip->i_qadata->qa_qd_num++; |
569 | qd++; | 602 | qd++; |
570 | } | 603 | } |
571 | 604 | ||
@@ -574,7 +607,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
574 | error = qdsb_get(sdp, make_kqid_gid(gid), qd); | 607 | error = qdsb_get(sdp, make_kqid_gid(gid), qd); |
575 | if (error) | 608 | if (error) |
576 | goto out; | 609 | goto out; |
577 | ip->i_res->rs_qa_qd_num++; | 610 | ip->i_qadata->qa_qd_num++; |
578 | qd++; | 611 | qd++; |
579 | } | 612 | } |
580 | 613 | ||
@@ -589,15 +622,15 @@ void gfs2_quota_unhold(struct gfs2_inode *ip) | |||
589 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 622 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
590 | unsigned int x; | 623 | unsigned int x; |
591 | 624 | ||
592 | if (ip->i_res == NULL) | 625 | if (ip->i_qadata == NULL) |
593 | return; | 626 | return; |
594 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); | 627 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); |
595 | 628 | ||
596 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 629 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
597 | qdsb_put(ip->i_res->rs_qa_qd[x]); | 630 | qdsb_put(ip->i_qadata->qa_qd[x]); |
598 | ip->i_res->rs_qa_qd[x] = NULL; | 631 | ip->i_qadata->qa_qd[x] = NULL; |
599 | } | 632 | } |
600 | ip->i_res->rs_qa_qd_num = 0; | 633 | ip->i_qadata->qa_qd_num = 0; |
601 | } | 634 | } |
602 | 635 | ||
603 | static int sort_qd(const void *a, const void *b) | 636 | static int sort_qd(const void *a, const void *b) |
@@ -843,7 +876,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
843 | unsigned int nalloc = 0, blocks; | 876 | unsigned int nalloc = 0, blocks; |
844 | int error; | 877 | int error; |
845 | 878 | ||
846 | error = gfs2_rs_alloc(ip); | 879 | error = gfs2_rsqa_alloc(ip); |
847 | if (error) | 880 | if (error) |
848 | return error; | 881 | return error; |
849 | 882 | ||
@@ -1006,20 +1039,20 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
1006 | unsigned int x; | 1039 | unsigned int x; |
1007 | int error = 0; | 1040 | int error = 0; |
1008 | 1041 | ||
1009 | error = gfs2_quota_hold(ip, uid, gid); | ||
1010 | if (error) | ||
1011 | return error; | ||
1012 | |||
1013 | if (capable(CAP_SYS_RESOURCE) || | 1042 | if (capable(CAP_SYS_RESOURCE) || |
1014 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 1043 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
1015 | return 0; | 1044 | return 0; |
1016 | 1045 | ||
1017 | sort(ip->i_res->rs_qa_qd, ip->i_res->rs_qa_qd_num, | 1046 | error = gfs2_quota_hold(ip, uid, gid); |
1047 | if (error) | ||
1048 | return error; | ||
1049 | |||
1050 | sort(ip->i_qadata->qa_qd, ip->i_qadata->qa_qd_num, | ||
1018 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); | 1051 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); |
1019 | 1052 | ||
1020 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1053 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1021 | qd = ip->i_res->rs_qa_qd[x]; | 1054 | qd = ip->i_qadata->qa_qd[x]; |
1022 | error = do_glock(qd, NO_FORCE, &ip->i_res->rs_qa_qd_ghs[x]); | 1055 | error = do_glock(qd, NO_FORCE, &ip->i_qadata->qa_qd_ghs[x]); |
1023 | if (error) | 1056 | if (error) |
1024 | break; | 1057 | break; |
1025 | } | 1058 | } |
@@ -1028,7 +1061,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
1028 | set_bit(GIF_QD_LOCKED, &ip->i_flags); | 1061 | set_bit(GIF_QD_LOCKED, &ip->i_flags); |
1029 | else { | 1062 | else { |
1030 | while (x--) | 1063 | while (x--) |
1031 | gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); | 1064 | gfs2_glock_dq_uninit(&ip->i_qadata->qa_qd_ghs[x]); |
1032 | gfs2_quota_unhold(ip); | 1065 | gfs2_quota_unhold(ip); |
1033 | } | 1066 | } |
1034 | 1067 | ||
@@ -1082,14 +1115,14 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) | |||
1082 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) | 1115 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) |
1083 | goto out; | 1116 | goto out; |
1084 | 1117 | ||
1085 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1118 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1086 | struct gfs2_quota_data *qd; | 1119 | struct gfs2_quota_data *qd; |
1087 | int sync; | 1120 | int sync; |
1088 | 1121 | ||
1089 | qd = ip->i_res->rs_qa_qd[x]; | 1122 | qd = ip->i_qadata->qa_qd[x]; |
1090 | sync = need_sync(qd); | 1123 | sync = need_sync(qd); |
1091 | 1124 | ||
1092 | gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); | 1125 | gfs2_glock_dq_uninit(&ip->i_qadata->qa_qd_ghs[x]); |
1093 | if (!sync) | 1126 | if (!sync) |
1094 | continue; | 1127 | continue; |
1095 | 1128 | ||
@@ -1168,8 +1201,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, | |||
1168 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 1201 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
1169 | return 0; | 1202 | return 0; |
1170 | 1203 | ||
1171 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1204 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1172 | qd = ip->i_res->rs_qa_qd[x]; | 1205 | qd = ip->i_qadata->qa_qd[x]; |
1173 | 1206 | ||
1174 | if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) || | 1207 | if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) || |
1175 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) | 1208 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) |
@@ -1217,14 +1250,16 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1217 | { | 1250 | { |
1218 | struct gfs2_quota_data *qd; | 1251 | struct gfs2_quota_data *qd; |
1219 | unsigned int x; | 1252 | unsigned int x; |
1253 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1220 | 1254 | ||
1221 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change)) | 1255 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON || |
1256 | gfs2_assert_warn(sdp, change)) | ||
1222 | return; | 1257 | return; |
1223 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) | 1258 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) |
1224 | return; | 1259 | return; |
1225 | 1260 | ||
1226 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1261 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1227 | qd = ip->i_res->rs_qa_qd[x]; | 1262 | qd = ip->i_qadata->qa_qd[x]; |
1228 | 1263 | ||
1229 | if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || | 1264 | if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || |
1230 | qid_eq(qd->qd_id, make_kqid_gid(gid))) { | 1265 | qid_eq(qd->qd_id, make_kqid_gid(gid))) { |
@@ -1635,7 +1670,7 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, | |||
1635 | if (error) | 1670 | if (error) |
1636 | return error; | 1671 | return error; |
1637 | 1672 | ||
1638 | error = gfs2_rs_alloc(ip); | 1673 | error = gfs2_rsqa_alloc(ip); |
1639 | if (error) | 1674 | if (error) |
1640 | goto out_put; | 1675 | goto out_put; |
1641 | 1676 | ||
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index ad04b3acae2b..1940dd9cb1c7 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h | |||
@@ -18,6 +18,8 @@ struct gfs2_sbd; | |||
18 | #define NO_UID_QUOTA_CHANGE INVALID_UID | 18 | #define NO_UID_QUOTA_CHANGE INVALID_UID |
19 | #define NO_GID_QUOTA_CHANGE INVALID_GID | 19 | #define NO_GID_QUOTA_CHANGE INVALID_GID |
20 | 20 | ||
21 | extern int gfs2_qa_alloc(struct gfs2_inode *ip); | ||
22 | extern void gfs2_qa_delete(struct gfs2_inode *ip); | ||
21 | extern int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); | 23 | extern int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); |
22 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); | 24 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); |
23 | 25 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index ac0a65d94a7e..cb30748e7b19 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -596,10 +596,11 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) | |||
596 | } | 596 | } |
597 | 597 | ||
598 | /** | 598 | /** |
599 | * gfs2_rs_alloc - make sure we have a reservation assigned to the inode | 599 | * gfs2_rsqa_alloc - make sure we have a reservation assigned to the inode |
600 | * plus a quota allocations data structure, if necessary | ||
600 | * @ip: the inode for this reservation | 601 | * @ip: the inode for this reservation |
601 | */ | 602 | */ |
602 | int gfs2_rs_alloc(struct gfs2_inode *ip) | 603 | int gfs2_rsqa_alloc(struct gfs2_inode *ip) |
603 | { | 604 | { |
604 | int error = 0; | 605 | int error = 0; |
605 | 606 | ||
@@ -614,6 +615,12 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) | |||
614 | } | 615 | } |
615 | 616 | ||
616 | RB_CLEAR_NODE(&ip->i_res->rs_node); | 617 | RB_CLEAR_NODE(&ip->i_res->rs_node); |
618 | error = gfs2_qa_alloc(ip); | ||
619 | if (error) { | ||
620 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | ||
621 | ip->i_res = NULL; | ||
622 | } | ||
623 | |||
617 | out: | 624 | out: |
618 | up_write(&ip->i_rw_mutex); | 625 | up_write(&ip->i_rw_mutex); |
619 | return error; | 626 | return error; |
@@ -678,12 +685,12 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs) | |||
678 | } | 685 | } |
679 | 686 | ||
680 | /** | 687 | /** |
681 | * gfs2_rs_delete - delete a multi-block reservation | 688 | * gfs2_rsqa_delete - delete a multi-block reservation and quota allocation |
682 | * @ip: The inode for this reservation | 689 | * @ip: The inode for this reservation |
683 | * @wcount: The inode's write count, or NULL | 690 | * @wcount: The inode's write count, or NULL |
684 | * | 691 | * |
685 | */ | 692 | */ |
686 | void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount) | 693 | void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount) |
687 | { | 694 | { |
688 | down_write(&ip->i_rw_mutex); | 695 | down_write(&ip->i_rw_mutex); |
689 | if (ip->i_res && ((wcount == NULL) || (atomic_read(wcount) <= 1))) { | 696 | if (ip->i_res && ((wcount == NULL) || (atomic_read(wcount) <= 1))) { |
@@ -691,6 +698,8 @@ void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount) | |||
691 | BUG_ON(ip->i_res->rs_free); | 698 | BUG_ON(ip->i_res->rs_free); |
692 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | 699 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); |
693 | ip->i_res = NULL; | 700 | ip->i_res = NULL; |
701 | |||
702 | gfs2_qa_delete(ip); | ||
694 | } | 703 | } |
695 | up_write(&ip->i_rw_mutex); | 704 | up_write(&ip->i_rw_mutex); |
696 | } | 705 | } |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index c0ab33fa3eed..06bbefaabc31 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -49,9 +49,9 @@ extern void gfs2_inplace_release(struct gfs2_inode *ip); | |||
49 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, | 49 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, |
50 | bool dinode, u64 *generation); | 50 | bool dinode, u64 *generation); |
51 | 51 | ||
52 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); | 52 | extern int gfs2_rsqa_alloc(struct gfs2_inode *ip); |
53 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); | 53 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); |
54 | extern void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount); | 54 | extern void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount); |
55 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); | 55 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
56 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 56 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
57 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); | 57 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 8f94282db2fe..b030ca223067 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -1607,7 +1607,7 @@ out_unlock: | |||
1607 | out: | 1607 | out: |
1608 | /* Case 3 starts here */ | 1608 | /* Case 3 starts here */ |
1609 | truncate_inode_pages_final(&inode->i_data); | 1609 | truncate_inode_pages_final(&inode->i_data); |
1610 | gfs2_rs_delete(ip, NULL); | 1610 | gfs2_rsqa_delete(ip, NULL); |
1611 | gfs2_ordered_del_inode(ip); | 1611 | gfs2_ordered_del_inode(ip); |
1612 | clear_inode(inode); | 1612 | clear_inode(inode); |
1613 | gfs2_dir_hash_inval(ip); | 1613 | gfs2_dir_hash_inval(ip); |
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 86d2035ac669..3b4819d8bdd6 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -27,6 +27,7 @@ struct kmem_cache *gfs2_inode_cachep __read_mostly; | |||
27 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; | 27 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; |
28 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; | 28 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; |
29 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; | 29 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; |
30 | struct kmem_cache *gfs2_qadata_cachep __read_mostly; | ||
30 | struct kmem_cache *gfs2_rsrv_cachep __read_mostly; | 31 | struct kmem_cache *gfs2_rsrv_cachep __read_mostly; |
31 | mempool_t *gfs2_page_pool __read_mostly; | 32 | mempool_t *gfs2_page_pool __read_mostly; |
32 | 33 | ||
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index cbdcbdf39614..9edbcc94bdf6 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -149,6 +149,7 @@ extern struct kmem_cache *gfs2_inode_cachep; | |||
149 | extern struct kmem_cache *gfs2_bufdata_cachep; | 149 | extern struct kmem_cache *gfs2_bufdata_cachep; |
150 | extern struct kmem_cache *gfs2_rgrpd_cachep; | 150 | extern struct kmem_cache *gfs2_rgrpd_cachep; |
151 | extern struct kmem_cache *gfs2_quotad_cachep; | 151 | extern struct kmem_cache *gfs2_quotad_cachep; |
152 | extern struct kmem_cache *gfs2_qadata_cachep; | ||
152 | extern struct kmem_cache *gfs2_rsrv_cachep; | 153 | extern struct kmem_cache *gfs2_rsrv_cachep; |
153 | extern mempool_t *gfs2_page_pool; | 154 | extern mempool_t *gfs2_page_pool; |
154 | 155 | ||