diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 188 |
1 files changed, 64 insertions, 124 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index cc00bd1d1f87..8833a4f264e3 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 | } |
@@ -440,59 +446,27 @@ static void gfs2_init_dir(struct buffer_head *dibh, | |||
440 | */ | 446 | */ |
441 | 447 | ||
442 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | 448 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, |
443 | const char *symname, struct buffer_head **bhp) | 449 | const char *symname) |
444 | { | 450 | { |
445 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
446 | struct gfs2_dinode *di; | 451 | struct gfs2_dinode *di; |
447 | struct buffer_head *dibh; | 452 | struct buffer_head *dibh; |
448 | struct timespec tv = CURRENT_TIME; | ||
449 | 453 | ||
450 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); | 454 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); |
451 | gfs2_trans_add_meta(ip->i_gl, dibh); | 455 | gfs2_trans_add_meta(ip->i_gl, dibh); |
452 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); | ||
453 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | ||
454 | di = (struct gfs2_dinode *)dibh->b_data; | 456 | di = (struct gfs2_dinode *)dibh->b_data; |
457 | gfs2_dinode_out(ip, di); | ||
455 | 458 | ||
456 | di->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | ||
457 | di->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | ||
458 | di->di_mode = cpu_to_be32(ip->i_inode.i_mode); | ||
459 | di->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode)); | ||
460 | di->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode)); | ||
461 | di->di_nlink = 0; | ||
462 | di->di_size = cpu_to_be64(ip->i_inode.i_size); | ||
463 | di->di_blocks = cpu_to_be64(1); | ||
464 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | ||
465 | di->di_major = cpu_to_be32(MAJOR(ip->i_inode.i_rdev)); | 459 | 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)); | 460 | 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); | ||
468 | di->di_generation = cpu_to_be64(ip->i_generation); | ||
469 | di->di_flags = 0; | ||
470 | di->__pad1 = 0; | 461 | di->__pad1 = 0; |
471 | di->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) ? GFS2_FORMAT_DE : 0); | ||
472 | di->di_height = 0; | ||
473 | di->__pad2 = 0; | 462 | di->__pad2 = 0; |
474 | di->__pad3 = 0; | 463 | di->__pad3 = 0; |
475 | di->di_depth = 0; | ||
476 | di->di_entries = 0; | ||
477 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 464 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
478 | di->di_eattr = 0; | ||
479 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); | ||
480 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | ||
481 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | ||
482 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 465 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
466 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | ||
483 | 467 | ||
484 | switch(ip->i_inode.i_mode & S_IFMT) { | 468 | switch(ip->i_inode.i_mode & S_IFMT) { |
485 | case S_IFREG: | ||
486 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
487 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
488 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
489 | break; | ||
490 | case S_IFDIR: | 469 | case S_IFDIR: |
491 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | ||
492 | GFS2_DIF_INHERIT_JDATA); | ||
493 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
494 | di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); | ||
495 | di->di_entries = cpu_to_be32(2); | ||
496 | gfs2_init_dir(dibh, dip); | 470 | gfs2_init_dir(dibh, dip); |
497 | break; | 471 | break; |
498 | case S_IFLNK: | 472 | case S_IFLNK: |
@@ -501,63 +475,17 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
501 | } | 475 | } |
502 | 476 | ||
503 | set_buffer_uptodate(dibh); | 477 | set_buffer_uptodate(dibh); |
504 | 478 | brelse(dibh); | |
505 | *bhp = dibh; | ||
506 | } | ||
507 | |||
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 | } | 479 | } |
539 | 480 | ||
540 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | 481 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, |
541 | struct gfs2_inode *ip) | 482 | struct gfs2_inode *ip, int arq) |
542 | { | 483 | { |
543 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 484 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
544 | int alloc_required; | ||
545 | struct buffer_head *dibh; | ||
546 | int error; | 485 | int error; |
547 | 486 | ||
548 | error = gfs2_rindex_update(sdp); | 487 | if (arq) { |
549 | if (error) | 488 | error = gfs2_quota_lock_check(dip); |
550 | return error; | ||
551 | |||
552 | error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); | ||
553 | if (error) | ||
554 | goto fail; | ||
555 | |||
556 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); | ||
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); | ||
561 | if (error) | 489 | if (error) |
562 | goto fail_quota_locks; | 490 | goto fail_quota_locks; |
563 | 491 | ||
@@ -581,26 +509,12 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
581 | if (error) | 509 | if (error) |
582 | goto fail_end_trans; | 510 | goto fail_end_trans; |
583 | 511 | ||
584 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
585 | if (error) | ||
586 | goto fail_end_trans; | ||
587 | set_nlink(&ip->i_inode, S_ISDIR(ip->i_inode.i_mode) ? 2 : 1); | ||
588 | gfs2_trans_add_meta(ip->i_gl, dibh); | ||
589 | gfs2_dinode_out(ip, dibh->b_data); | ||
590 | brelse(dibh); | ||
591 | return 0; | ||
592 | |||
593 | fail_end_trans: | 512 | fail_end_trans: |
594 | gfs2_trans_end(sdp); | 513 | gfs2_trans_end(sdp); |
595 | |||
596 | fail_ipreserv: | 514 | fail_ipreserv: |
597 | if (alloc_required) | 515 | gfs2_inplace_release(dip); |
598 | gfs2_inplace_release(dip); | ||
599 | |||
600 | fail_quota_locks: | 516 | fail_quota_locks: |
601 | gfs2_quota_unlock(dip); | 517 | gfs2_quota_unlock(dip); |
602 | |||
603 | fail: | ||
604 | return error; | 518 | return error; |
605 | } | 519 | } |
606 | 520 | ||
@@ -650,8 +564,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
650 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 564 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
651 | struct gfs2_glock *io_gl; | 565 | struct gfs2_glock *io_gl; |
652 | int error; | 566 | int error; |
653 | struct buffer_head *bh = NULL; | ||
654 | u32 aflags = 0; | 567 | u32 aflags = 0; |
568 | int arq; | ||
655 | 569 | ||
656 | if (!name->len || name->len > GFS2_FNAMESIZE) | 570 | if (!name->len || name->len > GFS2_FNAMESIZE) |
657 | return -ENAMETOOLONG; | 571 | return -ENAMETOOLONG; |
@@ -660,6 +574,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
660 | if (error) | 574 | if (error) |
661 | return error; | 575 | return error; |
662 | 576 | ||
577 | error = gfs2_rindex_update(sdp); | ||
578 | if (error) | ||
579 | return error; | ||
580 | |||
663 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 581 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
664 | if (error) | 582 | if (error) |
665 | goto fail; | 583 | goto fail; |
@@ -674,22 +592,48 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
674 | if (error) | 592 | if (error) |
675 | goto fail_gunlock; | 593 | goto fail_gunlock; |
676 | 594 | ||
595 | arq = error = gfs2_diradd_alloc_required(dir, name); | ||
596 | if (error < 0) | ||
597 | goto fail_gunlock; | ||
598 | |||
677 | inode = new_inode(sdp->sd_vfs); | 599 | inode = new_inode(sdp->sd_vfs); |
678 | if (!inode) { | 600 | error = -ENOMEM; |
679 | gfs2_glock_dq_uninit(ghs); | 601 | if (!inode) |
680 | return -ENOMEM; | 602 | goto fail_gunlock; |
681 | } | 603 | |
682 | ip = GFS2_I(inode); | 604 | ip = GFS2_I(inode); |
683 | error = gfs2_rs_alloc(ip); | 605 | error = gfs2_rs_alloc(ip); |
684 | if (error) | 606 | if (error) |
685 | goto fail_free_inode; | 607 | goto fail_free_inode; |
686 | 608 | ||
687 | set_bit(GIF_INVALID, &ip->i_flags); | ||
688 | inode->i_mode = mode; | 609 | inode->i_mode = mode; |
610 | set_nlink(inode, S_ISDIR(mode) ? 2 : 1); | ||
689 | inode->i_rdev = dev; | 611 | inode->i_rdev = dev; |
690 | inode->i_size = size; | 612 | inode->i_size = size; |
613 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
614 | gfs2_set_inode_blocks(inode, 1); | ||
691 | munge_mode_uid_gid(dip, inode); | 615 | munge_mode_uid_gid(dip, inode); |
692 | ip->i_goal = dip->i_goal; | 616 | ip->i_goal = dip->i_goal; |
617 | ip->i_diskflags = 0; | ||
618 | ip->i_eattr = 0; | ||
619 | ip->i_height = 0; | ||
620 | ip->i_depth = 0; | ||
621 | ip->i_entries = 0; | ||
622 | |||
623 | switch(mode & S_IFMT) { | ||
624 | case S_IFREG: | ||
625 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
626 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
627 | ip->i_diskflags |= GFS2_DIF_JDATA; | ||
628 | gfs2_set_aops(inode); | ||
629 | break; | ||
630 | case S_IFDIR: | ||
631 | ip->i_diskflags |= (dip->i_diskflags & GFS2_DIF_INHERIT_JDATA); | ||
632 | ip->i_diskflags |= GFS2_DIF_JDATA; | ||
633 | ip->i_entries = 2; | ||
634 | break; | ||
635 | } | ||
636 | gfs2_set_inode_flags(inode); | ||
693 | 637 | ||
694 | if ((GFS2_I(sdp->sd_root_dir->d_inode) == dip) || | 638 | if ((GFS2_I(sdp->sd_root_dir->d_inode) == dip) || |
695 | (dip->i_diskflags & GFS2_DIF_TOPDIR)) | 639 | (dip->i_diskflags & GFS2_DIF_TOPDIR)) |
@@ -708,10 +652,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
708 | if (error) | 652 | if (error) |
709 | goto fail_free_inode; | 653 | goto fail_free_inode; |
710 | 654 | ||
711 | error = make_dinode(dip, ip, symname, &bh); | 655 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
712 | if (error) | 656 | if (error) |
713 | goto fail_gunlock2; | 657 | goto fail_gunlock2; |
714 | 658 | ||
659 | init_dinode(dip, ip, symname); | ||
660 | gfs2_trans_end(sdp); | ||
661 | |||
715 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 662 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
716 | if (error) | 663 | if (error) |
717 | goto fail_gunlock2; | 664 | goto fail_gunlock2; |
@@ -725,10 +672,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
725 | gfs2_set_iop(inode); | 672 | gfs2_set_iop(inode); |
726 | insert_inode_hash(inode); | 673 | insert_inode_hash(inode); |
727 | 674 | ||
728 | error = gfs2_inode_refresh(ip); | ||
729 | if (error) | ||
730 | goto fail_gunlock3; | ||
731 | |||
732 | error = gfs2_acl_create(dip, inode); | 675 | error = gfs2_acl_create(dip, inode); |
733 | if (error) | 676 | if (error) |
734 | goto fail_gunlock3; | 677 | goto fail_gunlock3; |
@@ -737,18 +680,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
737 | if (error) | 680 | if (error) |
738 | goto fail_gunlock3; | 681 | goto fail_gunlock3; |
739 | 682 | ||
740 | error = link_dinode(dip, name, ip); | 683 | error = link_dinode(dip, name, ip, arq); |
741 | if (error) | 684 | if (error) |
742 | goto fail_gunlock3; | 685 | goto fail_gunlock3; |
743 | 686 | ||
744 | if (bh) | ||
745 | brelse(bh); | ||
746 | |||
747 | gfs2_trans_end(sdp); | ||
748 | gfs2_inplace_release(dip); | ||
749 | gfs2_quota_unlock(dip); | ||
750 | mark_inode_dirty(inode); | 687 | mark_inode_dirty(inode); |
751 | gfs2_glock_dq_uninit_m(2, ghs); | 688 | gfs2_glock_dq_uninit(ghs); |
689 | gfs2_glock_dq_uninit(ghs + 1); | ||
752 | d_instantiate(dentry, inode); | 690 | d_instantiate(dentry, inode); |
753 | return 0; | 691 | return 0; |
754 | 692 | ||
@@ -769,12 +707,12 @@ fail_free_inode: | |||
769 | fail_gunlock: | 707 | fail_gunlock: |
770 | gfs2_glock_dq_uninit(ghs); | 708 | gfs2_glock_dq_uninit(ghs); |
771 | if (inode && !IS_ERR(inode)) { | 709 | if (inode && !IS_ERR(inode)) { |
710 | clear_nlink(inode); | ||
711 | mark_inode_dirty(inode); | ||
772 | set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags); | 712 | set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags); |
773 | iput(inode); | 713 | iput(inode); |
774 | } | 714 | } |
775 | fail: | 715 | fail: |
776 | if (bh) | ||
777 | brelse(bh); | ||
778 | return error; | 716 | return error; |
779 | } | 717 | } |
780 | 718 | ||
@@ -1151,7 +1089,9 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
1151 | 1089 | ||
1152 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 1090 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1153 | { | 1091 | { |
1154 | return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0, 0); | 1092 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
1093 | unsigned dsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | ||
1094 | return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, dsize, 0); | ||
1155 | } | 1095 | } |
1156 | 1096 | ||
1157 | /** | 1097 | /** |