aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-02-26 11:15:20 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2013-04-08 03:39:56 -0400
commitfd4b4e042c6aac980ccac0e829aa1378d2c17bd5 (patch)
treefbb997693736724c2484fe219911d1dde609f090 /fs/gfs2
parent31880c37c11e28cb81c70757e38392b42e695dc6 (diff)
GFS2: Clean up inode creation path
This patch cleans up the inode creation code path in GFS2. After the Orlov allocator was merged, a number of potential improvements are now possible, and this is a first set of these. The quota handling is now updated so that it matches the point in the code where the allocation takes place. This means that the one exception in gfs2_alloc_blocks relating to quota is now no longer required, and we can use the generic code everywhere. In addition the call to figure out whether we need to allocate any extra blocks in order to add a directory entry is moved higher up gfs2_create_inode. This means that if it returns an error, we can deal with that at a stage where it is easier to handle that case. The returned status cannot change during the function since we hold an exclusive lock on the directory. Two calls to gfs2_rindex_update have been changed to one, again at the top of gfs2_create_inode to simplify error handling. The time stamps are also now initialised earlier in the creation process, this is gradually moving towards being able to remove the call to gfs2_refresh_inode in gfs2_inode_create once we have all the fields covered. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/inode.c99
-rw-r--r--fs/gfs2/rgrp.c8
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
410out_ipreserv: 414out_ipreserv:
411 gfs2_inplace_release(ip); 415 gfs2_inplace_release(ip);
416out_quota:
417 gfs2_quota_unlock(ip);
412out: 418out:
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
508static 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
535out_quota:
536 gfs2_quota_unlock(dip);
537 return error;
538}
539
540static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, 515static 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
593fail_end_trans: 560fail_end_trans:
594 gfs2_trans_end(sdp); 561 gfs2_trans_end(sdp);
595
596fail_ipreserv: 562fail_ipreserv:
597 if (alloc_required) 563 gfs2_inplace_release(dip);
598 gfs2_inplace_release(dip);
599
600fail_quota_locks: 564fail_quota_locks:
601 gfs2_quota_unlock(dip); 565 gfs2_quota_unlock(dip);
602
603fail:
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,