diff options
-rw-r--r-- | fs/gfs2/inode.c | 171 |
1 files changed, 92 insertions, 79 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 381893ceefa4..749b05a960ef 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -364,34 +364,34 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
364 | return 0; | 364 | return 0; |
365 | } | 365 | } |
366 | 366 | ||
367 | static void munge_mode_uid_gid(struct gfs2_inode *dip, umode_t *mode, | 367 | static void munge_mode_uid_gid(const struct gfs2_inode *dip, |
368 | unsigned int *uid, unsigned int *gid) | 368 | struct inode *inode) |
369 | { | 369 | { |
370 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 370 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
371 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { | 371 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
372 | if (S_ISDIR(*mode)) | 372 | if (S_ISDIR(inode->i_mode)) |
373 | *mode |= S_ISUID; | 373 | inode->i_mode |= S_ISUID; |
374 | else if (dip->i_inode.i_uid != current_fsuid()) | 374 | else if (dip->i_inode.i_uid != current_fsuid()) |
375 | *mode &= ~07111; | 375 | inode->i_mode &= ~07111; |
376 | *uid = dip->i_inode.i_uid; | 376 | inode->i_uid = dip->i_inode.i_uid; |
377 | } else | 377 | } else |
378 | *uid = current_fsuid(); | 378 | inode->i_uid = current_fsuid(); |
379 | 379 | ||
380 | if (dip->i_inode.i_mode & S_ISGID) { | 380 | if (dip->i_inode.i_mode & S_ISGID) { |
381 | if (S_ISDIR(*mode)) | 381 | if (S_ISDIR(inode->i_mode)) |
382 | *mode |= S_ISGID; | 382 | inode->i_mode |= S_ISGID; |
383 | *gid = dip->i_inode.i_gid; | 383 | inode->i_gid = dip->i_inode.i_gid; |
384 | } else | 384 | } else |
385 | *gid = current_fsgid(); | 385 | inode->i_gid = current_fsgid(); |
386 | } | 386 | } |
387 | 387 | ||
388 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) | 388 | static int alloc_dinode(struct gfs2_inode *ip) |
389 | { | 389 | { |
390 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 390 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
391 | int error; | 391 | int error; |
392 | int dblocks = 1; | 392 | int dblocks = 1; |
393 | 393 | ||
394 | error = gfs2_inplace_reserve(dip, RES_DINODE); | 394 | error = gfs2_inplace_reserve(ip, RES_DINODE); |
395 | if (error) | 395 | if (error) |
396 | goto out; | 396 | goto out; |
397 | 397 | ||
@@ -399,12 +399,15 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) | |||
399 | if (error) | 399 | if (error) |
400 | goto out_ipreserv; | 400 | goto out_ipreserv; |
401 | 401 | ||
402 | error = gfs2_alloc_blocks(dip, no_addr, &dblocks, 1, generation); | 402 | error = gfs2_alloc_blocks(ip, &ip->i_no_addr, &dblocks, 1, &ip->i_generation); |
403 | ip->i_no_formal_ino = ip->i_generation; | ||
404 | ip->i_inode.i_ino = ip->i_no_addr; | ||
405 | ip->i_goal = ip->i_no_addr; | ||
403 | 406 | ||
404 | gfs2_trans_end(sdp); | 407 | gfs2_trans_end(sdp); |
405 | 408 | ||
406 | out_ipreserv: | 409 | out_ipreserv: |
407 | gfs2_inplace_release(dip); | 410 | gfs2_inplace_release(ip); |
408 | out: | 411 | out: |
409 | return error; | 412 | return error; |
410 | } | 413 | } |
@@ -429,52 +432,42 @@ static void gfs2_init_dir(struct buffer_head *dibh, | |||
429 | /** | 432 | /** |
430 | * init_dinode - Fill in a new dinode structure | 433 | * init_dinode - Fill in a new dinode structure |
431 | * @dip: The directory this inode is being created in | 434 | * @dip: The directory this inode is being created in |
432 | * @gl: The glock covering the new inode | 435 | * @ip: The inode |
433 | * @inum: The inode number | ||
434 | * @mode: The file permissions | ||
435 | * @uid: The uid of the new inode | ||
436 | * @gid: The gid of the new inode | ||
437 | * @generation: The generation number of the new inode | ||
438 | * @dev: The device number (if a device node) | ||
439 | * @symname: The symlink destination (if a symlink) | 436 | * @symname: The symlink destination (if a symlink) |
440 | * @size: The inode size (ignored for directories) | ||
441 | * @bhp: The buffer head (returned to caller) | 437 | * @bhp: The buffer head (returned to caller) |
442 | * | 438 | * |
443 | */ | 439 | */ |
444 | 440 | ||
445 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 441 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, |
446 | const struct gfs2_inum_host *inum, umode_t mode, | 442 | const char *symname, struct buffer_head **bhp) |
447 | unsigned int uid, unsigned int gid, | ||
448 | const u64 *generation, dev_t dev, const char *symname, | ||
449 | unsigned size, struct buffer_head **bhp) | ||
450 | { | 443 | { |
451 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 444 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
452 | struct gfs2_dinode *di; | 445 | struct gfs2_dinode *di; |
453 | struct buffer_head *dibh; | 446 | struct buffer_head *dibh; |
454 | struct timespec tv = CURRENT_TIME; | 447 | struct timespec tv = CURRENT_TIME; |
455 | 448 | ||
456 | dibh = gfs2_meta_new(gl, inum->no_addr); | 449 | dibh = gfs2_meta_new(ip->i_gl, ip->i_no_addr); |
457 | gfs2_trans_add_bh(gl, dibh, 1); | 450 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
458 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); | 451 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); |
459 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 452 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
460 | di = (struct gfs2_dinode *)dibh->b_data; | 453 | di = (struct gfs2_dinode *)dibh->b_data; |
461 | 454 | ||
462 | di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino); | 455 | di->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); |
463 | di->di_num.no_addr = cpu_to_be64(inum->no_addr); | 456 | di->di_num.no_addr = cpu_to_be64(ip->i_no_addr); |
464 | di->di_mode = cpu_to_be32(mode); | 457 | di->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
465 | di->di_uid = cpu_to_be32(uid); | 458 | di->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
466 | di->di_gid = cpu_to_be32(gid); | 459 | di->di_gid = cpu_to_be32(ip->i_inode.i_gid); |
467 | di->di_nlink = 0; | 460 | di->di_nlink = 0; |
468 | di->di_size = cpu_to_be64(size); | 461 | di->di_size = cpu_to_be64(ip->i_inode.i_size); |
469 | di->di_blocks = cpu_to_be64(1); | 462 | di->di_blocks = cpu_to_be64(1); |
470 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | 463 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); |
471 | di->di_major = cpu_to_be32(MAJOR(dev)); | 464 | di->di_major = cpu_to_be32(MAJOR(ip->i_inode.i_rdev)); |
472 | di->di_minor = cpu_to_be32(MINOR(dev)); | 465 | di->di_minor = cpu_to_be32(MINOR(ip->i_inode.i_rdev)); |
473 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 466 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_no_addr); |
474 | di->di_generation = cpu_to_be64(*generation); | 467 | di->di_generation = cpu_to_be64(ip->i_generation); |
475 | di->di_flags = 0; | 468 | di->di_flags = 0; |
476 | di->__pad1 = 0; | 469 | di->__pad1 = 0; |
477 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); | 470 | di->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) ? GFS2_FORMAT_DE : 0); |
478 | di->di_height = 0; | 471 | di->di_height = 0; |
479 | di->__pad2 = 0; | 472 | di->__pad2 = 0; |
480 | di->__pad3 = 0; | 473 | di->__pad3 = 0; |
@@ -487,7 +480,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
487 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | 480 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); |
488 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 481 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
489 | 482 | ||
490 | switch(mode & S_IFMT) { | 483 | switch(ip->i_inode.i_mode & S_IFMT) { |
491 | case S_IFREG: | 484 | case S_IFREG: |
492 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | 485 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || |
493 | gfs2_tune_get(sdp, gt_new_files_jdata)) | 486 | gfs2_tune_get(sdp, gt_new_files_jdata)) |
@@ -502,7 +495,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
502 | gfs2_init_dir(dibh, dip); | 495 | gfs2_init_dir(dibh, dip); |
503 | break; | 496 | break; |
504 | case S_IFLNK: | 497 | case S_IFLNK: |
505 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, size); | 498 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, ip->i_inode.i_size); |
506 | break; | 499 | break; |
507 | } | 500 | } |
508 | 501 | ||
@@ -511,25 +504,22 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
511 | *bhp = dibh; | 504 | *bhp = dibh; |
512 | } | 505 | } |
513 | 506 | ||
514 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 507 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, |
515 | umode_t mode, const struct gfs2_inum_host *inum, | 508 | const char *symname, struct buffer_head **bhp) |
516 | const u64 *generation, dev_t dev, const char *symname, | ||
517 | unsigned int size, struct buffer_head **bhp) | ||
518 | { | 509 | { |
510 | struct inode *inode = &ip->i_inode; | ||
519 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 511 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
520 | unsigned int uid, gid; | ||
521 | int error; | 512 | int error; |
522 | 513 | ||
523 | munge_mode_uid_gid(dip, &mode, &uid, &gid); | ||
524 | error = gfs2_rindex_update(sdp); | 514 | error = gfs2_rindex_update(sdp); |
525 | if (error) | 515 | if (error) |
526 | return error; | 516 | return error; |
527 | 517 | ||
528 | error = gfs2_quota_lock(dip, uid, gid); | 518 | error = gfs2_quota_lock(dip, inode->i_uid, inode->i_gid); |
529 | if (error) | 519 | if (error) |
530 | return error; | 520 | return error; |
531 | 521 | ||
532 | error = gfs2_quota_check(dip, uid, gid); | 522 | error = gfs2_quota_check(dip, inode->i_uid, inode->i_gid); |
533 | if (error) | 523 | if (error) |
534 | goto out_quota; | 524 | goto out_quota; |
535 | 525 | ||
@@ -537,8 +527,8 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
537 | if (error) | 527 | if (error) |
538 | goto out_quota; | 528 | goto out_quota; |
539 | 529 | ||
540 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, symname, size, bhp); | 530 | init_dinode(dip, ip, symname, bhp); |
541 | gfs2_quota_change(dip, +1, uid, gid); | 531 | gfs2_quota_change(dip, +1, inode->i_uid, inode->i_gid); |
542 | gfs2_trans_end(sdp); | 532 | gfs2_trans_end(sdp); |
543 | 533 | ||
544 | out_quota: | 534 | out_quota: |
@@ -657,19 +647,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
657 | struct inode *inode = NULL; | 647 | struct inode *inode = NULL; |
658 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 648 | struct gfs2_inode *dip = GFS2_I(dir), *ip; |
659 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 649 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
660 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 650 | struct gfs2_glock *io_gl; |
661 | int error; | 651 | int error; |
662 | u64 generation; | ||
663 | struct buffer_head *bh = NULL; | 652 | struct buffer_head *bh = NULL; |
664 | 653 | ||
665 | if (!name->len || name->len > GFS2_FNAMESIZE) | 654 | if (!name->len || name->len > GFS2_FNAMESIZE) |
666 | return -ENAMETOOLONG; | 655 | return -ENAMETOOLONG; |
667 | 656 | ||
668 | /* We need a reservation to allocate the new dinode block. The | ||
669 | directory ip temporarily points to the reservation, but this is | ||
670 | being done to get a set of contiguous blocks for the new dinode. | ||
671 | Since this is a create, we don't have a sizehint yet, so it will | ||
672 | have to use the minimum reservation size. */ | ||
673 | error = gfs2_rs_alloc(dip); | 657 | error = gfs2_rs_alloc(dip); |
674 | if (error) | 658 | if (error) |
675 | return error; | 659 | return error; |
@@ -688,45 +672,63 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
688 | if (error) | 672 | if (error) |
689 | goto fail_gunlock; | 673 | goto fail_gunlock; |
690 | 674 | ||
691 | error = alloc_dinode(dip, &inum.no_addr, &generation); | 675 | inode = new_inode(sdp->sd_vfs); |
676 | ip = GFS2_I(inode); | ||
677 | error = gfs2_rs_alloc(ip); | ||
692 | if (error) | 678 | if (error) |
693 | goto fail_gunlock; | 679 | goto fail_free_inode; |
694 | inum.no_formal_ino = generation; | 680 | |
681 | set_bit(GIF_INVALID, &ip->i_flags); | ||
682 | inode->i_mode = mode; | ||
683 | inode->i_rdev = dev; | ||
684 | inode->i_size = size; | ||
685 | munge_mode_uid_gid(dip, inode); | ||
686 | ip->i_goal = dip->i_goal; | ||
695 | 687 | ||
696 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, | 688 | error = alloc_dinode(ip); |
697 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); | ||
698 | if (error) | 689 | if (error) |
699 | goto fail_gunlock; | 690 | goto fail_free_inode; |
700 | 691 | ||
701 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, symname, size, &bh); | 692 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
702 | if (error) | 693 | if (error) |
703 | goto fail_gunlock2; | 694 | goto fail_free_inode; |
704 | 695 | ||
705 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, | 696 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
706 | inum.no_formal_ino, 0); | 697 | if (error) |
707 | if (IS_ERR(inode)) | 698 | goto fail_free_inode; |
699 | |||
700 | error = make_dinode(dip, ip, symname, &bh); | ||
701 | if (error) | ||
708 | goto fail_gunlock2; | 702 | goto fail_gunlock2; |
709 | 703 | ||
710 | ip = GFS2_I(inode); | 704 | error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
711 | error = gfs2_inode_refresh(ip); | ||
712 | if (error) | 705 | if (error) |
713 | goto fail_gunlock2; | 706 | goto fail_gunlock2; |
714 | 707 | ||
715 | error = gfs2_rs_alloc(ip); | 708 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
716 | if (error) | 709 | if (error) |
717 | goto fail_gunlock2; | 710 | goto fail_gunlock2; |
718 | 711 | ||
712 | ip->i_iopen_gh.gh_gl->gl_object = ip; | ||
713 | gfs2_glock_put(io_gl); | ||
714 | gfs2_set_iop(inode); | ||
715 | insert_inode_hash(inode); | ||
716 | |||
717 | error = gfs2_inode_refresh(ip); | ||
718 | if (error) | ||
719 | goto fail_gunlock3; | ||
720 | |||
719 | error = gfs2_acl_create(dip, inode); | 721 | error = gfs2_acl_create(dip, inode); |
720 | if (error) | 722 | if (error) |
721 | goto fail_gunlock2; | 723 | goto fail_gunlock3; |
722 | 724 | ||
723 | error = gfs2_security_init(dip, ip, name); | 725 | error = gfs2_security_init(dip, ip, name); |
724 | if (error) | 726 | if (error) |
725 | goto fail_gunlock2; | 727 | goto fail_gunlock3; |
726 | 728 | ||
727 | error = link_dinode(dip, name, ip); | 729 | error = link_dinode(dip, name, ip); |
728 | if (error) | 730 | if (error) |
729 | goto fail_gunlock2; | 731 | goto fail_gunlock3; |
730 | 732 | ||
731 | if (bh) | 733 | if (bh) |
732 | brelse(bh); | 734 | brelse(bh); |
@@ -739,8 +741,20 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
739 | d_instantiate(dentry, inode); | 741 | d_instantiate(dentry, inode); |
740 | return 0; | 742 | return 0; |
741 | 743 | ||
744 | fail_gunlock3: | ||
745 | gfs2_glock_dq_uninit(ghs + 1); | ||
746 | if (ip->i_gl) | ||
747 | gfs2_glock_put(ip->i_gl); | ||
748 | goto fail_gunlock; | ||
749 | |||
742 | fail_gunlock2: | 750 | fail_gunlock2: |
743 | gfs2_glock_dq_uninit(ghs + 1); | 751 | gfs2_glock_dq_uninit(ghs + 1); |
752 | fail_free_inode: | ||
753 | if (ip->i_gl) | ||
754 | gfs2_glock_put(ip->i_gl); | ||
755 | gfs2_rs_delete(ip); | ||
756 | free_inode_nonrcu(inode); | ||
757 | inode = NULL; | ||
744 | fail_gunlock: | 758 | fail_gunlock: |
745 | gfs2_glock_dq_uninit(ghs); | 759 | gfs2_glock_dq_uninit(ghs); |
746 | if (inode && !IS_ERR(inode)) { | 760 | if (inode && !IS_ERR(inode)) { |
@@ -748,7 +762,6 @@ fail_gunlock: | |||
748 | iput(inode); | 762 | iput(inode); |
749 | } | 763 | } |
750 | fail: | 764 | fail: |
751 | gfs2_rs_delete(dip); | ||
752 | if (bh) | 765 | if (bh) |
753 | brelse(bh); | 766 | brelse(bh); |
754 | return error; | 767 | return error; |