diff options
-rw-r--r-- | fs/gfs2/inode.c | 99 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 8 |
2 files changed, 38 insertions, 69 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index cc00bd1d1f87..df51557fc986 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -392,11 +392,15 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags) | |||
392 | int error; | 392 | int error; |
393 | int dblocks = 1; | 393 | int dblocks = 1; |
394 | 394 | ||
395 | error = gfs2_inplace_reserve(ip, RES_DINODE, flags); | 395 | error = gfs2_quota_lock_check(ip); |
396 | if (error) | 396 | if (error) |
397 | goto out; | 397 | goto out; |
398 | 398 | ||
399 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0); | 399 | error = gfs2_inplace_reserve(ip, RES_DINODE, flags); |
400 | if (error) | ||
401 | goto out_quota; | ||
402 | |||
403 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 0); | ||
400 | if (error) | 404 | if (error) |
401 | goto out_ipreserv; | 405 | goto out_ipreserv; |
402 | 406 | ||
@@ -409,6 +413,8 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags) | |||
409 | 413 | ||
410 | out_ipreserv: | 414 | out_ipreserv: |
411 | gfs2_inplace_release(ip); | 415 | gfs2_inplace_release(ip); |
416 | out_quota: | ||
417 | gfs2_quota_unlock(ip); | ||
412 | out: | 418 | out: |
413 | return error; | 419 | return error; |
414 | } | 420 | } |
@@ -445,7 +451,6 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
445 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 451 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
446 | struct gfs2_dinode *di; | 452 | struct gfs2_dinode *di; |
447 | struct buffer_head *dibh; | 453 | struct buffer_head *dibh; |
448 | struct timespec tv = CURRENT_TIME; | ||
449 | 454 | ||
450 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); | 455 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); |
451 | gfs2_trans_add_meta(ip->i_gl, dibh); | 456 | gfs2_trans_add_meta(ip->i_gl, dibh); |
@@ -461,7 +466,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
461 | di->di_nlink = 0; | 466 | di->di_nlink = 0; |
462 | di->di_size = cpu_to_be64(ip->i_inode.i_size); | 467 | di->di_size = cpu_to_be64(ip->i_inode.i_size); |
463 | di->di_blocks = cpu_to_be64(1); | 468 | di->di_blocks = cpu_to_be64(1); |
464 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | 469 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
470 | di->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | ||
471 | di->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | ||
465 | di->di_major = cpu_to_be32(MAJOR(ip->i_inode.i_rdev)); | 472 | di->di_major = cpu_to_be32(MAJOR(ip->i_inode.i_rdev)); |
466 | di->di_minor = cpu_to_be32(MINOR(ip->i_inode.i_rdev)); | 473 | di->di_minor = cpu_to_be32(MINOR(ip->i_inode.i_rdev)); |
467 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_no_addr); | 474 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_no_addr); |
@@ -476,9 +483,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
476 | di->di_entries = 0; | 483 | di->di_entries = 0; |
477 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 484 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
478 | di->di_eattr = 0; | 485 | di->di_eattr = 0; |
479 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); | 486 | di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); |
480 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | 487 | di->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); |
481 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | 488 | di->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); |
482 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 489 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
483 | 490 | ||
484 | switch(ip->i_inode.i_mode & S_IFMT) { | 491 | switch(ip->i_inode.i_mode & S_IFMT) { |
@@ -505,58 +512,18 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
505 | *bhp = dibh; | 512 | *bhp = dibh; |
506 | } | 513 | } |
507 | 514 | ||
508 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | ||
509 | const char *symname, struct buffer_head **bhp) | ||
510 | { | ||
511 | struct inode *inode = &ip->i_inode; | ||
512 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
513 | int error; | ||
514 | |||
515 | error = gfs2_rindex_update(sdp); | ||
516 | if (error) | ||
517 | return error; | ||
518 | |||
519 | error = gfs2_quota_lock(dip, inode->i_uid, inode->i_gid); | ||
520 | if (error) | ||
521 | return error; | ||
522 | |||
523 | error = gfs2_quota_check(dip, inode->i_uid, inode->i_gid); | ||
524 | if (error) | ||
525 | goto out_quota; | ||
526 | |||
527 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0); | ||
528 | if (error) | ||
529 | goto out_quota; | ||
530 | |||
531 | init_dinode(dip, ip, symname, bhp); | ||
532 | gfs2_quota_change(dip, +1, inode->i_uid, inode->i_gid); | ||
533 | gfs2_trans_end(sdp); | ||
534 | |||
535 | out_quota: | ||
536 | gfs2_quota_unlock(dip); | ||
537 | return error; | ||
538 | } | ||
539 | |||
540 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | 515 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, |
541 | struct gfs2_inode *ip) | 516 | struct gfs2_inode *ip, int arq) |
542 | { | 517 | { |
543 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 518 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
544 | int alloc_required; | ||
545 | struct buffer_head *dibh; | 519 | struct buffer_head *dibh; |
546 | int error; | 520 | int error; |
547 | 521 | ||
548 | error = gfs2_rindex_update(sdp); | ||
549 | if (error) | ||
550 | return error; | ||
551 | |||
552 | error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); | 522 | error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
553 | if (error) | 523 | if (error) |
554 | goto fail; | 524 | return error; |
555 | 525 | ||
556 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); | 526 | if (arq) { |
557 | if (alloc_required < 0) | ||
558 | goto fail_quota_locks; | ||
559 | if (alloc_required) { | ||
560 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); | 527 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
561 | if (error) | 528 | if (error) |
562 | goto fail_quota_locks; | 529 | goto fail_quota_locks; |
@@ -592,15 +559,10 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
592 | 559 | ||
593 | fail_end_trans: | 560 | fail_end_trans: |
594 | gfs2_trans_end(sdp); | 561 | gfs2_trans_end(sdp); |
595 | |||
596 | fail_ipreserv: | 562 | fail_ipreserv: |
597 | if (alloc_required) | 563 | gfs2_inplace_release(dip); |
598 | gfs2_inplace_release(dip); | ||
599 | |||
600 | fail_quota_locks: | 564 | fail_quota_locks: |
601 | gfs2_quota_unlock(dip); | 565 | gfs2_quota_unlock(dip); |
602 | |||
603 | fail: | ||
604 | return error; | 566 | return error; |
605 | } | 567 | } |
606 | 568 | ||
@@ -652,6 +614,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
652 | int error; | 614 | int error; |
653 | struct buffer_head *bh = NULL; | 615 | struct buffer_head *bh = NULL; |
654 | u32 aflags = 0; | 616 | u32 aflags = 0; |
617 | int arq; | ||
655 | 618 | ||
656 | if (!name->len || name->len > GFS2_FNAMESIZE) | 619 | if (!name->len || name->len > GFS2_FNAMESIZE) |
657 | return -ENAMETOOLONG; | 620 | return -ENAMETOOLONG; |
@@ -660,6 +623,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
660 | if (error) | 623 | if (error) |
661 | return error; | 624 | return error; |
662 | 625 | ||
626 | error = gfs2_rindex_update(sdp); | ||
627 | if (error) | ||
628 | return error; | ||
629 | |||
663 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 630 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
664 | if (error) | 631 | if (error) |
665 | goto fail; | 632 | goto fail; |
@@ -674,11 +641,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
674 | if (error) | 641 | if (error) |
675 | goto fail_gunlock; | 642 | goto fail_gunlock; |
676 | 643 | ||
644 | arq = error = gfs2_diradd_alloc_required(dir, name); | ||
645 | if (error < 0) | ||
646 | goto fail_gunlock; | ||
647 | |||
677 | inode = new_inode(sdp->sd_vfs); | 648 | inode = new_inode(sdp->sd_vfs); |
678 | if (!inode) { | 649 | error = -ENOMEM; |
679 | gfs2_glock_dq_uninit(ghs); | 650 | if (!inode) |
680 | return -ENOMEM; | 651 | goto fail_gunlock; |
681 | } | 652 | |
682 | ip = GFS2_I(inode); | 653 | ip = GFS2_I(inode); |
683 | error = gfs2_rs_alloc(ip); | 654 | error = gfs2_rs_alloc(ip); |
684 | if (error) | 655 | if (error) |
@@ -688,6 +659,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
688 | inode->i_mode = mode; | 659 | inode->i_mode = mode; |
689 | inode->i_rdev = dev; | 660 | inode->i_rdev = dev; |
690 | inode->i_size = size; | 661 | inode->i_size = size; |
662 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
691 | munge_mode_uid_gid(dip, inode); | 663 | munge_mode_uid_gid(dip, inode); |
692 | ip->i_goal = dip->i_goal; | 664 | ip->i_goal = dip->i_goal; |
693 | 665 | ||
@@ -708,10 +680,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
708 | if (error) | 680 | if (error) |
709 | goto fail_free_inode; | 681 | goto fail_free_inode; |
710 | 682 | ||
711 | error = make_dinode(dip, ip, symname, &bh); | 683 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
712 | if (error) | 684 | if (error) |
713 | goto fail_gunlock2; | 685 | goto fail_gunlock2; |
714 | 686 | ||
687 | init_dinode(dip, ip, symname, &bh); | ||
688 | gfs2_trans_end(sdp); | ||
689 | |||
715 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 690 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
716 | if (error) | 691 | if (error) |
717 | goto fail_gunlock2; | 692 | goto fail_gunlock2; |
@@ -737,7 +712,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
737 | if (error) | 712 | if (error) |
738 | goto fail_gunlock3; | 713 | goto fail_gunlock3; |
739 | 714 | ||
740 | error = link_dinode(dip, name, ip); | 715 | error = link_dinode(dip, name, ip, arq); |
741 | if (error) | 716 | if (error) |
742 | goto fail_gunlock3; | 717 | goto fail_gunlock3; |
743 | 718 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 5a51265a4341..71c7fc523d70 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -2180,13 +2180,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
2180 | if (dinode) | 2180 | if (dinode) |
2181 | gfs2_trans_add_unrevoke(sdp, block, 1); | 2181 | gfs2_trans_add_unrevoke(sdp, block, 1); |
2182 | 2182 | ||
2183 | /* | 2183 | gfs2_quota_change(ip, *nblocks, ip->i_inode.i_uid, ip->i_inode.i_gid); |
2184 | * This needs reviewing to see why we cannot do the quota change | ||
2185 | * at this point in the dinode case. | ||
2186 | */ | ||
2187 | if (ndata) | ||
2188 | gfs2_quota_change(ip, ndata, ip->i_inode.i_uid, | ||
2189 | ip->i_inode.i_gid); | ||
2190 | 2184 | ||
2191 | rbm.rgd->rd_free_clone -= *nblocks; | 2185 | rbm.rgd->rd_free_clone -= *nblocks; |
2192 | trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks, | 2186 | trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks, |