diff options
Diffstat (limited to 'fs')
60 files changed, 1162 insertions, 1126 deletions
diff --git a/fs/afs/server.c b/fs/afs/server.c index f49099516675..9fdc7fe3a7bc 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -91,9 +91,10 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell, | |||
91 | 91 | ||
92 | memcpy(&server->addr, addr, sizeof(struct in_addr)); | 92 | memcpy(&server->addr, addr, sizeof(struct in_addr)); |
93 | server->addr.s_addr = addr->s_addr; | 93 | server->addr.s_addr = addr->s_addr; |
94 | _leave(" = %p{%d}", server, atomic_read(&server->usage)); | ||
95 | } else { | ||
96 | _leave(" = NULL [nomem]"); | ||
94 | } | 97 | } |
95 | |||
96 | _leave(" = %p{%d}", server, atomic_read(&server->usage)); | ||
97 | return server; | 98 | return server; |
98 | } | 99 | } |
99 | 100 | ||
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 2c5f9a0e5d72..63039ed9576f 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -990,10 +990,9 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( | |||
990 | 990 | ||
991 | /* clear any space allocated but not loaded */ | 991 | /* clear any space allocated but not loaded */ |
992 | if (phdr->p_filesz < phdr->p_memsz) { | 992 | if (phdr->p_filesz < phdr->p_memsz) { |
993 | ret = clear_user((void *) (seg->addr + phdr->p_filesz), | 993 | if (clear_user((void *) (seg->addr + phdr->p_filesz), |
994 | phdr->p_memsz - phdr->p_filesz); | 994 | phdr->p_memsz - phdr->p_filesz)) |
995 | if (ret) | 995 | return -EFAULT; |
996 | return ret; | ||
997 | } | 996 | } |
998 | 997 | ||
999 | if (mm) { | 998 | if (mm) { |
@@ -1027,7 +1026,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1027 | struct elf32_fdpic_loadseg *seg; | 1026 | struct elf32_fdpic_loadseg *seg; |
1028 | struct elf32_phdr *phdr; | 1027 | struct elf32_phdr *phdr; |
1029 | unsigned long load_addr, delta_vaddr; | 1028 | unsigned long load_addr, delta_vaddr; |
1030 | int loop, dvset, ret; | 1029 | int loop, dvset; |
1031 | 1030 | ||
1032 | load_addr = params->load_addr; | 1031 | load_addr = params->load_addr; |
1033 | delta_vaddr = 0; | 1032 | delta_vaddr = 0; |
@@ -1127,9 +1126,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1127 | * PT_LOAD */ | 1126 | * PT_LOAD */ |
1128 | if (prot & PROT_WRITE && disp > 0) { | 1127 | if (prot & PROT_WRITE && disp > 0) { |
1129 | kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); | 1128 | kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); |
1130 | ret = clear_user((void __user *) maddr, disp); | 1129 | if (clear_user((void __user *) maddr, disp)) |
1131 | if (ret) | 1130 | return -EFAULT; |
1132 | return ret; | ||
1133 | maddr += disp; | 1131 | maddr += disp; |
1134 | } | 1132 | } |
1135 | 1133 | ||
@@ -1164,19 +1162,17 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1164 | if (prot & PROT_WRITE && excess1 > 0) { | 1162 | if (prot & PROT_WRITE && excess1 > 0) { |
1165 | kdebug("clear[%d] ad=%lx sz=%lx", | 1163 | kdebug("clear[%d] ad=%lx sz=%lx", |
1166 | loop, maddr + phdr->p_filesz, excess1); | 1164 | loop, maddr + phdr->p_filesz, excess1); |
1167 | ret = clear_user((void __user *) maddr + phdr->p_filesz, | 1165 | if (clear_user((void __user *) maddr + phdr->p_filesz, |
1168 | excess1); | 1166 | excess1)) |
1169 | if (ret) | 1167 | return -EFAULT; |
1170 | return ret; | ||
1171 | } | 1168 | } |
1172 | 1169 | ||
1173 | #else | 1170 | #else |
1174 | if (excess > 0) { | 1171 | if (excess > 0) { |
1175 | kdebug("clear[%d] ad=%lx sz=%lx", | 1172 | kdebug("clear[%d] ad=%lx sz=%lx", |
1176 | loop, maddr + phdr->p_filesz, excess); | 1173 | loop, maddr + phdr->p_filesz, excess); |
1177 | ret = clear_user((void *) maddr + phdr->p_filesz, excess); | 1174 | if (clear_user((void *) maddr + phdr->p_filesz, excess)) |
1178 | if (ret) | 1175 | return -EFAULT; |
1179 | return ret; | ||
1180 | } | 1176 | } |
1181 | #endif | 1177 | #endif |
1182 | 1178 | ||
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 49566c1687d8..b6ab27ccf214 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -56,15 +56,22 @@ | |||
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * User data (stack, data section and bss) needs to be aligned | 59 | * User data (data section and bss) needs to be aligned. |
60 | * for the same reasons as SLAB memory is, and to the same amount. | 60 | * We pick 0x20 here because it is the max value elf2flt has always |
61 | * Avoid duplicating architecture specific code by using the same | 61 | * used in producing FLAT files, and because it seems to be large |
62 | * macro as with SLAB allocation: | 62 | * enough to make all the gcc alignment related tests happy. |
63 | */ | ||
64 | #define FLAT_DATA_ALIGN (0x20) | ||
65 | |||
66 | /* | ||
67 | * User data (stack) also needs to be aligned. | ||
68 | * Here we can be a bit looser than the data sections since this | ||
69 | * needs to only meet arch ABI requirements. | ||
63 | */ | 70 | */ |
64 | #ifdef ARCH_SLAB_MINALIGN | 71 | #ifdef ARCH_SLAB_MINALIGN |
65 | #define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN) | 72 | #define FLAT_STACK_ALIGN (ARCH_SLAB_MINALIGN) |
66 | #else | 73 | #else |
67 | #define FLAT_DATA_ALIGN (sizeof(void *)) | 74 | #define FLAT_STACK_ALIGN (sizeof(void *)) |
68 | #endif | 75 | #endif |
69 | 76 | ||
70 | #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ | 77 | #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ |
@@ -129,7 +136,7 @@ static unsigned long create_flat_tables( | |||
129 | 136 | ||
130 | sp = (unsigned long *)p; | 137 | sp = (unsigned long *)p; |
131 | sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); | 138 | sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); |
132 | sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN); | 139 | sp = (unsigned long *) ((unsigned long)sp & -FLAT_STACK_ALIGN); |
133 | argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); | 140 | argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); |
134 | envp = argv + (argc + 1); | 141 | envp = argv + (argc + 1); |
135 | 142 | ||
@@ -589,7 +596,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
589 | if (IS_ERR_VALUE(result)) { | 596 | if (IS_ERR_VALUE(result)) { |
590 | printk("Unable to read data+bss, errno %d\n", (int)-result); | 597 | printk("Unable to read data+bss, errno %d\n", (int)-result); |
591 | do_munmap(current->mm, textpos, text_len); | 598 | do_munmap(current->mm, textpos, text_len); |
592 | do_munmap(current->mm, realdatastart, data_len + extra); | 599 | do_munmap(current->mm, realdatastart, len); |
593 | ret = result; | 600 | ret = result; |
594 | goto err; | 601 | goto err; |
595 | } | 602 | } |
@@ -876,7 +883,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
876 | stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ | 883 | stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ |
877 | stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ | 884 | stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ |
878 | stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ | 885 | stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ |
879 | stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ | 886 | stack_len += FLAT_STACK_ALIGN - 1; /* reserve for upcoming alignment */ |
880 | 887 | ||
881 | res = load_flat_file(bprm, &libinfo, 0, &stack_len); | 888 | res = load_flat_file(bprm, &libinfo, 0, &stack_len); |
882 | if (IS_ERR_VALUE(res)) | 889 | if (IS_ERR_VALUE(res)) |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 7346c96308a5..99d6af811747 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -706,8 +706,13 @@ retry: | |||
706 | * @bdev is about to be opened exclusively. Check @bdev can be opened | 706 | * @bdev is about to be opened exclusively. Check @bdev can be opened |
707 | * exclusively and mark that an exclusive open is in progress. Each | 707 | * exclusively and mark that an exclusive open is in progress. Each |
708 | * successful call to this function must be matched with a call to | 708 | * successful call to this function must be matched with a call to |
709 | * either bd_claim() or bd_abort_claiming(). If this function | 709 | * either bd_finish_claiming() or bd_abort_claiming() (which do not |
710 | * succeeds, the matching bd_claim() is guaranteed to succeed. | 710 | * fail). |
711 | * | ||
712 | * This function is used to gain exclusive access to the block device | ||
713 | * without actually causing other exclusive open attempts to fail. It | ||
714 | * should be used when the open sequence itself requires exclusive | ||
715 | * access but may subsequently fail. | ||
711 | * | 716 | * |
712 | * CONTEXT: | 717 | * CONTEXT: |
713 | * Might sleep. | 718 | * Might sleep. |
@@ -734,6 +739,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, | |||
734 | return ERR_PTR(-ENXIO); | 739 | return ERR_PTR(-ENXIO); |
735 | 740 | ||
736 | whole = bdget_disk(disk, 0); | 741 | whole = bdget_disk(disk, 0); |
742 | module_put(disk->fops->owner); | ||
737 | put_disk(disk); | 743 | put_disk(disk); |
738 | if (!whole) | 744 | if (!whole) |
739 | return ERR_PTR(-ENOMEM); | 745 | return ERR_PTR(-ENOMEM); |
@@ -782,15 +788,46 @@ static void bd_abort_claiming(struct block_device *whole, void *holder) | |||
782 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ | 788 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ |
783 | } | 789 | } |
784 | 790 | ||
791 | /* increment holders when we have a legitimate claim. requires bdev_lock */ | ||
792 | static void __bd_claim(struct block_device *bdev, struct block_device *whole, | ||
793 | void *holder) | ||
794 | { | ||
795 | /* note that for a whole device bd_holders | ||
796 | * will be incremented twice, and bd_holder will | ||
797 | * be set to bd_claim before being set to holder | ||
798 | */ | ||
799 | whole->bd_holders++; | ||
800 | whole->bd_holder = bd_claim; | ||
801 | bdev->bd_holders++; | ||
802 | bdev->bd_holder = holder; | ||
803 | } | ||
804 | |||
805 | /** | ||
806 | * bd_finish_claiming - finish claiming a block device | ||
807 | * @bdev: block device of interest (passed to bd_start_claiming()) | ||
808 | * @whole: whole block device returned by bd_start_claiming() | ||
809 | * @holder: holder trying to claim @bdev | ||
810 | * | ||
811 | * Finish a claiming block started by bd_start_claiming(). | ||
812 | * | ||
813 | * CONTEXT: | ||
814 | * Grabs and releases bdev_lock. | ||
815 | */ | ||
816 | static void bd_finish_claiming(struct block_device *bdev, | ||
817 | struct block_device *whole, void *holder) | ||
818 | { | ||
819 | spin_lock(&bdev_lock); | ||
820 | BUG_ON(!bd_may_claim(bdev, whole, holder)); | ||
821 | __bd_claim(bdev, whole, holder); | ||
822 | __bd_abort_claiming(whole, holder); /* not actually an abort */ | ||
823 | } | ||
824 | |||
785 | /** | 825 | /** |
786 | * bd_claim - claim a block device | 826 | * bd_claim - claim a block device |
787 | * @bdev: block device to claim | 827 | * @bdev: block device to claim |
788 | * @holder: holder trying to claim @bdev | 828 | * @holder: holder trying to claim @bdev |
789 | * | 829 | * |
790 | * Try to claim @bdev which must have been opened successfully. This | 830 | * Try to claim @bdev which must have been opened successfully. |
791 | * function may be called with or without preceding | ||
792 | * blk_start_claiming(). In the former case, this function is always | ||
793 | * successful and terminates the claiming block. | ||
794 | * | 831 | * |
795 | * CONTEXT: | 832 | * CONTEXT: |
796 | * Might sleep. | 833 | * Might sleep. |
@@ -806,23 +843,10 @@ int bd_claim(struct block_device *bdev, void *holder) | |||
806 | might_sleep(); | 843 | might_sleep(); |
807 | 844 | ||
808 | spin_lock(&bdev_lock); | 845 | spin_lock(&bdev_lock); |
809 | |||
810 | res = bd_prepare_to_claim(bdev, whole, holder); | 846 | res = bd_prepare_to_claim(bdev, whole, holder); |
811 | if (res == 0) { | 847 | if (res == 0) |
812 | /* note that for a whole device bd_holders | 848 | __bd_claim(bdev, whole, holder); |
813 | * will be incremented twice, and bd_holder will | 849 | spin_unlock(&bdev_lock); |
814 | * be set to bd_claim before being set to holder | ||
815 | */ | ||
816 | whole->bd_holders++; | ||
817 | whole->bd_holder = bd_claim; | ||
818 | bdev->bd_holders++; | ||
819 | bdev->bd_holder = holder; | ||
820 | } | ||
821 | |||
822 | if (whole->bd_claiming) | ||
823 | __bd_abort_claiming(whole, holder); /* releases bdev_lock */ | ||
824 | else | ||
825 | spin_unlock(&bdev_lock); | ||
826 | 850 | ||
827 | return res; | 851 | return res; |
828 | } | 852 | } |
@@ -1476,7 +1500,7 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1476 | 1500 | ||
1477 | if (whole) { | 1501 | if (whole) { |
1478 | if (res == 0) | 1502 | if (res == 0) |
1479 | BUG_ON(bd_claim(bdev, filp) != 0); | 1503 | bd_finish_claiming(bdev, whole, filp); |
1480 | else | 1504 | else |
1481 | bd_abort_claiming(whole, filp); | 1505 | bd_abort_claiming(whole, filp); |
1482 | } | 1506 | } |
@@ -1712,7 +1736,7 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h | |||
1712 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) | 1736 | if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) |
1713 | goto out_blkdev_put; | 1737 | goto out_blkdev_put; |
1714 | 1738 | ||
1715 | BUG_ON(bd_claim(bdev, holder) != 0); | 1739 | bd_finish_claiming(bdev, whole, holder); |
1716 | return bdev; | 1740 | return bdev; |
1717 | 1741 | ||
1718 | out_blkdev_put: | 1742 | out_blkdev_put: |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 8d432cd9d580..2222d161c7b6 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -60,6 +60,8 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | |||
60 | size = __btrfs_getxattr(inode, name, value, size); | 60 | size = __btrfs_getxattr(inode, name, value, size); |
61 | if (size > 0) { | 61 | if (size > 0) { |
62 | acl = posix_acl_from_xattr(value, size); | 62 | acl = posix_acl_from_xattr(value, size); |
63 | if (IS_ERR(acl)) | ||
64 | return acl; | ||
63 | set_cached_acl(inode, type, acl); | 65 | set_cached_acl(inode, type, acl); |
64 | } | 66 | } |
65 | kfree(value); | 67 | kfree(value); |
@@ -160,6 +162,12 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
160 | int ret; | 162 | int ret; |
161 | struct posix_acl *acl = NULL; | 163 | struct posix_acl *acl = NULL; |
162 | 164 | ||
165 | if (!is_owner_or_cap(dentry->d_inode)) | ||
166 | return -EPERM; | ||
167 | |||
168 | if (!IS_POSIXACL(dentry->d_inode)) | ||
169 | return -EOPNOTSUPP; | ||
170 | |||
163 | if (value) { | 171 | if (value) { |
164 | acl = posix_acl_from_xattr(value, size); | 172 | acl = posix_acl_from_xattr(value, size); |
165 | if (acl == NULL) { | 173 | if (acl == NULL) { |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index f3b287c22caf..34f7c375567e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1941,8 +1941,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1941 | btrfs_level_size(tree_root, | 1941 | btrfs_level_size(tree_root, |
1942 | btrfs_super_log_root_level(disk_super)); | 1942 | btrfs_super_log_root_level(disk_super)); |
1943 | 1943 | ||
1944 | log_tree_root = kzalloc(sizeof(struct btrfs_root), | 1944 | log_tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); |
1945 | GFP_NOFS); | 1945 | if (!log_tree_root) { |
1946 | err = -ENOMEM; | ||
1947 | goto fail_trans_kthread; | ||
1948 | } | ||
1946 | 1949 | ||
1947 | __setup_root(nodesize, leafsize, sectorsize, stripesize, | 1950 | __setup_root(nodesize, leafsize, sectorsize, stripesize, |
1948 | log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); | 1951 | log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); |
@@ -1982,6 +1985,10 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1982 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); | 1985 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); |
1983 | if (!fs_info->fs_root) | 1986 | if (!fs_info->fs_root) |
1984 | goto fail_trans_kthread; | 1987 | goto fail_trans_kthread; |
1988 | if (IS_ERR(fs_info->fs_root)) { | ||
1989 | err = PTR_ERR(fs_info->fs_root); | ||
1990 | goto fail_trans_kthread; | ||
1991 | } | ||
1985 | 1992 | ||
1986 | if (!(sb->s_flags & MS_RDONLY)) { | 1993 | if (!(sb->s_flags & MS_RDONLY)) { |
1987 | down_read(&fs_info->cleanup_work_sem); | 1994 | down_read(&fs_info->cleanup_work_sem); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b9080d71991a..32d094002a57 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4360,7 +4360,8 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
4360 | 4360 | ||
4361 | block_rsv = get_block_rsv(trans, root); | 4361 | block_rsv = get_block_rsv(trans, root); |
4362 | cache = btrfs_lookup_block_group(root->fs_info, buf->start); | 4362 | cache = btrfs_lookup_block_group(root->fs_info, buf->start); |
4363 | BUG_ON(block_rsv->space_info != cache->space_info); | 4363 | if (block_rsv->space_info != cache->space_info) |
4364 | goto out; | ||
4364 | 4365 | ||
4365 | if (btrfs_header_generation(buf) == trans->transid) { | 4366 | if (btrfs_header_generation(buf) == trans->transid) { |
4366 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { | 4367 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 787b50a16a14..e354c33df082 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1140,7 +1140,7 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
1140 | /* | 1140 | /* |
1141 | * ok we haven't committed the transaction yet, lets do a commit | 1141 | * ok we haven't committed the transaction yet, lets do a commit |
1142 | */ | 1142 | */ |
1143 | if (file && file->private_data) | 1143 | if (file->private_data) |
1144 | btrfs_ioctl_trans_end(file); | 1144 | btrfs_ioctl_trans_end(file); |
1145 | 1145 | ||
1146 | trans = btrfs_start_transaction(root, 0); | 1146 | trans = btrfs_start_transaction(root, 0); |
@@ -1190,14 +1190,22 @@ static const struct vm_operations_struct btrfs_file_vm_ops = { | |||
1190 | 1190 | ||
1191 | static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) | 1191 | static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) |
1192 | { | 1192 | { |
1193 | vma->vm_ops = &btrfs_file_vm_ops; | 1193 | struct address_space *mapping = filp->f_mapping; |
1194 | |||
1195 | if (!mapping->a_ops->readpage) | ||
1196 | return -ENOEXEC; | ||
1197 | |||
1194 | file_accessed(filp); | 1198 | file_accessed(filp); |
1199 | vma->vm_ops = &btrfs_file_vm_ops; | ||
1200 | vma->vm_flags |= VM_CAN_NONLINEAR; | ||
1201 | |||
1195 | return 0; | 1202 | return 0; |
1196 | } | 1203 | } |
1197 | 1204 | ||
1198 | const struct file_operations btrfs_file_operations = { | 1205 | const struct file_operations btrfs_file_operations = { |
1199 | .llseek = generic_file_llseek, | 1206 | .llseek = generic_file_llseek, |
1200 | .read = do_sync_read, | 1207 | .read = do_sync_read, |
1208 | .write = do_sync_write, | ||
1201 | .aio_read = generic_file_aio_read, | 1209 | .aio_read = generic_file_aio_read, |
1202 | .splice_read = generic_file_splice_read, | 1210 | .splice_read = generic_file_splice_read, |
1203 | .aio_write = btrfs_file_aio_write, | 1211 | .aio_write = btrfs_file_aio_write, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fa6ccc1bfe2a..1bff92ad4744 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2673,7 +2673,7 @@ static int check_path_shared(struct btrfs_root *root, | |||
2673 | struct extent_buffer *eb; | 2673 | struct extent_buffer *eb; |
2674 | int level; | 2674 | int level; |
2675 | int ret; | 2675 | int ret; |
2676 | u64 refs; | 2676 | u64 refs = 1; |
2677 | 2677 | ||
2678 | for (level = 0; level < BTRFS_MAX_LEVEL; level++) { | 2678 | for (level = 0; level < BTRFS_MAX_LEVEL; level++) { |
2679 | if (!path->nodes[level]) | 2679 | if (!path->nodes[level]) |
@@ -6884,7 +6884,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
6884 | if (em->block_start == EXTENT_MAP_HOLE || | 6884 | if (em->block_start == EXTENT_MAP_HOLE || |
6885 | (cur_offset >= inode->i_size && | 6885 | (cur_offset >= inode->i_size && |
6886 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 6886 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
6887 | ret = btrfs_prealloc_file_range(inode, 0, cur_offset, | 6887 | ret = btrfs_prealloc_file_range(inode, mode, cur_offset, |
6888 | last_byte - cur_offset, | 6888 | last_byte - cur_offset, |
6889 | 1 << inode->i_blkbits, | 6889 | 1 << inode->i_blkbits, |
6890 | offset + len, | 6890 | offset + len, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4cdb98cf26de..4dbaf89b1337 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1280,7 +1280,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
1280 | trans = btrfs_start_transaction(root, 0); | 1280 | trans = btrfs_start_transaction(root, 0); |
1281 | if (IS_ERR(trans)) { | 1281 | if (IS_ERR(trans)) { |
1282 | err = PTR_ERR(trans); | 1282 | err = PTR_ERR(trans); |
1283 | goto out; | 1283 | goto out_up_write; |
1284 | } | 1284 | } |
1285 | trans->block_rsv = &root->fs_info->global_block_rsv; | 1285 | trans->block_rsv = &root->fs_info->global_block_rsv; |
1286 | 1286 | ||
@@ -1845,7 +1845,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
1845 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | 1845 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); |
1846 | di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, | 1846 | di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, |
1847 | dir_id, "default", 7, 1); | 1847 | dir_id, "default", 7, 1); |
1848 | if (!di) { | 1848 | if (IS_ERR_OR_NULL(di)) { |
1849 | btrfs_free_path(path); | 1849 | btrfs_free_path(path); |
1850 | btrfs_end_transaction(trans, root); | 1850 | btrfs_end_transaction(trans, root); |
1851 | printk(KERN_ERR "Umm, you don't have the default dir item, " | 1851 | printk(KERN_ERR "Umm, you don't have the default dir item, " |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 05d41e569236..b37d723b9d4a 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -784,16 +784,17 @@ again: | |||
784 | struct btrfs_extent_ref_v0 *ref0; | 784 | struct btrfs_extent_ref_v0 *ref0; |
785 | ref0 = btrfs_item_ptr(eb, path1->slots[0], | 785 | ref0 = btrfs_item_ptr(eb, path1->slots[0], |
786 | struct btrfs_extent_ref_v0); | 786 | struct btrfs_extent_ref_v0); |
787 | root = find_tree_root(rc, eb, ref0); | ||
788 | if (!root->ref_cows) | ||
789 | cur->cowonly = 1; | ||
790 | if (key.objectid == key.offset) { | 787 | if (key.objectid == key.offset) { |
788 | root = find_tree_root(rc, eb, ref0); | ||
791 | if (root && !should_ignore_root(root)) | 789 | if (root && !should_ignore_root(root)) |
792 | cur->root = root; | 790 | cur->root = root; |
793 | else | 791 | else |
794 | list_add(&cur->list, &useless); | 792 | list_add(&cur->list, &useless); |
795 | break; | 793 | break; |
796 | } | 794 | } |
795 | if (is_cowonly_root(btrfs_ref_root_v0(eb, | ||
796 | ref0))) | ||
797 | cur->cowonly = 1; | ||
797 | } | 798 | } |
798 | #else | 799 | #else |
799 | BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY); | 800 | BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY); |
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index b91ccd972644..2d958be761c8 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -330,7 +330,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
330 | { | 330 | { |
331 | struct btrfs_path *path; | 331 | struct btrfs_path *path; |
332 | int ret; | 332 | int ret; |
333 | u32 refs; | ||
334 | struct btrfs_root_item *ri; | 333 | struct btrfs_root_item *ri; |
335 | struct extent_buffer *leaf; | 334 | struct extent_buffer *leaf; |
336 | 335 | ||
@@ -344,8 +343,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
344 | leaf = path->nodes[0]; | 343 | leaf = path->nodes[0]; |
345 | ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item); | 344 | ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item); |
346 | 345 | ||
347 | refs = btrfs_disk_root_refs(leaf, ri); | ||
348 | BUG_ON(refs != 0); | ||
349 | ret = btrfs_del_item(trans, root, path); | 346 | ret = btrfs_del_item(trans, root, path); |
350 | out: | 347 | out: |
351 | btrfs_free_path(path); | 348 | btrfs_free_path(path); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index d34b2dfc9628..f2393b390318 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -360,6 +360,8 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
360 | */ | 360 | */ |
361 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | 361 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); |
362 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); | 362 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); |
363 | if (IS_ERR(di)) | ||
364 | return ERR_CAST(di); | ||
363 | if (!di) { | 365 | if (!di) { |
364 | /* | 366 | /* |
365 | * Ok the default dir item isn't there. This is weird since | 367 | * Ok the default dir item isn't there. This is weird since |
@@ -390,8 +392,8 @@ setup_root: | |||
390 | location.offset = 0; | 392 | location.offset = 0; |
391 | 393 | ||
392 | inode = btrfs_iget(sb, &location, new_root, &new); | 394 | inode = btrfs_iget(sb, &location, new_root, &new); |
393 | if (!inode) | 395 | if (IS_ERR(inode)) |
394 | return ERR_PTR(-ENOMEM); | 396 | return ERR_CAST(inode); |
395 | 397 | ||
396 | /* | 398 | /* |
397 | * If we're just mounting the root most subvol put the inode and return | 399 | * If we're just mounting the root most subvol put the inode and return |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index ae3e3a306445..619b61655ee5 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -981,6 +981,46 @@ static int send_cap_msg(struct ceph_mds_session *session, | |||
981 | return 0; | 981 | return 0; |
982 | } | 982 | } |
983 | 983 | ||
984 | static void __queue_cap_release(struct ceph_mds_session *session, | ||
985 | u64 ino, u64 cap_id, u32 migrate_seq, | ||
986 | u32 issue_seq) | ||
987 | { | ||
988 | struct ceph_msg *msg; | ||
989 | struct ceph_mds_cap_release *head; | ||
990 | struct ceph_mds_cap_item *item; | ||
991 | |||
992 | spin_lock(&session->s_cap_lock); | ||
993 | BUG_ON(!session->s_num_cap_releases); | ||
994 | msg = list_first_entry(&session->s_cap_releases, | ||
995 | struct ceph_msg, list_head); | ||
996 | |||
997 | dout(" adding %llx release to mds%d msg %p (%d left)\n", | ||
998 | ino, session->s_mds, msg, session->s_num_cap_releases); | ||
999 | |||
1000 | BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); | ||
1001 | head = msg->front.iov_base; | ||
1002 | head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); | ||
1003 | item = msg->front.iov_base + msg->front.iov_len; | ||
1004 | item->ino = cpu_to_le64(ino); | ||
1005 | item->cap_id = cpu_to_le64(cap_id); | ||
1006 | item->migrate_seq = cpu_to_le32(migrate_seq); | ||
1007 | item->seq = cpu_to_le32(issue_seq); | ||
1008 | |||
1009 | session->s_num_cap_releases--; | ||
1010 | |||
1011 | msg->front.iov_len += sizeof(*item); | ||
1012 | if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { | ||
1013 | dout(" release msg %p full\n", msg); | ||
1014 | list_move_tail(&msg->list_head, &session->s_cap_releases_done); | ||
1015 | } else { | ||
1016 | dout(" release msg %p at %d/%d (%d)\n", msg, | ||
1017 | (int)le32_to_cpu(head->num), | ||
1018 | (int)CEPH_CAPS_PER_RELEASE, | ||
1019 | (int)msg->front.iov_len); | ||
1020 | } | ||
1021 | spin_unlock(&session->s_cap_lock); | ||
1022 | } | ||
1023 | |||
984 | /* | 1024 | /* |
985 | * Queue cap releases when an inode is dropped from our cache. Since | 1025 | * Queue cap releases when an inode is dropped from our cache. Since |
986 | * inode is about to be destroyed, there is no need for i_lock. | 1026 | * inode is about to be destroyed, there is no need for i_lock. |
@@ -994,41 +1034,9 @@ void ceph_queue_caps_release(struct inode *inode) | |||
994 | while (p) { | 1034 | while (p) { |
995 | struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); | 1035 | struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); |
996 | struct ceph_mds_session *session = cap->session; | 1036 | struct ceph_mds_session *session = cap->session; |
997 | struct ceph_msg *msg; | ||
998 | struct ceph_mds_cap_release *head; | ||
999 | struct ceph_mds_cap_item *item; | ||
1000 | 1037 | ||
1001 | spin_lock(&session->s_cap_lock); | 1038 | __queue_cap_release(session, ceph_ino(inode), cap->cap_id, |
1002 | BUG_ON(!session->s_num_cap_releases); | 1039 | cap->mseq, cap->issue_seq); |
1003 | msg = list_first_entry(&session->s_cap_releases, | ||
1004 | struct ceph_msg, list_head); | ||
1005 | |||
1006 | dout(" adding %p release to mds%d msg %p (%d left)\n", | ||
1007 | inode, session->s_mds, msg, session->s_num_cap_releases); | ||
1008 | |||
1009 | BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); | ||
1010 | head = msg->front.iov_base; | ||
1011 | head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); | ||
1012 | item = msg->front.iov_base + msg->front.iov_len; | ||
1013 | item->ino = cpu_to_le64(ceph_ino(inode)); | ||
1014 | item->cap_id = cpu_to_le64(cap->cap_id); | ||
1015 | item->migrate_seq = cpu_to_le32(cap->mseq); | ||
1016 | item->seq = cpu_to_le32(cap->issue_seq); | ||
1017 | |||
1018 | session->s_num_cap_releases--; | ||
1019 | |||
1020 | msg->front.iov_len += sizeof(*item); | ||
1021 | if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { | ||
1022 | dout(" release msg %p full\n", msg); | ||
1023 | list_move_tail(&msg->list_head, | ||
1024 | &session->s_cap_releases_done); | ||
1025 | } else { | ||
1026 | dout(" release msg %p at %d/%d (%d)\n", msg, | ||
1027 | (int)le32_to_cpu(head->num), | ||
1028 | (int)CEPH_CAPS_PER_RELEASE, | ||
1029 | (int)msg->front.iov_len); | ||
1030 | } | ||
1031 | spin_unlock(&session->s_cap_lock); | ||
1032 | p = rb_next(p); | 1040 | p = rb_next(p); |
1033 | __ceph_remove_cap(cap); | 1041 | __ceph_remove_cap(cap); |
1034 | } | 1042 | } |
@@ -2655,7 +2663,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2655 | struct ceph_mds_caps *h; | 2663 | struct ceph_mds_caps *h; |
2656 | int mds = session->s_mds; | 2664 | int mds = session->s_mds; |
2657 | int op; | 2665 | int op; |
2658 | u32 seq; | 2666 | u32 seq, mseq; |
2659 | struct ceph_vino vino; | 2667 | struct ceph_vino vino; |
2660 | u64 cap_id; | 2668 | u64 cap_id; |
2661 | u64 size, max_size; | 2669 | u64 size, max_size; |
@@ -2675,6 +2683,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2675 | vino.snap = CEPH_NOSNAP; | 2683 | vino.snap = CEPH_NOSNAP; |
2676 | cap_id = le64_to_cpu(h->cap_id); | 2684 | cap_id = le64_to_cpu(h->cap_id); |
2677 | seq = le32_to_cpu(h->seq); | 2685 | seq = le32_to_cpu(h->seq); |
2686 | mseq = le32_to_cpu(h->migrate_seq); | ||
2678 | size = le64_to_cpu(h->size); | 2687 | size = le64_to_cpu(h->size); |
2679 | max_size = le64_to_cpu(h->max_size); | 2688 | max_size = le64_to_cpu(h->max_size); |
2680 | 2689 | ||
@@ -2689,6 +2698,18 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2689 | vino.snap, inode); | 2698 | vino.snap, inode); |
2690 | if (!inode) { | 2699 | if (!inode) { |
2691 | dout(" i don't have ino %llx\n", vino.ino); | 2700 | dout(" i don't have ino %llx\n", vino.ino); |
2701 | |||
2702 | if (op == CEPH_CAP_OP_IMPORT) | ||
2703 | __queue_cap_release(session, vino.ino, cap_id, | ||
2704 | mseq, seq); | ||
2705 | |||
2706 | /* | ||
2707 | * send any full release message to try to move things | ||
2708 | * along for the mds (who clearly thinks we still have this | ||
2709 | * cap). | ||
2710 | */ | ||
2711 | ceph_add_cap_releases(mdsc, session, -1); | ||
2712 | ceph_send_cap_releases(mdsc, session); | ||
2692 | goto done; | 2713 | goto done; |
2693 | } | 2714 | } |
2694 | 2715 | ||
@@ -2714,7 +2735,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2714 | spin_lock(&inode->i_lock); | 2735 | spin_lock(&inode->i_lock); |
2715 | cap = __get_cap_for_mds(ceph_inode(inode), mds); | 2736 | cap = __get_cap_for_mds(ceph_inode(inode), mds); |
2716 | if (!cap) { | 2737 | if (!cap) { |
2717 | dout("no cap on %p ino %llx.%llx from mds%d, releasing\n", | 2738 | dout(" no cap on %p ino %llx.%llx from mds%d\n", |
2718 | inode, ceph_ino(inode), ceph_snap(inode), mds); | 2739 | inode, ceph_ino(inode), ceph_snap(inode), mds); |
2719 | spin_unlock(&inode->i_lock); | 2740 | spin_unlock(&inode->i_lock); |
2720 | goto done; | 2741 | goto done; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 226f5a50d362..ab47f46ca282 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -827,7 +827,7 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
827 | 827 | ||
828 | spin_lock(&dcache_lock); | 828 | spin_lock(&dcache_lock); |
829 | spin_lock(&dn->d_lock); | 829 | spin_lock(&dn->d_lock); |
830 | list_move_tail(&dir->d_subdirs, &dn->d_u.d_child); | 830 | list_move(&dn->d_u.d_child, &dir->d_subdirs); |
831 | dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, | 831 | dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, |
832 | dn->d_u.d_child.prev, dn->d_u.d_child.next); | 832 | dn->d_u.d_child.prev, dn->d_u.d_child.next); |
833 | spin_unlock(&dn->d_lock); | 833 | spin_unlock(&dn->d_lock); |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index b49f12822cbc..1766947fc07a 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1066,9 +1066,9 @@ static int trim_caps(struct ceph_mds_client *mdsc, | |||
1066 | * | 1066 | * |
1067 | * Called under s_mutex. | 1067 | * Called under s_mutex. |
1068 | */ | 1068 | */ |
1069 | static int add_cap_releases(struct ceph_mds_client *mdsc, | 1069 | int ceph_add_cap_releases(struct ceph_mds_client *mdsc, |
1070 | struct ceph_mds_session *session, | 1070 | struct ceph_mds_session *session, |
1071 | int extra) | 1071 | int extra) |
1072 | { | 1072 | { |
1073 | struct ceph_msg *msg; | 1073 | struct ceph_msg *msg; |
1074 | struct ceph_mds_cap_release *head; | 1074 | struct ceph_mds_cap_release *head; |
@@ -1176,8 +1176,8 @@ static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq) | |||
1176 | /* | 1176 | /* |
1177 | * called under s_mutex | 1177 | * called under s_mutex |
1178 | */ | 1178 | */ |
1179 | static void send_cap_releases(struct ceph_mds_client *mdsc, | 1179 | void ceph_send_cap_releases(struct ceph_mds_client *mdsc, |
1180 | struct ceph_mds_session *session) | 1180 | struct ceph_mds_session *session) |
1181 | { | 1181 | { |
1182 | struct ceph_msg *msg; | 1182 | struct ceph_msg *msg; |
1183 | 1183 | ||
@@ -1980,7 +1980,7 @@ out_err: | |||
1980 | } | 1980 | } |
1981 | mutex_unlock(&mdsc->mutex); | 1981 | mutex_unlock(&mdsc->mutex); |
1982 | 1982 | ||
1983 | add_cap_releases(mdsc, req->r_session, -1); | 1983 | ceph_add_cap_releases(mdsc, req->r_session, -1); |
1984 | mutex_unlock(&session->s_mutex); | 1984 | mutex_unlock(&session->s_mutex); |
1985 | 1985 | ||
1986 | /* kick calling process */ | 1986 | /* kick calling process */ |
@@ -2433,6 +2433,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, | |||
2433 | struct ceph_dentry_info *di; | 2433 | struct ceph_dentry_info *di; |
2434 | int mds = session->s_mds; | 2434 | int mds = session->s_mds; |
2435 | struct ceph_mds_lease *h = msg->front.iov_base; | 2435 | struct ceph_mds_lease *h = msg->front.iov_base; |
2436 | u32 seq; | ||
2436 | struct ceph_vino vino; | 2437 | struct ceph_vino vino; |
2437 | int mask; | 2438 | int mask; |
2438 | struct qstr dname; | 2439 | struct qstr dname; |
@@ -2446,6 +2447,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, | |||
2446 | vino.ino = le64_to_cpu(h->ino); | 2447 | vino.ino = le64_to_cpu(h->ino); |
2447 | vino.snap = CEPH_NOSNAP; | 2448 | vino.snap = CEPH_NOSNAP; |
2448 | mask = le16_to_cpu(h->mask); | 2449 | mask = le16_to_cpu(h->mask); |
2450 | seq = le32_to_cpu(h->seq); | ||
2449 | dname.name = (void *)h + sizeof(*h) + sizeof(u32); | 2451 | dname.name = (void *)h + sizeof(*h) + sizeof(u32); |
2450 | dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32); | 2452 | dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32); |
2451 | if (dname.len != get_unaligned_le32(h+1)) | 2453 | if (dname.len != get_unaligned_le32(h+1)) |
@@ -2456,8 +2458,9 @@ static void handle_lease(struct ceph_mds_client *mdsc, | |||
2456 | 2458 | ||
2457 | /* lookup inode */ | 2459 | /* lookup inode */ |
2458 | inode = ceph_find_inode(sb, vino); | 2460 | inode = ceph_find_inode(sb, vino); |
2459 | dout("handle_lease '%s', mask %d, ino %llx %p\n", | 2461 | dout("handle_lease %s, mask %d, ino %llx %p %.*s\n", |
2460 | ceph_lease_op_name(h->action), mask, vino.ino, inode); | 2462 | ceph_lease_op_name(h->action), mask, vino.ino, inode, |
2463 | dname.len, dname.name); | ||
2461 | if (inode == NULL) { | 2464 | if (inode == NULL) { |
2462 | dout("handle_lease no inode %llx\n", vino.ino); | 2465 | dout("handle_lease no inode %llx\n", vino.ino); |
2463 | goto release; | 2466 | goto release; |
@@ -2482,7 +2485,8 @@ static void handle_lease(struct ceph_mds_client *mdsc, | |||
2482 | switch (h->action) { | 2485 | switch (h->action) { |
2483 | case CEPH_MDS_LEASE_REVOKE: | 2486 | case CEPH_MDS_LEASE_REVOKE: |
2484 | if (di && di->lease_session == session) { | 2487 | if (di && di->lease_session == session) { |
2485 | h->seq = cpu_to_le32(di->lease_seq); | 2488 | if (ceph_seq_cmp(di->lease_seq, seq) > 0) |
2489 | h->seq = cpu_to_le32(di->lease_seq); | ||
2486 | __ceph_mdsc_drop_dentry_lease(dentry); | 2490 | __ceph_mdsc_drop_dentry_lease(dentry); |
2487 | } | 2491 | } |
2488 | release = 1; | 2492 | release = 1; |
@@ -2496,7 +2500,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, | |||
2496 | unsigned long duration = | 2500 | unsigned long duration = |
2497 | le32_to_cpu(h->duration_ms) * HZ / 1000; | 2501 | le32_to_cpu(h->duration_ms) * HZ / 1000; |
2498 | 2502 | ||
2499 | di->lease_seq = le32_to_cpu(h->seq); | 2503 | di->lease_seq = seq; |
2500 | dentry->d_time = di->lease_renew_from + duration; | 2504 | dentry->d_time = di->lease_renew_from + duration; |
2501 | di->lease_renew_after = di->lease_renew_from + | 2505 | di->lease_renew_after = di->lease_renew_from + |
2502 | (duration >> 1); | 2506 | (duration >> 1); |
@@ -2686,10 +2690,10 @@ static void delayed_work(struct work_struct *work) | |||
2686 | send_renew_caps(mdsc, s); | 2690 | send_renew_caps(mdsc, s); |
2687 | else | 2691 | else |
2688 | ceph_con_keepalive(&s->s_con); | 2692 | ceph_con_keepalive(&s->s_con); |
2689 | add_cap_releases(mdsc, s, -1); | 2693 | ceph_add_cap_releases(mdsc, s, -1); |
2690 | if (s->s_state == CEPH_MDS_SESSION_OPEN || | 2694 | if (s->s_state == CEPH_MDS_SESSION_OPEN || |
2691 | s->s_state == CEPH_MDS_SESSION_HUNG) | 2695 | s->s_state == CEPH_MDS_SESSION_HUNG) |
2692 | send_cap_releases(mdsc, s); | 2696 | ceph_send_cap_releases(mdsc, s); |
2693 | mutex_unlock(&s->s_mutex); | 2697 | mutex_unlock(&s->s_mutex); |
2694 | ceph_put_mds_session(s); | 2698 | ceph_put_mds_session(s); |
2695 | 2699 | ||
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index d9936c4f1212..b292fa42a66d 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -322,6 +322,12 @@ static inline void ceph_mdsc_put_request(struct ceph_mds_request *req) | |||
322 | kref_put(&req->r_kref, ceph_mdsc_release_request); | 322 | kref_put(&req->r_kref, ceph_mdsc_release_request); |
323 | } | 323 | } |
324 | 324 | ||
325 | extern int ceph_add_cap_releases(struct ceph_mds_client *mdsc, | ||
326 | struct ceph_mds_session *session, | ||
327 | int extra); | ||
328 | extern void ceph_send_cap_releases(struct ceph_mds_client *mdsc, | ||
329 | struct ceph_mds_session *session); | ||
330 | |||
325 | extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); | 331 | extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); |
326 | 332 | ||
327 | extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, | 333 | extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, |
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 21c62e9b7d1d..07a539906e67 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c | |||
@@ -400,6 +400,8 @@ static void release_generic_request(struct kref *kref) | |||
400 | ceph_msg_put(req->reply); | 400 | ceph_msg_put(req->reply); |
401 | if (req->request) | 401 | if (req->request) |
402 | ceph_msg_put(req->request); | 402 | ceph_msg_put(req->request); |
403 | |||
404 | kfree(req); | ||
403 | } | 405 | } |
404 | 406 | ||
405 | static void put_generic_request(struct ceph_mon_generic_request *req) | 407 | static void put_generic_request(struct ceph_mon_generic_request *req) |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 4e0bee240b9d..fa87f51e38e1 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -89,7 +89,7 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
89 | 89 | ||
90 | buf->f_files = le64_to_cpu(st.num_objects); | 90 | buf->f_files = le64_to_cpu(st.num_objects); |
91 | buf->f_ffree = -1; | 91 | buf->f_ffree = -1; |
92 | buf->f_namelen = PATH_MAX; | 92 | buf->f_namelen = NAME_MAX; |
93 | buf->f_frsize = PAGE_CACHE_SIZE; | 93 | buf->f_frsize = PAGE_CACHE_SIZE; |
94 | 94 | ||
95 | /* leave fsid little-endian, regardless of host endianness */ | 95 | /* leave fsid little-endian, regardless of host endianness */ |
@@ -926,7 +926,7 @@ static int ceph_compare_super(struct super_block *sb, void *data) | |||
926 | /* | 926 | /* |
927 | * construct our own bdi so we can control readahead, etc. | 927 | * construct our own bdi so we can control readahead, etc. |
928 | */ | 928 | */ |
929 | static atomic_long_t bdi_seq = ATOMIC_INIT(0); | 929 | static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); |
930 | 930 | ||
931 | static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) | 931 | static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) |
932 | { | 932 | { |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index f1ff785b2292..75541af4b3db 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1952,6 +1952,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping, | |||
1952 | bytes_read -= PAGE_CACHE_SIZE; | 1952 | bytes_read -= PAGE_CACHE_SIZE; |
1953 | continue; | 1953 | continue; |
1954 | } | 1954 | } |
1955 | page_cache_release(page); | ||
1955 | 1956 | ||
1956 | target = kmap_atomic(page, KM_USER0); | 1957 | target = kmap_atomic(page, KM_USER0); |
1957 | 1958 | ||
diff --git a/fs/compat.c b/fs/compat.c index f0b391c50552..6490d2134ff3 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -626,7 +626,7 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
626 | tot_len += len; | 626 | tot_len += len; |
627 | if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ | 627 | if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ |
628 | goto out; | 628 | goto out; |
629 | if (!access_ok(vrfy_dir(type), buf, len)) { | 629 | if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { |
630 | ret = -EFAULT; | 630 | ret = -EFAULT; |
631 | goto out; | 631 | goto out; |
632 | } | 632 | } |
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 41645142b88b..cf78d44a8d6a 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
@@ -72,10 +72,6 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
72 | if (!sd) | 72 | if (!sd) |
73 | return -EINVAL; | 73 | return -EINVAL; |
74 | 74 | ||
75 | error = simple_setattr(dentry, iattr); | ||
76 | if (error) | ||
77 | return error; | ||
78 | |||
79 | sd_iattr = sd->s_iattr; | 75 | sd_iattr = sd->s_iattr; |
80 | if (!sd_iattr) { | 76 | if (!sd_iattr) { |
81 | /* setting attributes for the first time, allocate now */ | 77 | /* setting attributes for the first time, allocate now */ |
@@ -89,9 +85,12 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
89 | sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; | 85 | sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; |
90 | sd->s_iattr = sd_iattr; | 86 | sd->s_iattr = sd_iattr; |
91 | } | 87 | } |
92 | |||
93 | /* attributes were changed atleast once in past */ | 88 | /* attributes were changed atleast once in past */ |
94 | 89 | ||
90 | error = simple_setattr(dentry, iattr); | ||
91 | if (error) | ||
92 | return error; | ||
93 | |||
95 | if (ia_valid & ATTR_UID) | 94 | if (ia_valid & ATTR_UID) |
96 | sd_iattr->ia_uid = iattr->ia_uid; | 95 | sd_iattr->ia_uid = iattr->ia_uid; |
97 | if (ia_valid & ATTR_GID) | 96 | if (ia_valid & ATTR_GID) |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 19214435b752..3675088cb88c 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -1552,7 +1552,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) | |||
1552 | if (error) | 1552 | if (error) |
1553 | return error; | 1553 | return error; |
1554 | } | 1554 | } |
1555 | if (iattr->ia_valid & ATTR_SIZE) { | 1555 | if (iattr->ia_valid & ATTR_SIZE && iattr->ia_size != inode->i_size) { |
1556 | error = ext2_setsize(inode, iattr->ia_size); | 1556 | error = ext2_setsize(inode, iattr->ia_size); |
1557 | if (error) | 1557 | if (error) |
1558 | return error; | 1558 | return error; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 19df61c321fd..42272d67955a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4942,20 +4942,26 @@ void ext4_set_inode_flags(struct inode *inode) | |||
4942 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ | 4942 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ |
4943 | void ext4_get_inode_flags(struct ext4_inode_info *ei) | 4943 | void ext4_get_inode_flags(struct ext4_inode_info *ei) |
4944 | { | 4944 | { |
4945 | unsigned int flags = ei->vfs_inode.i_flags; | 4945 | unsigned int vfs_fl; |
4946 | 4946 | unsigned long old_fl, new_fl; | |
4947 | ei->i_flags &= ~(EXT4_SYNC_FL|EXT4_APPEND_FL| | 4947 | |
4948 | EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|EXT4_DIRSYNC_FL); | 4948 | do { |
4949 | if (flags & S_SYNC) | 4949 | vfs_fl = ei->vfs_inode.i_flags; |
4950 | ei->i_flags |= EXT4_SYNC_FL; | 4950 | old_fl = ei->i_flags; |
4951 | if (flags & S_APPEND) | 4951 | new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL| |
4952 | ei->i_flags |= EXT4_APPEND_FL; | 4952 | EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL| |
4953 | if (flags & S_IMMUTABLE) | 4953 | EXT4_DIRSYNC_FL); |
4954 | ei->i_flags |= EXT4_IMMUTABLE_FL; | 4954 | if (vfs_fl & S_SYNC) |
4955 | if (flags & S_NOATIME) | 4955 | new_fl |= EXT4_SYNC_FL; |
4956 | ei->i_flags |= EXT4_NOATIME_FL; | 4956 | if (vfs_fl & S_APPEND) |
4957 | if (flags & S_DIRSYNC) | 4957 | new_fl |= EXT4_APPEND_FL; |
4958 | ei->i_flags |= EXT4_DIRSYNC_FL; | 4958 | if (vfs_fl & S_IMMUTABLE) |
4959 | new_fl |= EXT4_IMMUTABLE_FL; | ||
4960 | if (vfs_fl & S_NOATIME) | ||
4961 | new_fl |= EXT4_NOATIME_FL; | ||
4962 | if (vfs_fl & S_DIRSYNC) | ||
4963 | new_fl |= EXT4_DIRSYNC_FL; | ||
4964 | } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl); | ||
4959 | } | 4965 | } |
4960 | 4966 | ||
4961 | static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, | 4967 | static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, |
@@ -5191,7 +5197,7 @@ static int ext4_inode_blocks_set(handle_t *handle, | |||
5191 | */ | 5197 | */ |
5192 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 5198 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
5193 | raw_inode->i_blocks_high = 0; | 5199 | raw_inode->i_blocks_high = 0; |
5194 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; | 5200 | ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE); |
5195 | return 0; | 5201 | return 0; |
5196 | } | 5202 | } |
5197 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) | 5203 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) |
@@ -5204,9 +5210,9 @@ static int ext4_inode_blocks_set(handle_t *handle, | |||
5204 | */ | 5210 | */ |
5205 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 5211 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
5206 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); | 5212 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); |
5207 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; | 5213 | ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE); |
5208 | } else { | 5214 | } else { |
5209 | ei->i_flags |= EXT4_HUGE_FILE_FL; | 5215 | ext4_set_inode_flag(inode, EXT4_INODE_HUGE_FILE); |
5210 | /* i_block is stored in file system block size */ | 5216 | /* i_block is stored in file system block size */ |
5211 | i_blocks = i_blocks >> (inode->i_blkbits - 9); | 5217 | i_blocks = i_blocks >> (inode->i_blkbits - 9); |
5212 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 5218 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 3a6c92ac131c..52abfa12762a 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c | |||
@@ -960,6 +960,9 @@ mext_check_arguments(struct inode *orig_inode, | |||
960 | return -EINVAL; | 960 | return -EINVAL; |
961 | } | 961 | } |
962 | 962 | ||
963 | if (IS_IMMUTABLE(donor_inode) || IS_APPEND(donor_inode)) | ||
964 | return -EPERM; | ||
965 | |||
963 | /* Ext4 move extent does not support swapfile */ | 966 | /* Ext4 move extent does not support swapfile */ |
964 | if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) { | 967 | if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) { |
965 | ext4_debug("ext4 move extent: The argument files should " | 968 | ext4_debug("ext4 move extent: The argument files should " |
diff --git a/fs/fcntl.c b/fs/fcntl.c index f74d270ba155..51e11bf5708f 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -274,7 +274,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg) | |||
274 | 274 | ||
275 | ret = copy_from_user(&owner, owner_p, sizeof(owner)); | 275 | ret = copy_from_user(&owner, owner_p, sizeof(owner)); |
276 | if (ret) | 276 | if (ret) |
277 | return ret; | 277 | return -EFAULT; |
278 | 278 | ||
279 | switch (owner.type) { | 279 | switch (owner.type) { |
280 | case F_OWNER_TID: | 280 | case F_OWNER_TID: |
@@ -332,8 +332,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg) | |||
332 | } | 332 | } |
333 | read_unlock(&filp->f_owner.lock); | 333 | read_unlock(&filp->f_owner.lock); |
334 | 334 | ||
335 | if (!ret) | 335 | if (!ret) { |
336 | ret = copy_to_user(owner_p, &owner, sizeof(owner)); | 336 | ret = copy_to_user(owner_p, &owner, sizeof(owner)); |
337 | if (ret) | ||
338 | ret = -EFAULT; | ||
339 | } | ||
337 | return ret; | 340 | return ret; |
338 | } | 341 | } |
339 | 342 | ||
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ea8592b90696..1d1088f48bc2 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -45,7 +45,6 @@ struct wb_writeback_args { | |||
45 | unsigned int for_kupdate:1; | 45 | unsigned int for_kupdate:1; |
46 | unsigned int range_cyclic:1; | 46 | unsigned int range_cyclic:1; |
47 | unsigned int for_background:1; | 47 | unsigned int for_background:1; |
48 | unsigned int sb_pinned:1; | ||
49 | }; | 48 | }; |
50 | 49 | ||
51 | /* | 50 | /* |
@@ -193,8 +192,7 @@ static void bdi_wait_on_work_clear(struct bdi_work *work) | |||
193 | } | 192 | } |
194 | 193 | ||
195 | static void bdi_alloc_queue_work(struct backing_dev_info *bdi, | 194 | static void bdi_alloc_queue_work(struct backing_dev_info *bdi, |
196 | struct wb_writeback_args *args, | 195 | struct wb_writeback_args *args) |
197 | int wait) | ||
198 | { | 196 | { |
199 | struct bdi_work *work; | 197 | struct bdi_work *work; |
200 | 198 | ||
@@ -206,8 +204,6 @@ static void bdi_alloc_queue_work(struct backing_dev_info *bdi, | |||
206 | if (work) { | 204 | if (work) { |
207 | bdi_work_init(work, args); | 205 | bdi_work_init(work, args); |
208 | bdi_queue_work(bdi, work); | 206 | bdi_queue_work(bdi, work); |
209 | if (wait) | ||
210 | bdi_wait_on_work_clear(work); | ||
211 | } else { | 207 | } else { |
212 | struct bdi_writeback *wb = &bdi->wb; | 208 | struct bdi_writeback *wb = &bdi->wb; |
213 | 209 | ||
@@ -234,11 +230,6 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, | |||
234 | .sync_mode = WB_SYNC_ALL, | 230 | .sync_mode = WB_SYNC_ALL, |
235 | .nr_pages = LONG_MAX, | 231 | .nr_pages = LONG_MAX, |
236 | .range_cyclic = 0, | 232 | .range_cyclic = 0, |
237 | /* | ||
238 | * Setting sb_pinned is not necessary for WB_SYNC_ALL, but | ||
239 | * lets make it explicitly clear. | ||
240 | */ | ||
241 | .sb_pinned = 1, | ||
242 | }; | 233 | }; |
243 | struct bdi_work work; | 234 | struct bdi_work work; |
244 | 235 | ||
@@ -254,23 +245,21 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, | |||
254 | * @bdi: the backing device to write from | 245 | * @bdi: the backing device to write from |
255 | * @sb: write inodes from this super_block | 246 | * @sb: write inodes from this super_block |
256 | * @nr_pages: the number of pages to write | 247 | * @nr_pages: the number of pages to write |
257 | * @sb_locked: caller already holds sb umount sem. | ||
258 | * | 248 | * |
259 | * Description: | 249 | * Description: |
260 | * This does WB_SYNC_NONE opportunistic writeback. The IO is only | 250 | * This does WB_SYNC_NONE opportunistic writeback. The IO is only |
261 | * started when this function returns, we make no guarentees on | 251 | * started when this function returns, we make no guarentees on |
262 | * completion. Caller specifies whether sb umount sem is held already or not. | 252 | * completion. Caller need not hold sb s_umount semaphore. |
263 | * | 253 | * |
264 | */ | 254 | */ |
265 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | 255 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, |
266 | long nr_pages, int sb_locked) | 256 | long nr_pages) |
267 | { | 257 | { |
268 | struct wb_writeback_args args = { | 258 | struct wb_writeback_args args = { |
269 | .sb = sb, | 259 | .sb = sb, |
270 | .sync_mode = WB_SYNC_NONE, | 260 | .sync_mode = WB_SYNC_NONE, |
271 | .nr_pages = nr_pages, | 261 | .nr_pages = nr_pages, |
272 | .range_cyclic = 1, | 262 | .range_cyclic = 1, |
273 | .sb_pinned = sb_locked, | ||
274 | }; | 263 | }; |
275 | 264 | ||
276 | /* | 265 | /* |
@@ -282,7 +271,7 @@ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | |||
282 | args.for_background = 1; | 271 | args.for_background = 1; |
283 | } | 272 | } |
284 | 273 | ||
285 | bdi_alloc_queue_work(bdi, &args, sb_locked); | 274 | bdi_alloc_queue_work(bdi, &args); |
286 | } | 275 | } |
287 | 276 | ||
288 | /* | 277 | /* |
@@ -595,7 +584,7 @@ static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc, | |||
595 | /* | 584 | /* |
596 | * Caller must already hold the ref for this | 585 | * Caller must already hold the ref for this |
597 | */ | 586 | */ |
598 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->sb_pinned) { | 587 | if (wbc->sync_mode == WB_SYNC_ALL) { |
599 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); | 588 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); |
600 | return SB_NOT_PINNED; | 589 | return SB_NOT_PINNED; |
601 | } | 590 | } |
@@ -769,7 +758,6 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
769 | .for_kupdate = args->for_kupdate, | 758 | .for_kupdate = args->for_kupdate, |
770 | .for_background = args->for_background, | 759 | .for_background = args->for_background, |
771 | .range_cyclic = args->range_cyclic, | 760 | .range_cyclic = args->range_cyclic, |
772 | .sb_pinned = args->sb_pinned, | ||
773 | }; | 761 | }; |
774 | unsigned long oldest_jif; | 762 | unsigned long oldest_jif; |
775 | long wrote = 0; | 763 | long wrote = 0; |
@@ -912,7 +900,6 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
912 | 900 | ||
913 | while ((work = get_next_work_item(bdi, wb)) != NULL) { | 901 | while ((work = get_next_work_item(bdi, wb)) != NULL) { |
914 | struct wb_writeback_args args = work->args; | 902 | struct wb_writeback_args args = work->args; |
915 | int post_clear; | ||
916 | 903 | ||
917 | /* | 904 | /* |
918 | * Override sync mode, in case we must wait for completion | 905 | * Override sync mode, in case we must wait for completion |
@@ -920,13 +907,11 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
920 | if (force_wait) | 907 | if (force_wait) |
921 | work->args.sync_mode = args.sync_mode = WB_SYNC_ALL; | 908 | work->args.sync_mode = args.sync_mode = WB_SYNC_ALL; |
922 | 909 | ||
923 | post_clear = WB_SYNC_ALL || args.sb_pinned; | ||
924 | |||
925 | /* | 910 | /* |
926 | * If this isn't a data integrity operation, just notify | 911 | * If this isn't a data integrity operation, just notify |
927 | * that we have seen this work and we are now starting it. | 912 | * that we have seen this work and we are now starting it. |
928 | */ | 913 | */ |
929 | if (!post_clear) | 914 | if (args.sync_mode == WB_SYNC_NONE) |
930 | wb_clear_pending(wb, work); | 915 | wb_clear_pending(wb, work); |
931 | 916 | ||
932 | wrote += wb_writeback(wb, &args); | 917 | wrote += wb_writeback(wb, &args); |
@@ -935,7 +920,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
935 | * This is a data integrity writeback, so only do the | 920 | * This is a data integrity writeback, so only do the |
936 | * notification when we have completed the work. | 921 | * notification when we have completed the work. |
937 | */ | 922 | */ |
938 | if (post_clear) | 923 | if (args.sync_mode == WB_SYNC_ALL) |
939 | wb_clear_pending(wb, work); | 924 | wb_clear_pending(wb, work); |
940 | } | 925 | } |
941 | 926 | ||
@@ -1011,7 +996,7 @@ static void bdi_writeback_all(struct super_block *sb, long nr_pages) | |||
1011 | if (!bdi_has_dirty_io(bdi)) | 996 | if (!bdi_has_dirty_io(bdi)) |
1012 | continue; | 997 | continue; |
1013 | 998 | ||
1014 | bdi_alloc_queue_work(bdi, &args, 0); | 999 | bdi_alloc_queue_work(bdi, &args); |
1015 | } | 1000 | } |
1016 | 1001 | ||
1017 | rcu_read_unlock(); | 1002 | rcu_read_unlock(); |
@@ -1220,18 +1205,6 @@ static void wait_sb_inodes(struct super_block *sb) | |||
1220 | iput(old_inode); | 1205 | iput(old_inode); |
1221 | } | 1206 | } |
1222 | 1207 | ||
1223 | static void __writeback_inodes_sb(struct super_block *sb, int sb_locked) | ||
1224 | { | ||
1225 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); | ||
1226 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); | ||
1227 | long nr_to_write; | ||
1228 | |||
1229 | nr_to_write = nr_dirty + nr_unstable + | ||
1230 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); | ||
1231 | |||
1232 | bdi_start_writeback(sb->s_bdi, sb, nr_to_write, sb_locked); | ||
1233 | } | ||
1234 | |||
1235 | /** | 1208 | /** |
1236 | * writeback_inodes_sb - writeback dirty inodes from given super_block | 1209 | * writeback_inodes_sb - writeback dirty inodes from given super_block |
1237 | * @sb: the superblock | 1210 | * @sb: the superblock |
@@ -1243,21 +1216,16 @@ static void __writeback_inodes_sb(struct super_block *sb, int sb_locked) | |||
1243 | */ | 1216 | */ |
1244 | void writeback_inodes_sb(struct super_block *sb) | 1217 | void writeback_inodes_sb(struct super_block *sb) |
1245 | { | 1218 | { |
1246 | __writeback_inodes_sb(sb, 0); | 1219 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); |
1247 | } | 1220 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); |
1248 | EXPORT_SYMBOL(writeback_inodes_sb); | 1221 | long nr_to_write; |
1249 | 1222 | ||
1250 | /** | 1223 | nr_to_write = nr_dirty + nr_unstable + |
1251 | * writeback_inodes_sb_locked - writeback dirty inodes from given super_block | 1224 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); |
1252 | * @sb: the superblock | 1225 | |
1253 | * | 1226 | bdi_start_writeback(sb->s_bdi, sb, nr_to_write); |
1254 | * Like writeback_inodes_sb(), except the caller already holds the | ||
1255 | * sb umount sem. | ||
1256 | */ | ||
1257 | void writeback_inodes_sb_locked(struct super_block *sb) | ||
1258 | { | ||
1259 | __writeback_inodes_sb(sb, 1); | ||
1260 | } | 1227 | } |
1228 | EXPORT_SYMBOL(writeback_inodes_sb); | ||
1261 | 1229 | ||
1262 | /** | 1230 | /** |
1263 | * writeback_inodes_sb_if_idle - start writeback if none underway | 1231 | * writeback_inodes_sb_if_idle - start writeback if none underway |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 47aefd376e54..723b889fd219 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -710,30 +710,26 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
710 | goto superseded; | 710 | goto superseded; |
711 | } | 711 | } |
712 | 712 | ||
713 | if (page) { | 713 | radix_tree_tag_set(&cookie->stores, page->index, |
714 | radix_tree_tag_set(&cookie->stores, page->index, | 714 | FSCACHE_COOKIE_STORING_TAG); |
715 | FSCACHE_COOKIE_STORING_TAG); | 715 | radix_tree_tag_clear(&cookie->stores, page->index, |
716 | radix_tree_tag_clear(&cookie->stores, page->index, | 716 | FSCACHE_COOKIE_PENDING_TAG); |
717 | FSCACHE_COOKIE_PENDING_TAG); | ||
718 | } | ||
719 | 717 | ||
720 | spin_unlock(&cookie->stores_lock); | 718 | spin_unlock(&cookie->stores_lock); |
721 | spin_unlock(&object->lock); | 719 | spin_unlock(&object->lock); |
722 | 720 | ||
723 | if (page) { | 721 | fscache_set_op_state(&op->op, "Store"); |
724 | fscache_set_op_state(&op->op, "Store"); | 722 | fscache_stat(&fscache_n_store_pages); |
725 | fscache_stat(&fscache_n_store_pages); | 723 | fscache_stat(&fscache_n_cop_write_page); |
726 | fscache_stat(&fscache_n_cop_write_page); | 724 | ret = object->cache->ops->write_page(op, page); |
727 | ret = object->cache->ops->write_page(op, page); | 725 | fscache_stat_d(&fscache_n_cop_write_page); |
728 | fscache_stat_d(&fscache_n_cop_write_page); | 726 | fscache_set_op_state(&op->op, "EndWrite"); |
729 | fscache_set_op_state(&op->op, "EndWrite"); | 727 | fscache_end_page_write(object, page); |
730 | fscache_end_page_write(object, page); | 728 | if (ret < 0) { |
731 | if (ret < 0) { | 729 | fscache_set_op_state(&op->op, "Abort"); |
732 | fscache_set_op_state(&op->op, "Abort"); | 730 | fscache_abort_object(object); |
733 | fscache_abort_object(object); | 731 | } else { |
734 | } else { | 732 | fscache_enqueue_operation(&op->op); |
735 | fscache_enqueue_operation(&op->op); | ||
736 | } | ||
737 | } | 733 | } |
738 | 734 | ||
739 | _leave(""); | 735 | _leave(""); |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index a33aab6b5e68..54a92fd02bbd 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -234,8 +234,9 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
234 | if (inode->i_mode != mode) { | 234 | if (inode->i_mode != mode) { |
235 | struct iattr attr; | 235 | struct iattr attr; |
236 | 236 | ||
237 | attr.ia_valid = ATTR_MODE; | 237 | attr.ia_valid = ATTR_MODE | ATTR_CTIME; |
238 | attr.ia_mode = mode; | 238 | attr.ia_mode = mode; |
239 | attr.ia_ctime = CURRENT_TIME_SEC; | ||
239 | rc = jffs2_do_setattr(inode, &attr); | 240 | rc = jffs2_do_setattr(inode, &attr); |
240 | if (rc < 0) | 241 | if (rc < 0) |
241 | return rc; | 242 | return rc; |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 7aa4417e085f..166062a68230 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -222,15 +222,18 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, | |||
222 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); | 222 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); |
223 | 223 | ||
224 | jffs2_free_raw_inode(ri); | 224 | jffs2_free_raw_inode(ri); |
225 | d_instantiate(dentry, inode); | ||
226 | 225 | ||
227 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", | 226 | D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", |
228 | inode->i_ino, inode->i_mode, inode->i_nlink, | 227 | inode->i_ino, inode->i_mode, inode->i_nlink, |
229 | f->inocache->pino_nlink, inode->i_mapping->nrpages)); | 228 | f->inocache->pino_nlink, inode->i_mapping->nrpages)); |
229 | |||
230 | d_instantiate(dentry, inode); | ||
231 | unlock_new_inode(inode); | ||
230 | return 0; | 232 | return 0; |
231 | 233 | ||
232 | fail: | 234 | fail: |
233 | make_bad_inode(inode); | 235 | make_bad_inode(inode); |
236 | unlock_new_inode(inode); | ||
234 | iput(inode); | 237 | iput(inode); |
235 | jffs2_free_raw_inode(ri); | 238 | jffs2_free_raw_inode(ri); |
236 | return ret; | 239 | return ret; |
@@ -360,8 +363,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
360 | /* Eeek. Wave bye bye */ | 363 | /* Eeek. Wave bye bye */ |
361 | mutex_unlock(&f->sem); | 364 | mutex_unlock(&f->sem); |
362 | jffs2_complete_reservation(c); | 365 | jffs2_complete_reservation(c); |
363 | jffs2_clear_inode(inode); | 366 | ret = PTR_ERR(fn); |
364 | return PTR_ERR(fn); | 367 | goto fail; |
365 | } | 368 | } |
366 | 369 | ||
367 | /* We use f->target field to store the target path. */ | 370 | /* We use f->target field to store the target path. */ |
@@ -370,8 +373,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
370 | printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); | 373 | printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); |
371 | mutex_unlock(&f->sem); | 374 | mutex_unlock(&f->sem); |
372 | jffs2_complete_reservation(c); | 375 | jffs2_complete_reservation(c); |
373 | jffs2_clear_inode(inode); | 376 | ret = -ENOMEM; |
374 | return -ENOMEM; | 377 | goto fail; |
375 | } | 378 | } |
376 | 379 | ||
377 | memcpy(f->target, target, targetlen + 1); | 380 | memcpy(f->target, target, targetlen + 1); |
@@ -386,30 +389,24 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
386 | jffs2_complete_reservation(c); | 389 | jffs2_complete_reservation(c); |
387 | 390 | ||
388 | ret = jffs2_init_security(inode, dir_i); | 391 | ret = jffs2_init_security(inode, dir_i); |
389 | if (ret) { | 392 | if (ret) |
390 | jffs2_clear_inode(inode); | 393 | goto fail; |
391 | return ret; | 394 | |
392 | } | ||
393 | ret = jffs2_init_acl_post(inode); | 395 | ret = jffs2_init_acl_post(inode); |
394 | if (ret) { | 396 | if (ret) |
395 | jffs2_clear_inode(inode); | 397 | goto fail; |
396 | return ret; | ||
397 | } | ||
398 | 398 | ||
399 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | 399 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, |
400 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 400 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); |
401 | if (ret) { | 401 | if (ret) |
402 | /* Eep. */ | 402 | goto fail; |
403 | jffs2_clear_inode(inode); | ||
404 | return ret; | ||
405 | } | ||
406 | 403 | ||
407 | rd = jffs2_alloc_raw_dirent(); | 404 | rd = jffs2_alloc_raw_dirent(); |
408 | if (!rd) { | 405 | if (!rd) { |
409 | /* Argh. Now we treat it like a normal delete */ | 406 | /* Argh. Now we treat it like a normal delete */ |
410 | jffs2_complete_reservation(c); | 407 | jffs2_complete_reservation(c); |
411 | jffs2_clear_inode(inode); | 408 | ret = -ENOMEM; |
412 | return -ENOMEM; | 409 | goto fail; |
413 | } | 410 | } |
414 | 411 | ||
415 | dir_f = JFFS2_INODE_INFO(dir_i); | 412 | dir_f = JFFS2_INODE_INFO(dir_i); |
@@ -437,8 +434,8 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
437 | jffs2_complete_reservation(c); | 434 | jffs2_complete_reservation(c); |
438 | jffs2_free_raw_dirent(rd); | 435 | jffs2_free_raw_dirent(rd); |
439 | mutex_unlock(&dir_f->sem); | 436 | mutex_unlock(&dir_f->sem); |
440 | jffs2_clear_inode(inode); | 437 | ret = PTR_ERR(fd); |
441 | return PTR_ERR(fd); | 438 | goto fail; |
442 | } | 439 | } |
443 | 440 | ||
444 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); | 441 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); |
@@ -453,7 +450,14 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char | |||
453 | jffs2_complete_reservation(c); | 450 | jffs2_complete_reservation(c); |
454 | 451 | ||
455 | d_instantiate(dentry, inode); | 452 | d_instantiate(dentry, inode); |
453 | unlock_new_inode(inode); | ||
456 | return 0; | 454 | return 0; |
455 | |||
456 | fail: | ||
457 | make_bad_inode(inode); | ||
458 | unlock_new_inode(inode); | ||
459 | iput(inode); | ||
460 | return ret; | ||
457 | } | 461 | } |
458 | 462 | ||
459 | 463 | ||
@@ -519,8 +523,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
519 | /* Eeek. Wave bye bye */ | 523 | /* Eeek. Wave bye bye */ |
520 | mutex_unlock(&f->sem); | 524 | mutex_unlock(&f->sem); |
521 | jffs2_complete_reservation(c); | 525 | jffs2_complete_reservation(c); |
522 | jffs2_clear_inode(inode); | 526 | ret = PTR_ERR(fn); |
523 | return PTR_ERR(fn); | 527 | goto fail; |
524 | } | 528 | } |
525 | /* No data here. Only a metadata node, which will be | 529 | /* No data here. Only a metadata node, which will be |
526 | obsoleted by the first data write | 530 | obsoleted by the first data write |
@@ -531,30 +535,24 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
531 | jffs2_complete_reservation(c); | 535 | jffs2_complete_reservation(c); |
532 | 536 | ||
533 | ret = jffs2_init_security(inode, dir_i); | 537 | ret = jffs2_init_security(inode, dir_i); |
534 | if (ret) { | 538 | if (ret) |
535 | jffs2_clear_inode(inode); | 539 | goto fail; |
536 | return ret; | 540 | |
537 | } | ||
538 | ret = jffs2_init_acl_post(inode); | 541 | ret = jffs2_init_acl_post(inode); |
539 | if (ret) { | 542 | if (ret) |
540 | jffs2_clear_inode(inode); | 543 | goto fail; |
541 | return ret; | ||
542 | } | ||
543 | 544 | ||
544 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | 545 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, |
545 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 546 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); |
546 | if (ret) { | 547 | if (ret) |
547 | /* Eep. */ | 548 | goto fail; |
548 | jffs2_clear_inode(inode); | ||
549 | return ret; | ||
550 | } | ||
551 | 549 | ||
552 | rd = jffs2_alloc_raw_dirent(); | 550 | rd = jffs2_alloc_raw_dirent(); |
553 | if (!rd) { | 551 | if (!rd) { |
554 | /* Argh. Now we treat it like a normal delete */ | 552 | /* Argh. Now we treat it like a normal delete */ |
555 | jffs2_complete_reservation(c); | 553 | jffs2_complete_reservation(c); |
556 | jffs2_clear_inode(inode); | 554 | ret = -ENOMEM; |
557 | return -ENOMEM; | 555 | goto fail; |
558 | } | 556 | } |
559 | 557 | ||
560 | dir_f = JFFS2_INODE_INFO(dir_i); | 558 | dir_f = JFFS2_INODE_INFO(dir_i); |
@@ -582,8 +580,8 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
582 | jffs2_complete_reservation(c); | 580 | jffs2_complete_reservation(c); |
583 | jffs2_free_raw_dirent(rd); | 581 | jffs2_free_raw_dirent(rd); |
584 | mutex_unlock(&dir_f->sem); | 582 | mutex_unlock(&dir_f->sem); |
585 | jffs2_clear_inode(inode); | 583 | ret = PTR_ERR(fd); |
586 | return PTR_ERR(fd); | 584 | goto fail; |
587 | } | 585 | } |
588 | 586 | ||
589 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); | 587 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); |
@@ -599,7 +597,14 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) | |||
599 | jffs2_complete_reservation(c); | 597 | jffs2_complete_reservation(c); |
600 | 598 | ||
601 | d_instantiate(dentry, inode); | 599 | d_instantiate(dentry, inode); |
600 | unlock_new_inode(inode); | ||
602 | return 0; | 601 | return 0; |
602 | |||
603 | fail: | ||
604 | make_bad_inode(inode); | ||
605 | unlock_new_inode(inode); | ||
606 | iput(inode); | ||
607 | return ret; | ||
603 | } | 608 | } |
604 | 609 | ||
605 | static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | 610 | static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) |
@@ -693,8 +698,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
693 | /* Eeek. Wave bye bye */ | 698 | /* Eeek. Wave bye bye */ |
694 | mutex_unlock(&f->sem); | 699 | mutex_unlock(&f->sem); |
695 | jffs2_complete_reservation(c); | 700 | jffs2_complete_reservation(c); |
696 | jffs2_clear_inode(inode); | 701 | ret = PTR_ERR(fn); |
697 | return PTR_ERR(fn); | 702 | goto fail; |
698 | } | 703 | } |
699 | /* No data here. Only a metadata node, which will be | 704 | /* No data here. Only a metadata node, which will be |
700 | obsoleted by the first data write | 705 | obsoleted by the first data write |
@@ -705,30 +710,24 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
705 | jffs2_complete_reservation(c); | 710 | jffs2_complete_reservation(c); |
706 | 711 | ||
707 | ret = jffs2_init_security(inode, dir_i); | 712 | ret = jffs2_init_security(inode, dir_i); |
708 | if (ret) { | 713 | if (ret) |
709 | jffs2_clear_inode(inode); | 714 | goto fail; |
710 | return ret; | 715 | |
711 | } | ||
712 | ret = jffs2_init_acl_post(inode); | 716 | ret = jffs2_init_acl_post(inode); |
713 | if (ret) { | 717 | if (ret) |
714 | jffs2_clear_inode(inode); | 718 | goto fail; |
715 | return ret; | ||
716 | } | ||
717 | 719 | ||
718 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, | 720 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen, |
719 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | 721 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); |
720 | if (ret) { | 722 | if (ret) |
721 | /* Eep. */ | 723 | goto fail; |
722 | jffs2_clear_inode(inode); | ||
723 | return ret; | ||
724 | } | ||
725 | 724 | ||
726 | rd = jffs2_alloc_raw_dirent(); | 725 | rd = jffs2_alloc_raw_dirent(); |
727 | if (!rd) { | 726 | if (!rd) { |
728 | /* Argh. Now we treat it like a normal delete */ | 727 | /* Argh. Now we treat it like a normal delete */ |
729 | jffs2_complete_reservation(c); | 728 | jffs2_complete_reservation(c); |
730 | jffs2_clear_inode(inode); | 729 | ret = -ENOMEM; |
731 | return -ENOMEM; | 730 | goto fail; |
732 | } | 731 | } |
733 | 732 | ||
734 | dir_f = JFFS2_INODE_INFO(dir_i); | 733 | dir_f = JFFS2_INODE_INFO(dir_i); |
@@ -759,8 +758,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
759 | jffs2_complete_reservation(c); | 758 | jffs2_complete_reservation(c); |
760 | jffs2_free_raw_dirent(rd); | 759 | jffs2_free_raw_dirent(rd); |
761 | mutex_unlock(&dir_f->sem); | 760 | mutex_unlock(&dir_f->sem); |
762 | jffs2_clear_inode(inode); | 761 | ret = PTR_ERR(fd); |
763 | return PTR_ERR(fd); | 762 | goto fail; |
764 | } | 763 | } |
765 | 764 | ||
766 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); | 765 | dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); |
@@ -775,8 +774,14 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de | |||
775 | jffs2_complete_reservation(c); | 774 | jffs2_complete_reservation(c); |
776 | 775 | ||
777 | d_instantiate(dentry, inode); | 776 | d_instantiate(dentry, inode); |
778 | 777 | unlock_new_inode(inode); | |
779 | return 0; | 778 | return 0; |
779 | |||
780 | fail: | ||
781 | make_bad_inode(inode); | ||
782 | unlock_new_inode(inode); | ||
783 | iput(inode); | ||
784 | return ret; | ||
780 | } | 785 | } |
781 | 786 | ||
782 | static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | 787 | static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 8bc2c80ab159..459d39d1ea0b 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -465,7 +465,12 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i | |||
465 | inode->i_blocks = 0; | 465 | inode->i_blocks = 0; |
466 | inode->i_size = 0; | 466 | inode->i_size = 0; |
467 | 467 | ||
468 | insert_inode_hash(inode); | 468 | if (insert_inode_locked(inode) < 0) { |
469 | make_bad_inode(inode); | ||
470 | unlock_new_inode(inode); | ||
471 | iput(inode); | ||
472 | return ERR_PTR(-EINVAL); | ||
473 | } | ||
469 | 474 | ||
470 | return inode; | 475 | return inode; |
471 | } | 476 | } |
diff --git a/fs/libfs.c b/fs/libfs.c index 09e1016eb774..dcaf972cbf1b 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -489,7 +489,8 @@ int simple_write_end(struct file *file, struct address_space *mapping, | |||
489 | * unique inode values later for this filesystem, then you must take care | 489 | * unique inode values later for this filesystem, then you must take care |
490 | * to pass it an appropriate max_reserved value to avoid collisions. | 490 | * to pass it an appropriate max_reserved value to avoid collisions. |
491 | */ | 491 | */ |
492 | int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) | 492 | int simple_fill_super(struct super_block *s, unsigned long magic, |
493 | struct tree_descr *files) | ||
493 | { | 494 | { |
494 | struct inode *inode; | 495 | struct inode *inode; |
495 | struct dentry *root; | 496 | struct dentry *root; |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 91969589131c..1dbf921ca44b 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -75,10 +75,6 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n) | |||
75 | if (!IS_ERR(page)) | 75 | if (!IS_ERR(page)) |
76 | kmap(page); | 76 | kmap(page); |
77 | return page; | 77 | return page; |
78 | |||
79 | fail: | ||
80 | dir_put_page(page); | ||
81 | return ERR_PTR(-EIO); | ||
82 | } | 78 | } |
83 | 79 | ||
84 | static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi) | 80 | static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi) |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 12f7109720c2..4a2734758778 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -4122,8 +4122,8 @@ nfs4_state_shutdown(void) | |||
4122 | nfs4_lock_state(); | 4122 | nfs4_lock_state(); |
4123 | nfs4_release_reclaim(); | 4123 | nfs4_release_reclaim(); |
4124 | __nfs4_state_shutdown(); | 4124 | __nfs4_state_shutdown(); |
4125 | nfsd4_destroy_callback_queue(); | ||
4126 | nfs4_unlock_state(); | 4125 | nfs4_unlock_state(); |
4126 | nfsd4_destroy_callback_queue(); | ||
4127 | } | 4127 | } |
4128 | 4128 | ||
4129 | /* | 4129 | /* |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index ebbf3b6b2457..3c111120b619 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -443,8 +443,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
443 | if (size_change) | 443 | if (size_change) |
444 | put_write_access(inode); | 444 | put_write_access(inode); |
445 | if (!err) | 445 | if (!err) |
446 | if (EX_ISSYNC(fhp->fh_export)) | 446 | commit_metadata(fhp); |
447 | write_inode_now(inode, 1); | ||
448 | out: | 447 | out: |
449 | return err; | 448 | return err; |
450 | 449 | ||
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h index af638d59e3bf..43c8c5b541fd 100644 --- a/fs/nilfs2/btree.h +++ b/fs/nilfs2/btree.h | |||
@@ -75,8 +75,6 @@ struct nilfs_btree_path { | |||
75 | 75 | ||
76 | extern struct kmem_cache *nilfs_btree_path_cache; | 76 | extern struct kmem_cache *nilfs_btree_path_cache; |
77 | 77 | ||
78 | int nilfs_btree_path_cache_init(void); | ||
79 | void nilfs_btree_path_cache_destroy(void); | ||
80 | int nilfs_btree_init(struct nilfs_bmap *); | 78 | int nilfs_btree_init(struct nilfs_bmap *); |
81 | int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64, | 79 | int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64, |
82 | const __u64 *, const __u64 *, int); | 80 | const __u64 *, const __u64 *, int); |
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h index fdf1c3b6d673..85fbb66455e2 100644 --- a/fs/nilfs2/segbuf.h +++ b/fs/nilfs2/segbuf.h | |||
@@ -127,8 +127,6 @@ struct nilfs_segment_buffer { | |||
127 | 127 | ||
128 | extern struct kmem_cache *nilfs_segbuf_cachep; | 128 | extern struct kmem_cache *nilfs_segbuf_cachep; |
129 | 129 | ||
130 | int __init nilfs_init_segbuf_cache(void); | ||
131 | void nilfs_destroy_segbuf_cache(void); | ||
132 | struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); | 130 | struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); |
133 | void nilfs_segbuf_free(struct nilfs_segment_buffer *); | 131 | void nilfs_segbuf_free(struct nilfs_segment_buffer *); |
134 | void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, | 132 | void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, |
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index dca142361ccf..01e20dbb217d 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
@@ -221,8 +221,6 @@ enum { | |||
221 | extern struct kmem_cache *nilfs_transaction_cachep; | 221 | extern struct kmem_cache *nilfs_transaction_cachep; |
222 | 222 | ||
223 | /* segment.c */ | 223 | /* segment.c */ |
224 | extern int nilfs_init_transaction_cache(void); | ||
225 | extern void nilfs_destroy_transaction_cache(void); | ||
226 | extern void nilfs_relax_pressure_in_lock(struct super_block *); | 224 | extern void nilfs_relax_pressure_in_lock(struct super_block *); |
227 | 225 | ||
228 | extern int nilfs_construct_segment(struct super_block *); | 226 | extern int nilfs_construct_segment(struct super_block *); |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 03b34b738993..414ef68931cf 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -1130,13 +1130,13 @@ static void nilfs_segbuf_init_once(void *obj) | |||
1130 | 1130 | ||
1131 | static void nilfs_destroy_cachep(void) | 1131 | static void nilfs_destroy_cachep(void) |
1132 | { | 1132 | { |
1133 | if (nilfs_inode_cachep) | 1133 | if (nilfs_inode_cachep) |
1134 | kmem_cache_destroy(nilfs_inode_cachep); | 1134 | kmem_cache_destroy(nilfs_inode_cachep); |
1135 | if (nilfs_transaction_cachep) | 1135 | if (nilfs_transaction_cachep) |
1136 | kmem_cache_destroy(nilfs_transaction_cachep); | 1136 | kmem_cache_destroy(nilfs_transaction_cachep); |
1137 | if (nilfs_segbuf_cachep) | 1137 | if (nilfs_segbuf_cachep) |
1138 | kmem_cache_destroy(nilfs_segbuf_cachep); | 1138 | kmem_cache_destroy(nilfs_segbuf_cachep); |
1139 | if (nilfs_btree_path_cache) | 1139 | if (nilfs_btree_path_cache) |
1140 | kmem_cache_destroy(nilfs_btree_path_cache); | 1140 | kmem_cache_destroy(nilfs_btree_path_cache); |
1141 | } | 1141 | } |
1142 | 1142 | ||
@@ -26,9 +26,14 @@ | |||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * The max size that a non-root user is allowed to grow the pipe. Can | 28 | * The max size that a non-root user is allowed to grow the pipe. Can |
29 | * be set by root in /proc/sys/fs/pipe-max-pages | 29 | * be set by root in /proc/sys/fs/pipe-max-size |
30 | */ | 30 | */ |
31 | unsigned int pipe_max_pages = PIPE_DEF_BUFFERS * 16; | 31 | unsigned int pipe_max_size = 1048576; |
32 | |||
33 | /* | ||
34 | * Minimum pipe size, as required by POSIX | ||
35 | */ | ||
36 | unsigned int pipe_min_size = PAGE_SIZE; | ||
32 | 37 | ||
33 | /* | 38 | /* |
34 | * We use a start+len construction, which provides full use of the | 39 | * We use a start+len construction, which provides full use of the |
@@ -1118,26 +1123,20 @@ SYSCALL_DEFINE1(pipe, int __user *, fildes) | |||
1118 | * Allocate a new array of pipe buffers and copy the info over. Returns the | 1123 | * Allocate a new array of pipe buffers and copy the info over. Returns the |
1119 | * pipe size if successful, or return -ERROR on error. | 1124 | * pipe size if successful, or return -ERROR on error. |
1120 | */ | 1125 | */ |
1121 | static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) | 1126 | static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) |
1122 | { | 1127 | { |
1123 | struct pipe_buffer *bufs; | 1128 | struct pipe_buffer *bufs; |
1124 | 1129 | ||
1125 | /* | 1130 | /* |
1126 | * Must be a power-of-2 currently | ||
1127 | */ | ||
1128 | if (!is_power_of_2(arg)) | ||
1129 | return -EINVAL; | ||
1130 | |||
1131 | /* | ||
1132 | * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't | 1131 | * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't |
1133 | * expect a lot of shrink+grow operations, just free and allocate | 1132 | * expect a lot of shrink+grow operations, just free and allocate |
1134 | * again like we would do for growing. If the pipe currently | 1133 | * again like we would do for growing. If the pipe currently |
1135 | * contains more buffers than arg, then return busy. | 1134 | * contains more buffers than arg, then return busy. |
1136 | */ | 1135 | */ |
1137 | if (arg < pipe->nrbufs) | 1136 | if (nr_pages < pipe->nrbufs) |
1138 | return -EBUSY; | 1137 | return -EBUSY; |
1139 | 1138 | ||
1140 | bufs = kcalloc(arg, sizeof(struct pipe_buffer), GFP_KERNEL); | 1139 | bufs = kcalloc(nr_pages, sizeof(struct pipe_buffer), GFP_KERNEL); |
1141 | if (unlikely(!bufs)) | 1140 | if (unlikely(!bufs)) |
1142 | return -ENOMEM; | 1141 | return -ENOMEM; |
1143 | 1142 | ||
@@ -1146,20 +1145,56 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) | |||
1146 | * and adjust the indexes. | 1145 | * and adjust the indexes. |
1147 | */ | 1146 | */ |
1148 | if (pipe->nrbufs) { | 1147 | if (pipe->nrbufs) { |
1149 | const unsigned int tail = pipe->nrbufs & (pipe->buffers - 1); | 1148 | unsigned int tail; |
1150 | const unsigned int head = pipe->nrbufs - tail; | 1149 | unsigned int head; |
1150 | |||
1151 | tail = pipe->curbuf + pipe->nrbufs; | ||
1152 | if (tail < pipe->buffers) | ||
1153 | tail = 0; | ||
1154 | else | ||
1155 | tail &= (pipe->buffers - 1); | ||
1151 | 1156 | ||
1157 | head = pipe->nrbufs - tail; | ||
1152 | if (head) | 1158 | if (head) |
1153 | memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); | 1159 | memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); |
1154 | if (tail) | 1160 | if (tail) |
1155 | memcpy(bufs + head, pipe->bufs + pipe->curbuf, tail * sizeof(struct pipe_buffer)); | 1161 | memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer)); |
1156 | } | 1162 | } |
1157 | 1163 | ||
1158 | pipe->curbuf = 0; | 1164 | pipe->curbuf = 0; |
1159 | kfree(pipe->bufs); | 1165 | kfree(pipe->bufs); |
1160 | pipe->bufs = bufs; | 1166 | pipe->bufs = bufs; |
1161 | pipe->buffers = arg; | 1167 | pipe->buffers = nr_pages; |
1162 | return arg; | 1168 | return nr_pages * PAGE_SIZE; |
1169 | } | ||
1170 | |||
1171 | /* | ||
1172 | * Currently we rely on the pipe array holding a power-of-2 number | ||
1173 | * of pages. | ||
1174 | */ | ||
1175 | static inline unsigned int round_pipe_size(unsigned int size) | ||
1176 | { | ||
1177 | unsigned long nr_pages; | ||
1178 | |||
1179 | nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
1180 | return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; | ||
1181 | } | ||
1182 | |||
1183 | /* | ||
1184 | * This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax | ||
1185 | * will return an error. | ||
1186 | */ | ||
1187 | int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, | ||
1188 | size_t *lenp, loff_t *ppos) | ||
1189 | { | ||
1190 | int ret; | ||
1191 | |||
1192 | ret = proc_dointvec_minmax(table, write, buf, lenp, ppos); | ||
1193 | if (ret < 0 || !write) | ||
1194 | return ret; | ||
1195 | |||
1196 | pipe_max_size = round_pipe_size(pipe_max_size); | ||
1197 | return ret; | ||
1163 | } | 1198 | } |
1164 | 1199 | ||
1165 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | 1200 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
@@ -1174,23 +1209,25 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1174 | mutex_lock(&pipe->inode->i_mutex); | 1209 | mutex_lock(&pipe->inode->i_mutex); |
1175 | 1210 | ||
1176 | switch (cmd) { | 1211 | switch (cmd) { |
1177 | case F_SETPIPE_SZ: | 1212 | case F_SETPIPE_SZ: { |
1178 | if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages) { | 1213 | unsigned int size, nr_pages; |
1179 | ret = -EINVAL; | 1214 | |
1215 | size = round_pipe_size(arg); | ||
1216 | nr_pages = size >> PAGE_SHIFT; | ||
1217 | |||
1218 | ret = -EINVAL; | ||
1219 | if (!nr_pages) | ||
1180 | goto out; | 1220 | goto out; |
1181 | } | 1221 | |
1182 | /* | 1222 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { |
1183 | * The pipe needs to be at least 2 pages large to | 1223 | ret = -EPERM; |
1184 | * guarantee POSIX behaviour. | ||
1185 | */ | ||
1186 | if (arg < 2) { | ||
1187 | ret = -EINVAL; | ||
1188 | goto out; | 1224 | goto out; |
1189 | } | 1225 | } |
1190 | ret = pipe_set_size(pipe, arg); | 1226 | ret = pipe_set_size(pipe, nr_pages); |
1191 | break; | 1227 | break; |
1228 | } | ||
1192 | case F_GETPIPE_SZ: | 1229 | case F_GETPIPE_SZ: |
1193 | ret = pipe->buffers; | 1230 | ret = pipe->buffers * PAGE_SIZE; |
1194 | break; | 1231 | break; |
1195 | default: | 1232 | default: |
1196 | ret = -EINVAL; | 1233 | ret = -EINVAL; |
diff --git a/fs/splice.c b/fs/splice.c index ac22b00d86c3..740e6b9faf7a 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -354,7 +354,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
354 | break; | 354 | break; |
355 | 355 | ||
356 | error = add_to_page_cache_lru(page, mapping, index, | 356 | error = add_to_page_cache_lru(page, mapping, index, |
357 | mapping_gfp_mask(mapping)); | 357 | GFP_KERNEL); |
358 | if (unlikely(error)) { | 358 | if (unlikely(error)) { |
359 | page_cache_release(page); | 359 | page_cache_release(page); |
360 | if (error == -EEXIST) | 360 | if (error == -EEXIST) |
@@ -42,7 +42,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) | |||
42 | if (wait) | 42 | if (wait) |
43 | sync_inodes_sb(sb); | 43 | sync_inodes_sb(sb); |
44 | else | 44 | else |
45 | writeback_inodes_sb_locked(sb); | 45 | writeback_inodes_sb(sb); |
46 | 46 | ||
47 | if (sb->s_op->sync_fs) | 47 | if (sb->s_op->sync_fs) |
48 | sb->s_op->sync_fs(sb, wait); | 48 | sb->s_op->sync_fs(sb, wait); |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index bde1a4c3679a..0835a3b70e03 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -117,11 +117,13 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
117 | if (error) | 117 | if (error) |
118 | goto out; | 118 | goto out; |
119 | 119 | ||
120 | error = sysfs_sd_setattr(sd, iattr); | ||
121 | if (error) | ||
122 | goto out; | ||
123 | |||
120 | /* this ignores size changes */ | 124 | /* this ignores size changes */ |
121 | generic_setattr(inode, iattr); | 125 | generic_setattr(inode, iattr); |
122 | 126 | ||
123 | error = sysfs_sd_setattr(sd, iattr); | ||
124 | |||
125 | out: | 127 | out: |
126 | mutex_unlock(&sysfs_mutex); | 128 | mutex_unlock(&sysfs_mutex); |
127 | return error; | 129 | return error; |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 089eaca860b4..34640d6dbdcb 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -1333,6 +1333,21 @@ xfs_vm_writepage( | |||
1333 | trace_xfs_writepage(inode, page, 0); | 1333 | trace_xfs_writepage(inode, page, 0); |
1334 | 1334 | ||
1335 | /* | 1335 | /* |
1336 | * Refuse to write the page out if we are called from reclaim context. | ||
1337 | * | ||
1338 | * This is primarily to avoid stack overflows when called from deep | ||
1339 | * used stacks in random callers for direct reclaim, but disabling | ||
1340 | * reclaim for kswap is a nice side-effect as kswapd causes rather | ||
1341 | * suboptimal I/O patters, too. | ||
1342 | * | ||
1343 | * This should really be done by the core VM, but until that happens | ||
1344 | * filesystems like XFS, btrfs and ext4 have to take care of this | ||
1345 | * by themselves. | ||
1346 | */ | ||
1347 | if (current->flags & PF_MEMALLOC) | ||
1348 | goto out_fail; | ||
1349 | |||
1350 | /* | ||
1336 | * We need a transaction if: | 1351 | * We need a transaction if: |
1337 | * 1. There are delalloc buffers on the page | 1352 | * 1. There are delalloc buffers on the page |
1338 | * 2. The page is uptodate and we have unmapped buffers | 1353 | * 2. The page is uptodate and we have unmapped buffers |
@@ -1366,14 +1381,6 @@ xfs_vm_writepage( | |||
1366 | if (!page_has_buffers(page)) | 1381 | if (!page_has_buffers(page)) |
1367 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); | 1382 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); |
1368 | 1383 | ||
1369 | |||
1370 | /* | ||
1371 | * VM calculation for nr_to_write seems off. Bump it way | ||
1372 | * up, this gets simple streaming writes zippy again. | ||
1373 | * To be reviewed again after Jens' writeback changes. | ||
1374 | */ | ||
1375 | wbc->nr_to_write *= 4; | ||
1376 | |||
1377 | /* | 1384 | /* |
1378 | * Convert delayed allocate, unwritten or unmapped space | 1385 | * Convert delayed allocate, unwritten or unmapped space |
1379 | * to real space and flush out to disk. | 1386 | * to real space and flush out to disk. |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 9c8019c78c92..44f0b2de153e 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -585,11 +585,20 @@ xfs_vn_fallocate( | |||
585 | bf.l_len = len; | 585 | bf.l_len = len; |
586 | 586 | ||
587 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 587 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
588 | |||
589 | /* check the new inode size is valid before allocating */ | ||
590 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
591 | offset + len > i_size_read(inode)) { | ||
592 | new_size = offset + len; | ||
593 | error = inode_newsize_ok(inode, new_size); | ||
594 | if (error) | ||
595 | goto out_unlock; | ||
596 | } | ||
597 | |||
588 | error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, | 598 | error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, |
589 | 0, XFS_ATTR_NOLOCK); | 599 | 0, XFS_ATTR_NOLOCK); |
590 | if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && | 600 | if (error) |
591 | offset + len > i_size_read(inode)) | 601 | goto out_unlock; |
592 | new_size = offset + len; | ||
593 | 602 | ||
594 | /* Change file size if needed */ | 603 | /* Change file size if needed */ |
595 | if (new_size) { | 604 | if (new_size) { |
@@ -600,6 +609,7 @@ xfs_vn_fallocate( | |||
600 | error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); | 609 | error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); |
601 | } | 610 | } |
602 | 611 | ||
612 | out_unlock: | ||
603 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 613 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
604 | out_error: | 614 | out_error: |
605 | return error; | 615 | return error; |
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c index 9ac8aea91529..067cafbfc635 100644 --- a/fs/xfs/linux-2.6/xfs_quotaops.c +++ b/fs/xfs/linux-2.6/xfs_quotaops.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
24 | #include "xfs_mount.h" | 24 | #include "xfs_mount.h" |
25 | #include "xfs_quota.h" | 25 | #include "xfs_quota.h" |
26 | #include "xfs_log.h" | ||
27 | #include "xfs_trans.h" | 26 | #include "xfs_trans.h" |
28 | #include "xfs_bmap_btree.h" | 27 | #include "xfs_bmap_btree.h" |
29 | #include "xfs_inode.h" | 28 | #include "xfs_inode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 3884e20bc14e..ef7f0218bccb 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -164,10 +164,6 @@ xfs_inode_ag_iterator( | |||
164 | struct xfs_perag *pag; | 164 | struct xfs_perag *pag; |
165 | 165 | ||
166 | pag = xfs_perag_get(mp, ag); | 166 | pag = xfs_perag_get(mp, ag); |
167 | if (!pag->pag_ici_init) { | ||
168 | xfs_perag_put(pag); | ||
169 | continue; | ||
170 | } | ||
171 | error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, | 167 | error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, |
172 | exclusive, &nr); | 168 | exclusive, &nr); |
173 | xfs_perag_put(pag); | 169 | xfs_perag_put(pag); |
@@ -867,12 +863,7 @@ xfs_reclaim_inode_shrink( | |||
867 | down_read(&xfs_mount_list_lock); | 863 | down_read(&xfs_mount_list_lock); |
868 | list_for_each_entry(mp, &xfs_mount_list, m_mplist) { | 864 | list_for_each_entry(mp, &xfs_mount_list, m_mplist) { |
869 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { | 865 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { |
870 | |||
871 | pag = xfs_perag_get(mp, ag); | 866 | pag = xfs_perag_get(mp, ag); |
872 | if (!pag->pag_ici_init) { | ||
873 | xfs_perag_put(pag); | ||
874 | continue; | ||
875 | } | ||
876 | reclaimable += pag->pag_ici_reclaimable; | 867 | reclaimable += pag->pag_ici_reclaimable; |
877 | xfs_perag_put(pag); | 868 | xfs_perag_put(pag); |
878 | } | 869 | } |
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c index 207fa77f63ae..d12be8470cba 100644 --- a/fs/xfs/linux-2.6/xfs_trace.c +++ b/fs/xfs/linux-2.6/xfs_trace.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include "quota/xfs_dquot_item.h" | 50 | #include "quota/xfs_dquot_item.h" |
51 | #include "quota/xfs_dquot.h" | 51 | #include "quota/xfs_dquot.h" |
52 | #include "xfs_log_recover.h" | 52 | #include "xfs_log_recover.h" |
53 | #include "xfs_buf_item.h" | ||
54 | #include "xfs_inode_item.h" | 53 | #include "xfs_inode_item.h" |
55 | 54 | ||
56 | /* | 55 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index ff6bc797baf2..73d5aa117384 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h | |||
@@ -82,33 +82,6 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class, | |||
82 | ) | 82 | ) |
83 | ) | 83 | ) |
84 | 84 | ||
85 | #define DEFINE_PERAG_REF_EVENT(name) \ | ||
86 | TRACE_EVENT(name, \ | ||
87 | TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ | ||
88 | unsigned long caller_ip), \ | ||
89 | TP_ARGS(mp, agno, refcount, caller_ip), \ | ||
90 | TP_STRUCT__entry( \ | ||
91 | __field(dev_t, dev) \ | ||
92 | __field(xfs_agnumber_t, agno) \ | ||
93 | __field(int, refcount) \ | ||
94 | __field(unsigned long, caller_ip) \ | ||
95 | ), \ | ||
96 | TP_fast_assign( \ | ||
97 | __entry->dev = mp->m_super->s_dev; \ | ||
98 | __entry->agno = agno; \ | ||
99 | __entry->refcount = refcount; \ | ||
100 | __entry->caller_ip = caller_ip; \ | ||
101 | ), \ | ||
102 | TP_printk("dev %d:%d agno %u refcount %d caller %pf", \ | ||
103 | MAJOR(__entry->dev), MINOR(__entry->dev), \ | ||
104 | __entry->agno, \ | ||
105 | __entry->refcount, \ | ||
106 | (char *)__entry->caller_ip) \ | ||
107 | ); | ||
108 | |||
109 | DEFINE_PERAG_REF_EVENT(xfs_perag_get) | ||
110 | DEFINE_PERAG_REF_EVENT(xfs_perag_put) | ||
111 | |||
112 | #define DEFINE_ATTR_LIST_EVENT(name) \ | 85 | #define DEFINE_ATTR_LIST_EVENT(name) \ |
113 | DEFINE_EVENT(xfs_attr_list_class, name, \ | 86 | DEFINE_EVENT(xfs_attr_list_class, name, \ |
114 | TP_PROTO(struct xfs_attr_list_context *ctx), \ | 87 | TP_PROTO(struct xfs_attr_list_context *ctx), \ |
@@ -122,6 +95,37 @@ DEFINE_ATTR_LIST_EVENT(xfs_attr_list_add); | |||
122 | DEFINE_ATTR_LIST_EVENT(xfs_attr_list_wrong_blk); | 95 | DEFINE_ATTR_LIST_EVENT(xfs_attr_list_wrong_blk); |
123 | DEFINE_ATTR_LIST_EVENT(xfs_attr_list_notfound); | 96 | DEFINE_ATTR_LIST_EVENT(xfs_attr_list_notfound); |
124 | 97 | ||
98 | DECLARE_EVENT_CLASS(xfs_perag_class, | ||
99 | TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, | ||
100 | unsigned long caller_ip), | ||
101 | TP_ARGS(mp, agno, refcount, caller_ip), | ||
102 | TP_STRUCT__entry( | ||
103 | __field(dev_t, dev) | ||
104 | __field(xfs_agnumber_t, agno) | ||
105 | __field(int, refcount) | ||
106 | __field(unsigned long, caller_ip) | ||
107 | ), | ||
108 | TP_fast_assign( | ||
109 | __entry->dev = mp->m_super->s_dev; | ||
110 | __entry->agno = agno; | ||
111 | __entry->refcount = refcount; | ||
112 | __entry->caller_ip = caller_ip; | ||
113 | ), | ||
114 | TP_printk("dev %d:%d agno %u refcount %d caller %pf", | ||
115 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
116 | __entry->agno, | ||
117 | __entry->refcount, | ||
118 | (char *)__entry->caller_ip) | ||
119 | ); | ||
120 | |||
121 | #define DEFINE_PERAG_REF_EVENT(name) \ | ||
122 | DEFINE_EVENT(xfs_perag_class, name, \ | ||
123 | TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ | ||
124 | unsigned long caller_ip), \ | ||
125 | TP_ARGS(mp, agno, refcount, caller_ip)) | ||
126 | DEFINE_PERAG_REF_EVENT(xfs_perag_get); | ||
127 | DEFINE_PERAG_REF_EVENT(xfs_perag_put); | ||
128 | |||
125 | TRACE_EVENT(xfs_attr_list_node_descend, | 129 | TRACE_EVENT(xfs_attr_list_node_descend, |
126 | TP_PROTO(struct xfs_attr_list_context *ctx, | 130 | TP_PROTO(struct xfs_attr_list_context *ctx, |
127 | struct xfs_da_node_entry *btree), | 131 | struct xfs_da_node_entry *btree), |
@@ -775,165 +779,181 @@ DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_enter); | |||
775 | DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_exit); | 779 | DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_exit); |
776 | DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_sub); | 780 | DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_sub); |
777 | 781 | ||
778 | #define DEFINE_RW_EVENT(name) \ | 782 | DECLARE_EVENT_CLASS(xfs_file_class, |
779 | TRACE_EVENT(name, \ | 783 | TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), |
780 | TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \ | 784 | TP_ARGS(ip, count, offset, flags), |
781 | TP_ARGS(ip, count, offset, flags), \ | 785 | TP_STRUCT__entry( |
782 | TP_STRUCT__entry( \ | 786 | __field(dev_t, dev) |
783 | __field(dev_t, dev) \ | 787 | __field(xfs_ino_t, ino) |
784 | __field(xfs_ino_t, ino) \ | 788 | __field(xfs_fsize_t, size) |
785 | __field(xfs_fsize_t, size) \ | 789 | __field(xfs_fsize_t, new_size) |
786 | __field(xfs_fsize_t, new_size) \ | 790 | __field(loff_t, offset) |
787 | __field(loff_t, offset) \ | 791 | __field(size_t, count) |
788 | __field(size_t, count) \ | 792 | __field(int, flags) |
789 | __field(int, flags) \ | 793 | ), |
790 | ), \ | 794 | TP_fast_assign( |
791 | TP_fast_assign( \ | 795 | __entry->dev = VFS_I(ip)->i_sb->s_dev; |
792 | __entry->dev = VFS_I(ip)->i_sb->s_dev; \ | 796 | __entry->ino = ip->i_ino; |
793 | __entry->ino = ip->i_ino; \ | 797 | __entry->size = ip->i_d.di_size; |
794 | __entry->size = ip->i_d.di_size; \ | 798 | __entry->new_size = ip->i_new_size; |
795 | __entry->new_size = ip->i_new_size; \ | 799 | __entry->offset = offset; |
796 | __entry->offset = offset; \ | 800 | __entry->count = count; |
797 | __entry->count = count; \ | 801 | __entry->flags = flags; |
798 | __entry->flags = flags; \ | 802 | ), |
799 | ), \ | 803 | TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " |
800 | TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ | 804 | "offset 0x%llx count 0x%zx ioflags %s", |
801 | "offset 0x%llx count 0x%zx ioflags %s", \ | 805 | MAJOR(__entry->dev), MINOR(__entry->dev), |
802 | MAJOR(__entry->dev), MINOR(__entry->dev), \ | 806 | __entry->ino, |
803 | __entry->ino, \ | 807 | __entry->size, |
804 | __entry->size, \ | 808 | __entry->new_size, |
805 | __entry->new_size, \ | 809 | __entry->offset, |
806 | __entry->offset, \ | 810 | __entry->count, |
807 | __entry->count, \ | 811 | __print_flags(__entry->flags, "|", XFS_IO_FLAGS)) |
808 | __print_flags(__entry->flags, "|", XFS_IO_FLAGS)) \ | ||
809 | ) | 812 | ) |
813 | |||
814 | #define DEFINE_RW_EVENT(name) \ | ||
815 | DEFINE_EVENT(xfs_file_class, name, \ | ||
816 | TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \ | ||
817 | TP_ARGS(ip, count, offset, flags)) | ||
810 | DEFINE_RW_EVENT(xfs_file_read); | 818 | DEFINE_RW_EVENT(xfs_file_read); |
811 | DEFINE_RW_EVENT(xfs_file_buffered_write); | 819 | DEFINE_RW_EVENT(xfs_file_buffered_write); |
812 | DEFINE_RW_EVENT(xfs_file_direct_write); | 820 | DEFINE_RW_EVENT(xfs_file_direct_write); |
813 | DEFINE_RW_EVENT(xfs_file_splice_read); | 821 | DEFINE_RW_EVENT(xfs_file_splice_read); |
814 | DEFINE_RW_EVENT(xfs_file_splice_write); | 822 | DEFINE_RW_EVENT(xfs_file_splice_write); |
815 | 823 | ||
816 | 824 | DECLARE_EVENT_CLASS(xfs_page_class, | |
817 | #define DEFINE_PAGE_EVENT(name) \ | 825 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off), |
818 | TRACE_EVENT(name, \ | 826 | TP_ARGS(inode, page, off), |
819 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \ | 827 | TP_STRUCT__entry( |
820 | TP_ARGS(inode, page, off), \ | 828 | __field(dev_t, dev) |
821 | TP_STRUCT__entry( \ | 829 | __field(xfs_ino_t, ino) |
822 | __field(dev_t, dev) \ | 830 | __field(pgoff_t, pgoff) |
823 | __field(xfs_ino_t, ino) \ | 831 | __field(loff_t, size) |
824 | __field(pgoff_t, pgoff) \ | 832 | __field(unsigned long, offset) |
825 | __field(loff_t, size) \ | 833 | __field(int, delalloc) |
826 | __field(unsigned long, offset) \ | 834 | __field(int, unmapped) |
827 | __field(int, delalloc) \ | 835 | __field(int, unwritten) |
828 | __field(int, unmapped) \ | 836 | ), |
829 | __field(int, unwritten) \ | 837 | TP_fast_assign( |
830 | ), \ | 838 | int delalloc = -1, unmapped = -1, unwritten = -1; |
831 | TP_fast_assign( \ | 839 | |
832 | int delalloc = -1, unmapped = -1, unwritten = -1; \ | 840 | if (page_has_buffers(page)) |
833 | \ | 841 | xfs_count_page_state(page, &delalloc, |
834 | if (page_has_buffers(page)) \ | 842 | &unmapped, &unwritten); |
835 | xfs_count_page_state(page, &delalloc, \ | 843 | __entry->dev = inode->i_sb->s_dev; |
836 | &unmapped, &unwritten); \ | 844 | __entry->ino = XFS_I(inode)->i_ino; |
837 | __entry->dev = inode->i_sb->s_dev; \ | 845 | __entry->pgoff = page_offset(page); |
838 | __entry->ino = XFS_I(inode)->i_ino; \ | 846 | __entry->size = i_size_read(inode); |
839 | __entry->pgoff = page_offset(page); \ | 847 | __entry->offset = off; |
840 | __entry->size = i_size_read(inode); \ | 848 | __entry->delalloc = delalloc; |
841 | __entry->offset = off; \ | 849 | __entry->unmapped = unmapped; |
842 | __entry->delalloc = delalloc; \ | 850 | __entry->unwritten = unwritten; |
843 | __entry->unmapped = unmapped; \ | 851 | ), |
844 | __entry->unwritten = unwritten; \ | 852 | TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " |
845 | ), \ | 853 | "delalloc %d unmapped %d unwritten %d", |
846 | TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " \ | 854 | MAJOR(__entry->dev), MINOR(__entry->dev), |
847 | "delalloc %d unmapped %d unwritten %d", \ | 855 | __entry->ino, |
848 | MAJOR(__entry->dev), MINOR(__entry->dev), \ | 856 | __entry->pgoff, |
849 | __entry->ino, \ | 857 | __entry->size, |
850 | __entry->pgoff, \ | 858 | __entry->offset, |
851 | __entry->size, \ | 859 | __entry->delalloc, |
852 | __entry->offset, \ | 860 | __entry->unmapped, |
853 | __entry->delalloc, \ | 861 | __entry->unwritten) |
854 | __entry->unmapped, \ | ||
855 | __entry->unwritten) \ | ||
856 | ) | 862 | ) |
863 | |||
864 | #define DEFINE_PAGE_EVENT(name) \ | ||
865 | DEFINE_EVENT(xfs_page_class, name, \ | ||
866 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \ | ||
867 | TP_ARGS(inode, page, off)) | ||
857 | DEFINE_PAGE_EVENT(xfs_writepage); | 868 | DEFINE_PAGE_EVENT(xfs_writepage); |
858 | DEFINE_PAGE_EVENT(xfs_releasepage); | 869 | DEFINE_PAGE_EVENT(xfs_releasepage); |
859 | DEFINE_PAGE_EVENT(xfs_invalidatepage); | 870 | DEFINE_PAGE_EVENT(xfs_invalidatepage); |
860 | 871 | ||
861 | #define DEFINE_IOMAP_EVENT(name) \ | 872 | DECLARE_EVENT_CLASS(xfs_iomap_class, |
862 | TRACE_EVENT(name, \ | 873 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, |
863 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ | 874 | int flags, struct xfs_bmbt_irec *irec), |
864 | int flags, struct xfs_bmbt_irec *irec), \ | 875 | TP_ARGS(ip, offset, count, flags, irec), |
865 | TP_ARGS(ip, offset, count, flags, irec), \ | 876 | TP_STRUCT__entry( |
866 | TP_STRUCT__entry( \ | 877 | __field(dev_t, dev) |
867 | __field(dev_t, dev) \ | 878 | __field(xfs_ino_t, ino) |
868 | __field(xfs_ino_t, ino) \ | 879 | __field(loff_t, size) |
869 | __field(loff_t, size) \ | 880 | __field(loff_t, new_size) |
870 | __field(loff_t, new_size) \ | 881 | __field(loff_t, offset) |
871 | __field(loff_t, offset) \ | 882 | __field(size_t, count) |
872 | __field(size_t, count) \ | 883 | __field(int, flags) |
873 | __field(int, flags) \ | 884 | __field(xfs_fileoff_t, startoff) |
874 | __field(xfs_fileoff_t, startoff) \ | 885 | __field(xfs_fsblock_t, startblock) |
875 | __field(xfs_fsblock_t, startblock) \ | 886 | __field(xfs_filblks_t, blockcount) |
876 | __field(xfs_filblks_t, blockcount) \ | 887 | ), |
877 | ), \ | 888 | TP_fast_assign( |
878 | TP_fast_assign( \ | 889 | __entry->dev = VFS_I(ip)->i_sb->s_dev; |
879 | __entry->dev = VFS_I(ip)->i_sb->s_dev; \ | 890 | __entry->ino = ip->i_ino; |
880 | __entry->ino = ip->i_ino; \ | 891 | __entry->size = ip->i_d.di_size; |
881 | __entry->size = ip->i_d.di_size; \ | 892 | __entry->new_size = ip->i_new_size; |
882 | __entry->new_size = ip->i_new_size; \ | 893 | __entry->offset = offset; |
883 | __entry->offset = offset; \ | 894 | __entry->count = count; |
884 | __entry->count = count; \ | 895 | __entry->flags = flags; |
885 | __entry->flags = flags; \ | 896 | __entry->startoff = irec ? irec->br_startoff : 0; |
886 | __entry->startoff = irec ? irec->br_startoff : 0; \ | 897 | __entry->startblock = irec ? irec->br_startblock : 0; |
887 | __entry->startblock = irec ? irec->br_startblock : 0; \ | 898 | __entry->blockcount = irec ? irec->br_blockcount : 0; |
888 | __entry->blockcount = irec ? irec->br_blockcount : 0; \ | 899 | ), |
889 | ), \ | 900 | TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " |
890 | TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ | 901 | "offset 0x%llx count %zd flags %s " |
891 | "offset 0x%llx count %zd flags %s " \ | 902 | "startoff 0x%llx startblock %lld blockcount 0x%llx", |
892 | "startoff 0x%llx startblock %lld blockcount 0x%llx", \ | 903 | MAJOR(__entry->dev), MINOR(__entry->dev), |
893 | MAJOR(__entry->dev), MINOR(__entry->dev), \ | 904 | __entry->ino, |
894 | __entry->ino, \ | 905 | __entry->size, |
895 | __entry->size, \ | 906 | __entry->new_size, |
896 | __entry->new_size, \ | 907 | __entry->offset, |
897 | __entry->offset, \ | 908 | __entry->count, |
898 | __entry->count, \ | 909 | __print_flags(__entry->flags, "|", BMAPI_FLAGS), |
899 | __print_flags(__entry->flags, "|", BMAPI_FLAGS), \ | 910 | __entry->startoff, |
900 | __entry->startoff, \ | 911 | (__int64_t)__entry->startblock, |
901 | (__int64_t)__entry->startblock, \ | 912 | __entry->blockcount) |
902 | __entry->blockcount) \ | ||
903 | ) | 913 | ) |
914 | |||
915 | #define DEFINE_IOMAP_EVENT(name) \ | ||
916 | DEFINE_EVENT(xfs_iomap_class, name, \ | ||
917 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ | ||
918 | int flags, struct xfs_bmbt_irec *irec), \ | ||
919 | TP_ARGS(ip, offset, count, flags, irec)) | ||
904 | DEFINE_IOMAP_EVENT(xfs_iomap_enter); | 920 | DEFINE_IOMAP_EVENT(xfs_iomap_enter); |
905 | DEFINE_IOMAP_EVENT(xfs_iomap_found); | 921 | DEFINE_IOMAP_EVENT(xfs_iomap_found); |
906 | DEFINE_IOMAP_EVENT(xfs_iomap_alloc); | 922 | DEFINE_IOMAP_EVENT(xfs_iomap_alloc); |
907 | 923 | ||
908 | #define DEFINE_SIMPLE_IO_EVENT(name) \ | 924 | DECLARE_EVENT_CLASS(xfs_simple_io_class, |
909 | TRACE_EVENT(name, \ | 925 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), |
910 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \ | 926 | TP_ARGS(ip, offset, count), |
911 | TP_ARGS(ip, offset, count), \ | 927 | TP_STRUCT__entry( |
912 | TP_STRUCT__entry( \ | 928 | __field(dev_t, dev) |
913 | __field(dev_t, dev) \ | 929 | __field(xfs_ino_t, ino) |
914 | __field(xfs_ino_t, ino) \ | 930 | __field(loff_t, size) |
915 | __field(loff_t, size) \ | 931 | __field(loff_t, new_size) |
916 | __field(loff_t, new_size) \ | 932 | __field(loff_t, offset) |
917 | __field(loff_t, offset) \ | 933 | __field(size_t, count) |
918 | __field(size_t, count) \ | 934 | ), |
919 | ), \ | 935 | TP_fast_assign( |
920 | TP_fast_assign( \ | 936 | __entry->dev = VFS_I(ip)->i_sb->s_dev; |
921 | __entry->dev = VFS_I(ip)->i_sb->s_dev; \ | 937 | __entry->ino = ip->i_ino; |
922 | __entry->ino = ip->i_ino; \ | 938 | __entry->size = ip->i_d.di_size; |
923 | __entry->size = ip->i_d.di_size; \ | 939 | __entry->new_size = ip->i_new_size; |
924 | __entry->new_size = ip->i_new_size; \ | 940 | __entry->offset = offset; |
925 | __entry->offset = offset; \ | 941 | __entry->count = count; |
926 | __entry->count = count; \ | 942 | ), |
927 | ), \ | 943 | TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " |
928 | TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ | 944 | "offset 0x%llx count %zd", |
929 | "offset 0x%llx count %zd", \ | 945 | MAJOR(__entry->dev), MINOR(__entry->dev), |
930 | MAJOR(__entry->dev), MINOR(__entry->dev), \ | 946 | __entry->ino, |
931 | __entry->ino, \ | 947 | __entry->size, |
932 | __entry->size, \ | 948 | __entry->new_size, |
933 | __entry->new_size, \ | 949 | __entry->offset, |
934 | __entry->offset, \ | 950 | __entry->count) |
935 | __entry->count) \ | ||
936 | ); | 951 | ); |
952 | |||
953 | #define DEFINE_SIMPLE_IO_EVENT(name) \ | ||
954 | DEFINE_EVENT(xfs_simple_io_class, name, \ | ||
955 | TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \ | ||
956 | TP_ARGS(ip, offset, count)) | ||
937 | DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); | 957 | DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); |
938 | DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); | 958 | DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); |
939 | 959 | ||
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 38e764146644..2d8b7bc792c9 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -249,8 +249,10 @@ xfs_qm_hold_quotafs_ref( | |||
249 | 249 | ||
250 | if (!xfs_Gqm) { | 250 | if (!xfs_Gqm) { |
251 | xfs_Gqm = xfs_Gqm_init(); | 251 | xfs_Gqm = xfs_Gqm_init(); |
252 | if (!xfs_Gqm) | 252 | if (!xfs_Gqm) { |
253 | mutex_unlock(&xfs_Gqm_lock); | ||
253 | return ENOMEM; | 254 | return ENOMEM; |
255 | } | ||
254 | } | 256 | } |
255 | 257 | ||
256 | /* | 258 | /* |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index 401f364ad36c..4917d4eed4ed 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -227,7 +227,6 @@ typedef struct xfs_perag { | |||
227 | 227 | ||
228 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ | 228 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ |
229 | 229 | ||
230 | int pag_ici_init; /* incore inode cache initialised */ | ||
231 | rwlock_t pag_ici_lock; /* incore inode lock */ | 230 | rwlock_t pag_ici_lock; /* incore inode lock */ |
232 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ | 231 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ |
233 | int pag_ici_reclaimable; /* reclaimable inodes */ | 232 | int pag_ici_reclaimable; /* reclaimable inodes */ |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 6845db90818f..75df75f43d48 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -382,9 +382,6 @@ xfs_iget( | |||
382 | 382 | ||
383 | /* get the perag structure and ensure that it's inode capable */ | 383 | /* get the perag structure and ensure that it's inode capable */ |
384 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); | 384 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); |
385 | if (!pag->pagi_inodeok) | ||
386 | return EINVAL; | ||
387 | ASSERT(pag->pag_ici_init); | ||
388 | agino = XFS_INO_TO_AGINO(mp, ino); | 385 | agino = XFS_INO_TO_AGINO(mp, ino); |
389 | 386 | ||
390 | again: | 387 | again: |
@@ -744,30 +741,24 @@ xfs_ilock_demote( | |||
744 | } | 741 | } |
745 | 742 | ||
746 | #ifdef DEBUG | 743 | #ifdef DEBUG |
747 | /* | ||
748 | * Debug-only routine, without additional rw_semaphore APIs, we can | ||
749 | * now only answer requests regarding whether we hold the lock for write | ||
750 | * (reader state is outside our visibility, we only track writer state). | ||
751 | * | ||
752 | * Note: this means !xfs_isilocked would give false positives, so don't do that. | ||
753 | */ | ||
754 | int | 744 | int |
755 | xfs_isilocked( | 745 | xfs_isilocked( |
756 | xfs_inode_t *ip, | 746 | xfs_inode_t *ip, |
757 | uint lock_flags) | 747 | uint lock_flags) |
758 | { | 748 | { |
759 | if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) == | 749 | if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) { |
760 | XFS_ILOCK_EXCL) { | 750 | if (!(lock_flags & XFS_ILOCK_SHARED)) |
761 | if (!ip->i_lock.mr_writer) | 751 | return !!ip->i_lock.mr_writer; |
762 | return 0; | 752 | return rwsem_is_locked(&ip->i_lock.mr_lock); |
763 | } | 753 | } |
764 | 754 | ||
765 | if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) == | 755 | if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) { |
766 | XFS_IOLOCK_EXCL) { | 756 | if (!(lock_flags & XFS_IOLOCK_SHARED)) |
767 | if (!ip->i_iolock.mr_writer) | 757 | return !!ip->i_iolock.mr_writer; |
768 | return 0; | 758 | return rwsem_is_locked(&ip->i_iolock.mr_lock); |
769 | } | 759 | } |
770 | 760 | ||
771 | return 1; | 761 | ASSERT(0); |
762 | return 0; | ||
772 | } | 763 | } |
773 | #endif | 764 | #endif |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8cd6e8d8fe9c..d53c39de7d05 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1940,10 +1940,10 @@ xfs_ifree_cluster( | |||
1940 | int blks_per_cluster; | 1940 | int blks_per_cluster; |
1941 | int nbufs; | 1941 | int nbufs; |
1942 | int ninodes; | 1942 | int ninodes; |
1943 | int i, j, found, pre_flushed; | 1943 | int i, j; |
1944 | xfs_daddr_t blkno; | 1944 | xfs_daddr_t blkno; |
1945 | xfs_buf_t *bp; | 1945 | xfs_buf_t *bp; |
1946 | xfs_inode_t *ip, **ip_found; | 1946 | xfs_inode_t *ip; |
1947 | xfs_inode_log_item_t *iip; | 1947 | xfs_inode_log_item_t *iip; |
1948 | xfs_log_item_t *lip; | 1948 | xfs_log_item_t *lip; |
1949 | struct xfs_perag *pag; | 1949 | struct xfs_perag *pag; |
@@ -1960,114 +1960,97 @@ xfs_ifree_cluster( | |||
1960 | nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; | 1960 | nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; |
1961 | } | 1961 | } |
1962 | 1962 | ||
1963 | ip_found = kmem_alloc(ninodes * sizeof(xfs_inode_t *), KM_NOFS); | ||
1964 | |||
1965 | for (j = 0; j < nbufs; j++, inum += ninodes) { | 1963 | for (j = 0; j < nbufs; j++, inum += ninodes) { |
1964 | int found = 0; | ||
1965 | |||
1966 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), | 1966 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), |
1967 | XFS_INO_TO_AGBNO(mp, inum)); | 1967 | XFS_INO_TO_AGBNO(mp, inum)); |
1968 | 1968 | ||
1969 | /* | ||
1970 | * We obtain and lock the backing buffer first in the process | ||
1971 | * here, as we have to ensure that any dirty inode that we | ||
1972 | * can't get the flush lock on is attached to the buffer. | ||
1973 | * If we scan the in-memory inodes first, then buffer IO can | ||
1974 | * complete before we get a lock on it, and hence we may fail | ||
1975 | * to mark all the active inodes on the buffer stale. | ||
1976 | */ | ||
1977 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, | ||
1978 | mp->m_bsize * blks_per_cluster, | ||
1979 | XBF_LOCK); | ||
1980 | |||
1981 | /* | ||
1982 | * Walk the inodes already attached to the buffer and mark them | ||
1983 | * stale. These will all have the flush locks held, so an | ||
1984 | * in-memory inode walk can't lock them. | ||
1985 | */ | ||
1986 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); | ||
1987 | while (lip) { | ||
1988 | if (lip->li_type == XFS_LI_INODE) { | ||
1989 | iip = (xfs_inode_log_item_t *)lip; | ||
1990 | ASSERT(iip->ili_logged == 1); | ||
1991 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; | ||
1992 | xfs_trans_ail_copy_lsn(mp->m_ail, | ||
1993 | &iip->ili_flush_lsn, | ||
1994 | &iip->ili_item.li_lsn); | ||
1995 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | ||
1996 | found++; | ||
1997 | } | ||
1998 | lip = lip->li_bio_list; | ||
1999 | } | ||
1969 | 2000 | ||
1970 | /* | 2001 | /* |
1971 | * Look for each inode in memory and attempt to lock it, | 2002 | * For each inode in memory attempt to add it to the inode |
1972 | * we can be racing with flush and tail pushing here. | 2003 | * buffer and set it up for being staled on buffer IO |
1973 | * any inode we get the locks on, add to an array of | 2004 | * completion. This is safe as we've locked out tail pushing |
1974 | * inode items to process later. | 2005 | * and flushing by locking the buffer. |
1975 | * | 2006 | * |
1976 | * The get the buffer lock, we could beat a flush | 2007 | * We have already marked every inode that was part of a |
1977 | * or tail pushing thread to the lock here, in which | 2008 | * transaction stale above, which means there is no point in |
1978 | * case they will go looking for the inode buffer | 2009 | * even trying to lock them. |
1979 | * and fail, we need some other form of interlock | ||
1980 | * here. | ||
1981 | */ | 2010 | */ |
1982 | found = 0; | ||
1983 | for (i = 0; i < ninodes; i++) { | 2011 | for (i = 0; i < ninodes; i++) { |
1984 | read_lock(&pag->pag_ici_lock); | 2012 | read_lock(&pag->pag_ici_lock); |
1985 | ip = radix_tree_lookup(&pag->pag_ici_root, | 2013 | ip = radix_tree_lookup(&pag->pag_ici_root, |
1986 | XFS_INO_TO_AGINO(mp, (inum + i))); | 2014 | XFS_INO_TO_AGINO(mp, (inum + i))); |
1987 | 2015 | ||
1988 | /* Inode not in memory or we found it already, | 2016 | /* Inode not in memory or stale, nothing to do */ |
1989 | * nothing to do | ||
1990 | */ | ||
1991 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { | 2017 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { |
1992 | read_unlock(&pag->pag_ici_lock); | 2018 | read_unlock(&pag->pag_ici_lock); |
1993 | continue; | 2019 | continue; |
1994 | } | 2020 | } |
1995 | 2021 | ||
1996 | if (xfs_inode_clean(ip)) { | 2022 | /* don't try to lock/unlock the current inode */ |
1997 | read_unlock(&pag->pag_ici_lock); | 2023 | if (ip != free_ip && |
1998 | continue; | 2024 | !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
1999 | } | ||
2000 | |||
2001 | /* If we can get the locks then add it to the | ||
2002 | * list, otherwise by the time we get the bp lock | ||
2003 | * below it will already be attached to the | ||
2004 | * inode buffer. | ||
2005 | */ | ||
2006 | |||
2007 | /* This inode will already be locked - by us, lets | ||
2008 | * keep it that way. | ||
2009 | */ | ||
2010 | |||
2011 | if (ip == free_ip) { | ||
2012 | if (xfs_iflock_nowait(ip)) { | ||
2013 | xfs_iflags_set(ip, XFS_ISTALE); | ||
2014 | if (xfs_inode_clean(ip)) { | ||
2015 | xfs_ifunlock(ip); | ||
2016 | } else { | ||
2017 | ip_found[found++] = ip; | ||
2018 | } | ||
2019 | } | ||
2020 | read_unlock(&pag->pag_ici_lock); | 2025 | read_unlock(&pag->pag_ici_lock); |
2021 | continue; | 2026 | continue; |
2022 | } | 2027 | } |
2028 | read_unlock(&pag->pag_ici_lock); | ||
2023 | 2029 | ||
2024 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2030 | if (!xfs_iflock_nowait(ip)) { |
2025 | if (xfs_iflock_nowait(ip)) { | 2031 | if (ip != free_ip) |
2026 | xfs_iflags_set(ip, XFS_ISTALE); | ||
2027 | |||
2028 | if (xfs_inode_clean(ip)) { | ||
2029 | xfs_ifunlock(ip); | ||
2030 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2031 | } else { | ||
2032 | ip_found[found++] = ip; | ||
2033 | } | ||
2034 | } else { | ||
2035 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2032 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2036 | } | 2033 | continue; |
2037 | } | 2034 | } |
2038 | read_unlock(&pag->pag_ici_lock); | ||
2039 | } | ||
2040 | 2035 | ||
2041 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, | 2036 | xfs_iflags_set(ip, XFS_ISTALE); |
2042 | mp->m_bsize * blks_per_cluster, | 2037 | if (xfs_inode_clean(ip)) { |
2043 | XBF_LOCK); | 2038 | ASSERT(ip != free_ip); |
2044 | 2039 | xfs_ifunlock(ip); | |
2045 | pre_flushed = 0; | 2040 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2046 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); | 2041 | continue; |
2047 | while (lip) { | ||
2048 | if (lip->li_type == XFS_LI_INODE) { | ||
2049 | iip = (xfs_inode_log_item_t *)lip; | ||
2050 | ASSERT(iip->ili_logged == 1); | ||
2051 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; | ||
2052 | xfs_trans_ail_copy_lsn(mp->m_ail, | ||
2053 | &iip->ili_flush_lsn, | ||
2054 | &iip->ili_item.li_lsn); | ||
2055 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | ||
2056 | pre_flushed++; | ||
2057 | } | 2042 | } |
2058 | lip = lip->li_bio_list; | ||
2059 | } | ||
2060 | 2043 | ||
2061 | for (i = 0; i < found; i++) { | ||
2062 | ip = ip_found[i]; | ||
2063 | iip = ip->i_itemp; | 2044 | iip = ip->i_itemp; |
2064 | |||
2065 | if (!iip) { | 2045 | if (!iip) { |
2046 | /* inode with unlogged changes only */ | ||
2047 | ASSERT(ip != free_ip); | ||
2066 | ip->i_update_core = 0; | 2048 | ip->i_update_core = 0; |
2067 | xfs_ifunlock(ip); | 2049 | xfs_ifunlock(ip); |
2068 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2050 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2069 | continue; | 2051 | continue; |
2070 | } | 2052 | } |
2053 | found++; | ||
2071 | 2054 | ||
2072 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2055 | iip->ili_last_fields = iip->ili_format.ilf_fields; |
2073 | iip->ili_format.ilf_fields = 0; | 2056 | iip->ili_format.ilf_fields = 0; |
@@ -2078,17 +2061,16 @@ xfs_ifree_cluster( | |||
2078 | xfs_buf_attach_iodone(bp, | 2061 | xfs_buf_attach_iodone(bp, |
2079 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) | 2062 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) |
2080 | xfs_istale_done, (xfs_log_item_t *)iip); | 2063 | xfs_istale_done, (xfs_log_item_t *)iip); |
2081 | if (ip != free_ip) { | 2064 | |
2065 | if (ip != free_ip) | ||
2082 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2066 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2083 | } | ||
2084 | } | 2067 | } |
2085 | 2068 | ||
2086 | if (found || pre_flushed) | 2069 | if (found) |
2087 | xfs_trans_stale_inode_buf(tp, bp); | 2070 | xfs_trans_stale_inode_buf(tp, bp); |
2088 | xfs_trans_binval(tp, bp); | 2071 | xfs_trans_binval(tp, bp); |
2089 | } | 2072 | } |
2090 | 2073 | ||
2091 | kmem_free(ip_found); | ||
2092 | xfs_perag_put(pag); | 2074 | xfs_perag_put(pag); |
2093 | } | 2075 | } |
2094 | 2076 | ||
@@ -2649,8 +2631,6 @@ xfs_iflush_cluster( | |||
2649 | int i; | 2631 | int i; |
2650 | 2632 | ||
2651 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | 2633 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); |
2652 | ASSERT(pag->pagi_inodeok); | ||
2653 | ASSERT(pag->pag_ici_init); | ||
2654 | 2634 | ||
2655 | inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; | 2635 | inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; |
2656 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); | 2636 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 14a69aec2c0b..ed0684cc50ee 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -132,15 +132,10 @@ xlog_align( | |||
132 | int nbblks, | 132 | int nbblks, |
133 | xfs_buf_t *bp) | 133 | xfs_buf_t *bp) |
134 | { | 134 | { |
135 | xfs_daddr_t offset; | 135 | xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); |
136 | xfs_caddr_t ptr; | ||
137 | 136 | ||
138 | offset = blk_no & ((xfs_daddr_t) log->l_sectBBsize - 1); | 137 | ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); |
139 | ptr = XFS_BUF_PTR(bp) + BBTOB(offset); | 138 | return XFS_BUF_PTR(bp) + BBTOB(offset); |
140 | |||
141 | ASSERT(ptr + BBTOB(nbblks) <= XFS_BUF_PTR(bp) + XFS_BUF_SIZE(bp)); | ||
142 | |||
143 | return ptr; | ||
144 | } | 139 | } |
145 | 140 | ||
146 | 141 | ||
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index d7bf38c8cd1c..d59f4e8bedcf 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -268,10 +268,10 @@ xfs_sb_validate_fsb_count( | |||
268 | 268 | ||
269 | #if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ | 269 | #if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ |
270 | if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) | 270 | if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) |
271 | return E2BIG; | 271 | return EFBIG; |
272 | #else /* Limited by UINT_MAX of sectors */ | 272 | #else /* Limited by UINT_MAX of sectors */ |
273 | if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) | 273 | if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) |
274 | return E2BIG; | 274 | return EFBIG; |
275 | #endif | 275 | #endif |
276 | return 0; | 276 | return 0; |
277 | } | 277 | } |
@@ -393,7 +393,7 @@ xfs_mount_validate_sb( | |||
393 | xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { | 393 | xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { |
394 | xfs_fs_mount_cmn_err(flags, | 394 | xfs_fs_mount_cmn_err(flags, |
395 | "file system too large to be mounted on this system."); | 395 | "file system too large to be mounted on this system."); |
396 | return XFS_ERROR(E2BIG); | 396 | return XFS_ERROR(EFBIG); |
397 | } | 397 | } |
398 | 398 | ||
399 | if (unlikely(sbp->sb_inprogress)) { | 399 | if (unlikely(sbp->sb_inprogress)) { |
@@ -413,17 +413,6 @@ xfs_mount_validate_sb( | |||
413 | return 0; | 413 | return 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | STATIC void | ||
417 | xfs_initialize_perag_icache( | ||
418 | xfs_perag_t *pag) | ||
419 | { | ||
420 | if (!pag->pag_ici_init) { | ||
421 | rwlock_init(&pag->pag_ici_lock); | ||
422 | INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); | ||
423 | pag->pag_ici_init = 1; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | int | 416 | int |
428 | xfs_initialize_perag( | 417 | xfs_initialize_perag( |
429 | xfs_mount_t *mp, | 418 | xfs_mount_t *mp, |
@@ -436,13 +425,8 @@ xfs_initialize_perag( | |||
436 | xfs_agino_t agino; | 425 | xfs_agino_t agino; |
437 | xfs_ino_t ino; | 426 | xfs_ino_t ino; |
438 | xfs_sb_t *sbp = &mp->m_sb; | 427 | xfs_sb_t *sbp = &mp->m_sb; |
439 | xfs_ino_t max_inum = XFS_MAXINUMBER_32; | ||
440 | int error = -ENOMEM; | 428 | int error = -ENOMEM; |
441 | 429 | ||
442 | /* Check to see if the filesystem can overflow 32 bit inodes */ | ||
443 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); | ||
444 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); | ||
445 | |||
446 | /* | 430 | /* |
447 | * Walk the current per-ag tree so we don't try to initialise AGs | 431 | * Walk the current per-ag tree so we don't try to initialise AGs |
448 | * that already exist (growfs case). Allocate and insert all the | 432 | * that already exist (growfs case). Allocate and insert all the |
@@ -456,11 +440,18 @@ xfs_initialize_perag( | |||
456 | } | 440 | } |
457 | if (!first_initialised) | 441 | if (!first_initialised) |
458 | first_initialised = index; | 442 | first_initialised = index; |
443 | |||
459 | pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); | 444 | pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); |
460 | if (!pag) | 445 | if (!pag) |
461 | goto out_unwind; | 446 | goto out_unwind; |
447 | pag->pag_agno = index; | ||
448 | pag->pag_mount = mp; | ||
449 | rwlock_init(&pag->pag_ici_lock); | ||
450 | INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); | ||
451 | |||
462 | if (radix_tree_preload(GFP_NOFS)) | 452 | if (radix_tree_preload(GFP_NOFS)) |
463 | goto out_unwind; | 453 | goto out_unwind; |
454 | |||
464 | spin_lock(&mp->m_perag_lock); | 455 | spin_lock(&mp->m_perag_lock); |
465 | if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { | 456 | if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { |
466 | BUG(); | 457 | BUG(); |
@@ -469,25 +460,26 @@ xfs_initialize_perag( | |||
469 | error = -EEXIST; | 460 | error = -EEXIST; |
470 | goto out_unwind; | 461 | goto out_unwind; |
471 | } | 462 | } |
472 | pag->pag_agno = index; | ||
473 | pag->pag_mount = mp; | ||
474 | spin_unlock(&mp->m_perag_lock); | 463 | spin_unlock(&mp->m_perag_lock); |
475 | radix_tree_preload_end(); | 464 | radix_tree_preload_end(); |
476 | } | 465 | } |
477 | 466 | ||
478 | /* Clear the mount flag if no inode can overflow 32 bits | 467 | /* |
479 | * on this filesystem, or if specifically requested.. | 468 | * If we mount with the inode64 option, or no inode overflows |
469 | * the legacy 32-bit address space clear the inode32 option. | ||
480 | */ | 470 | */ |
481 | if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { | 471 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); |
472 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); | ||
473 | |||
474 | if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32) | ||
482 | mp->m_flags |= XFS_MOUNT_32BITINODES; | 475 | mp->m_flags |= XFS_MOUNT_32BITINODES; |
483 | } else { | 476 | else |
484 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; | 477 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; |
485 | } | ||
486 | 478 | ||
487 | /* If we can overflow then setup the ag headers accordingly */ | ||
488 | if (mp->m_flags & XFS_MOUNT_32BITINODES) { | 479 | if (mp->m_flags & XFS_MOUNT_32BITINODES) { |
489 | /* Calculate how much should be reserved for inodes to | 480 | /* |
490 | * meet the max inode percentage. | 481 | * Calculate how much should be reserved for inodes to meet |
482 | * the max inode percentage. | ||
491 | */ | 483 | */ |
492 | if (mp->m_maxicount) { | 484 | if (mp->m_maxicount) { |
493 | __uint64_t icount; | 485 | __uint64_t icount; |
@@ -500,30 +492,28 @@ xfs_initialize_perag( | |||
500 | } else { | 492 | } else { |
501 | max_metadata = agcount; | 493 | max_metadata = agcount; |
502 | } | 494 | } |
495 | |||
503 | for (index = 0; index < agcount; index++) { | 496 | for (index = 0; index < agcount; index++) { |
504 | ino = XFS_AGINO_TO_INO(mp, index, agino); | 497 | ino = XFS_AGINO_TO_INO(mp, index, agino); |
505 | if (ino > max_inum) { | 498 | if (ino > XFS_MAXINUMBER_32) { |
506 | index++; | 499 | index++; |
507 | break; | 500 | break; |
508 | } | 501 | } |
509 | 502 | ||
510 | /* This ag is preferred for inodes */ | ||
511 | pag = xfs_perag_get(mp, index); | 503 | pag = xfs_perag_get(mp, index); |
512 | pag->pagi_inodeok = 1; | 504 | pag->pagi_inodeok = 1; |
513 | if (index < max_metadata) | 505 | if (index < max_metadata) |
514 | pag->pagf_metadata = 1; | 506 | pag->pagf_metadata = 1; |
515 | xfs_initialize_perag_icache(pag); | ||
516 | xfs_perag_put(pag); | 507 | xfs_perag_put(pag); |
517 | } | 508 | } |
518 | } else { | 509 | } else { |
519 | /* Setup default behavior for smaller filesystems */ | ||
520 | for (index = 0; index < agcount; index++) { | 510 | for (index = 0; index < agcount; index++) { |
521 | pag = xfs_perag_get(mp, index); | 511 | pag = xfs_perag_get(mp, index); |
522 | pag->pagi_inodeok = 1; | 512 | pag->pagi_inodeok = 1; |
523 | xfs_initialize_perag_icache(pag); | ||
524 | xfs_perag_put(pag); | 513 | xfs_perag_put(pag); |
525 | } | 514 | } |
526 | } | 515 | } |
516 | |||
527 | if (maxagi) | 517 | if (maxagi) |
528 | *maxagi = index; | 518 | *maxagi = index; |
529 | return 0; | 519 | return 0; |
@@ -1009,7 +999,7 @@ xfs_check_sizes(xfs_mount_t *mp) | |||
1009 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); | 999 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); |
1010 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { | 1000 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { |
1011 | cmn_err(CE_WARN, "XFS: size check 1 failed"); | 1001 | cmn_err(CE_WARN, "XFS: size check 1 failed"); |
1012 | return XFS_ERROR(E2BIG); | 1002 | return XFS_ERROR(EFBIG); |
1013 | } | 1003 | } |
1014 | error = xfs_read_buf(mp, mp->m_ddev_targp, | 1004 | error = xfs_read_buf(mp, mp->m_ddev_targp, |
1015 | d - XFS_FSS_TO_BB(mp, 1), | 1005 | d - XFS_FSS_TO_BB(mp, 1), |
@@ -1019,7 +1009,7 @@ xfs_check_sizes(xfs_mount_t *mp) | |||
1019 | } else { | 1009 | } else { |
1020 | cmn_err(CE_WARN, "XFS: size check 2 failed"); | 1010 | cmn_err(CE_WARN, "XFS: size check 2 failed"); |
1021 | if (error == ENOSPC) | 1011 | if (error == ENOSPC) |
1022 | error = XFS_ERROR(E2BIG); | 1012 | error = XFS_ERROR(EFBIG); |
1023 | return error; | 1013 | return error; |
1024 | } | 1014 | } |
1025 | 1015 | ||
@@ -1027,7 +1017,7 @@ xfs_check_sizes(xfs_mount_t *mp) | |||
1027 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); | 1017 | d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); |
1028 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { | 1018 | if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { |
1029 | cmn_err(CE_WARN, "XFS: size check 3 failed"); | 1019 | cmn_err(CE_WARN, "XFS: size check 3 failed"); |
1030 | return XFS_ERROR(E2BIG); | 1020 | return XFS_ERROR(EFBIG); |
1031 | } | 1021 | } |
1032 | error = xfs_read_buf(mp, mp->m_logdev_targp, | 1022 | error = xfs_read_buf(mp, mp->m_logdev_targp, |
1033 | d - XFS_FSB_TO_BB(mp, 1), | 1023 | d - XFS_FSB_TO_BB(mp, 1), |
@@ -1037,7 +1027,7 @@ xfs_check_sizes(xfs_mount_t *mp) | |||
1037 | } else { | 1027 | } else { |
1038 | cmn_err(CE_WARN, "XFS: size check 3 failed"); | 1028 | cmn_err(CE_WARN, "XFS: size check 3 failed"); |
1039 | if (error == ENOSPC) | 1029 | if (error == ENOSPC) |
1040 | error = XFS_ERROR(E2BIG); | 1030 | error = XFS_ERROR(EFBIG); |
1041 | return error; | 1031 | return error; |
1042 | } | 1032 | } |
1043 | } | 1033 | } |
@@ -1254,7 +1244,7 @@ xfs_mountfs( | |||
1254 | * Allocate and initialize the per-ag data. | 1244 | * Allocate and initialize the per-ag data. |
1255 | */ | 1245 | */ |
1256 | spin_lock_init(&mp->m_perag_lock); | 1246 | spin_lock_init(&mp->m_perag_lock); |
1257 | INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS); | 1247 | INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); |
1258 | error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); | 1248 | error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); |
1259 | if (error) { | 1249 | if (error) { |
1260 | cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error); | 1250 | cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error); |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 6be05f756d59..16445518506d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -2247,7 +2247,7 @@ xfs_rtmount_init( | |||
2247 | cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu", | 2247 | cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu", |
2248 | (unsigned long long) XFS_BB_TO_FSB(mp, d), | 2248 | (unsigned long long) XFS_BB_TO_FSB(mp, d), |
2249 | (unsigned long long) mp->m_sb.sb_rblocks); | 2249 | (unsigned long long) mp->m_sb.sb_rblocks); |
2250 | return XFS_ERROR(E2BIG); | 2250 | return XFS_ERROR(EFBIG); |
2251 | } | 2251 | } |
2252 | error = xfs_read_buf(mp, mp->m_rtdev_targp, | 2252 | error = xfs_read_buf(mp, mp->m_rtdev_targp, |
2253 | d - XFS_FSB_TO_BB(mp, 1), | 2253 | d - XFS_FSB_TO_BB(mp, 1), |
@@ -2256,7 +2256,7 @@ xfs_rtmount_init( | |||
2256 | cmn_err(CE_WARN, | 2256 | cmn_err(CE_WARN, |
2257 | "XFS: realtime mount -- xfs_read_buf failed, returned %d", error); | 2257 | "XFS: realtime mount -- xfs_read_buf failed, returned %d", error); |
2258 | if (error == ENOSPC) | 2258 | if (error == ENOSPC) |
2259 | return XFS_ERROR(E2BIG); | 2259 | return XFS_ERROR(EFBIG); |
2260 | return error; | 2260 | return error; |
2261 | } | 2261 | } |
2262 | xfs_buf_relse(bp); | 2262 | xfs_buf_relse(bp); |
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index b2d67adb6a08..ff614c29b441 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h | |||
@@ -147,7 +147,16 @@ xfs_growfs_rt( | |||
147 | # define xfs_rtfree_extent(t,b,l) (ENOSYS) | 147 | # define xfs_rtfree_extent(t,b,l) (ENOSYS) |
148 | # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) | 148 | # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) |
149 | # define xfs_growfs_rt(mp,in) (ENOSYS) | 149 | # define xfs_growfs_rt(mp,in) (ENOSYS) |
150 | # define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) | 150 | static inline int /* error */ |
151 | xfs_rtmount_init( | ||
152 | xfs_mount_t *mp) /* file system mount structure */ | ||
153 | { | ||
154 | if (mp->m_sb.sb_rblocks == 0) | ||
155 | return 0; | ||
156 | |||
157 | cmn_err(CE_WARN, "XFS: Not built with CONFIG_XFS_RT"); | ||
158 | return ENOSYS; | ||
159 | } | ||
151 | # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) | 160 | # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) |
152 | # define xfs_rtunmount_inodes(m) | 161 | # define xfs_rtunmount_inodes(m) |
153 | #endif /* CONFIG_XFS_RT */ | 162 | #endif /* CONFIG_XFS_RT */ |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index ce558efa2ea0..28547dfce037 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -48,134 +48,489 @@ | |||
48 | 48 | ||
49 | kmem_zone_t *xfs_trans_zone; | 49 | kmem_zone_t *xfs_trans_zone; |
50 | 50 | ||
51 | |||
51 | /* | 52 | /* |
52 | * Reservation functions here avoid a huge stack in xfs_trans_init | 53 | * Various log reservation values. |
53 | * due to register overflow from temporaries in the calculations. | 54 | * |
55 | * These are based on the size of the file system block because that is what | ||
56 | * most transactions manipulate. Each adds in an additional 128 bytes per | ||
57 | * item logged to try to account for the overhead of the transaction mechanism. | ||
58 | * | ||
59 | * Note: Most of the reservations underestimate the number of allocation | ||
60 | * groups into which they could free extents in the xfs_bmap_finish() call. | ||
61 | * This is because the number in the worst case is quite high and quite | ||
62 | * unusual. In order to fix this we need to change xfs_bmap_finish() to free | ||
63 | * extents in only a single AG at a time. This will require changes to the | ||
64 | * EFI code as well, however, so that the EFI for the extents not freed is | ||
65 | * logged again in each transaction. See SGI PV #261917. | ||
66 | * | ||
67 | * Reservation functions here avoid a huge stack in xfs_trans_init due to | ||
68 | * register overflow from temporaries in the calculations. | ||
69 | */ | ||
70 | |||
71 | |||
72 | /* | ||
73 | * In a write transaction we can allocate a maximum of 2 | ||
74 | * extents. This gives: | ||
75 | * the inode getting the new extents: inode size | ||
76 | * the inode's bmap btree: max depth * block size | ||
77 | * the agfs of the ags from which the extents are allocated: 2 * sector | ||
78 | * the superblock free block counter: sector size | ||
79 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
80 | * And the bmap_finish transaction can free bmap blocks in a join: | ||
81 | * the agfs of the ags containing the blocks: 2 * sector size | ||
82 | * the agfls of the ags containing the blocks: 2 * sector size | ||
83 | * the super block free block counter: sector size | ||
84 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
54 | */ | 85 | */ |
55 | STATIC uint | 86 | STATIC uint |
56 | xfs_calc_write_reservation(xfs_mount_t *mp) | 87 | xfs_calc_write_reservation( |
88 | struct xfs_mount *mp) | ||
57 | { | 89 | { |
58 | return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 90 | return XFS_DQUOT_LOGRES(mp) + |
91 | MAX((mp->m_sb.sb_inodesize + | ||
92 | XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + | ||
93 | 2 * mp->m_sb.sb_sectsize + | ||
94 | mp->m_sb.sb_sectsize + | ||
95 | XFS_ALLOCFREE_LOG_RES(mp, 2) + | ||
96 | 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + | ||
97 | XFS_ALLOCFREE_LOG_COUNT(mp, 2))), | ||
98 | (2 * mp->m_sb.sb_sectsize + | ||
99 | 2 * mp->m_sb.sb_sectsize + | ||
100 | mp->m_sb.sb_sectsize + | ||
101 | XFS_ALLOCFREE_LOG_RES(mp, 2) + | ||
102 | 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); | ||
59 | } | 103 | } |
60 | 104 | ||
105 | /* | ||
106 | * In truncating a file we free up to two extents at once. We can modify: | ||
107 | * the inode being truncated: inode size | ||
108 | * the inode's bmap btree: (max depth + 1) * block size | ||
109 | * And the bmap_finish transaction can free the blocks and bmap blocks: | ||
110 | * the agf for each of the ags: 4 * sector size | ||
111 | * the agfl for each of the ags: 4 * sector size | ||
112 | * the super block to reflect the freed blocks: sector size | ||
113 | * worst case split in allocation btrees per extent assuming 4 extents: | ||
114 | * 4 exts * 2 trees * (2 * max depth - 1) * block size | ||
115 | * the inode btree: max depth * blocksize | ||
116 | * the allocation btrees: 2 trees * (max depth - 1) * block size | ||
117 | */ | ||
61 | STATIC uint | 118 | STATIC uint |
62 | xfs_calc_itruncate_reservation(xfs_mount_t *mp) | 119 | xfs_calc_itruncate_reservation( |
120 | struct xfs_mount *mp) | ||
63 | { | 121 | { |
64 | return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 122 | return XFS_DQUOT_LOGRES(mp) + |
123 | MAX((mp->m_sb.sb_inodesize + | ||
124 | XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + | ||
125 | 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), | ||
126 | (4 * mp->m_sb.sb_sectsize + | ||
127 | 4 * mp->m_sb.sb_sectsize + | ||
128 | mp->m_sb.sb_sectsize + | ||
129 | XFS_ALLOCFREE_LOG_RES(mp, 4) + | ||
130 | 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) + | ||
131 | 128 * 5 + | ||
132 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
133 | 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + | ||
134 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); | ||
65 | } | 135 | } |
66 | 136 | ||
137 | /* | ||
138 | * In renaming a files we can modify: | ||
139 | * the four inodes involved: 4 * inode size | ||
140 | * the two directory btrees: 2 * (max depth + v2) * dir block size | ||
141 | * the two directory bmap btrees: 2 * max depth * block size | ||
142 | * And the bmap_finish transaction can free dir and bmap blocks (two sets | ||
143 | * of bmap blocks) giving: | ||
144 | * the agf for the ags in which the blocks live: 3 * sector size | ||
145 | * the agfl for the ags in which the blocks live: 3 * sector size | ||
146 | * the superblock for the free block count: sector size | ||
147 | * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size | ||
148 | */ | ||
67 | STATIC uint | 149 | STATIC uint |
68 | xfs_calc_rename_reservation(xfs_mount_t *mp) | 150 | xfs_calc_rename_reservation( |
151 | struct xfs_mount *mp) | ||
69 | { | 152 | { |
70 | return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 153 | return XFS_DQUOT_LOGRES(mp) + |
154 | MAX((4 * mp->m_sb.sb_inodesize + | ||
155 | 2 * XFS_DIROP_LOG_RES(mp) + | ||
156 | 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))), | ||
157 | (3 * mp->m_sb.sb_sectsize + | ||
158 | 3 * mp->m_sb.sb_sectsize + | ||
159 | mp->m_sb.sb_sectsize + | ||
160 | XFS_ALLOCFREE_LOG_RES(mp, 3) + | ||
161 | 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))); | ||
71 | } | 162 | } |
72 | 163 | ||
164 | /* | ||
165 | * For creating a link to an inode: | ||
166 | * the parent directory inode: inode size | ||
167 | * the linked inode: inode size | ||
168 | * the directory btree could split: (max depth + v2) * dir block size | ||
169 | * the directory bmap btree could join or split: (max depth + v2) * blocksize | ||
170 | * And the bmap_finish transaction can free some bmap blocks giving: | ||
171 | * the agf for the ag in which the blocks live: sector size | ||
172 | * the agfl for the ag in which the blocks live: sector size | ||
173 | * the superblock for the free block count: sector size | ||
174 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size | ||
175 | */ | ||
73 | STATIC uint | 176 | STATIC uint |
74 | xfs_calc_link_reservation(xfs_mount_t *mp) | 177 | xfs_calc_link_reservation( |
178 | struct xfs_mount *mp) | ||
75 | { | 179 | { |
76 | return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 180 | return XFS_DQUOT_LOGRES(mp) + |
181 | MAX((mp->m_sb.sb_inodesize + | ||
182 | mp->m_sb.sb_inodesize + | ||
183 | XFS_DIROP_LOG_RES(mp) + | ||
184 | 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), | ||
185 | (mp->m_sb.sb_sectsize + | ||
186 | mp->m_sb.sb_sectsize + | ||
187 | mp->m_sb.sb_sectsize + | ||
188 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
189 | 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); | ||
77 | } | 190 | } |
78 | 191 | ||
192 | /* | ||
193 | * For removing a directory entry we can modify: | ||
194 | * the parent directory inode: inode size | ||
195 | * the removed inode: inode size | ||
196 | * the directory btree could join: (max depth + v2) * dir block size | ||
197 | * the directory bmap btree could join or split: (max depth + v2) * blocksize | ||
198 | * And the bmap_finish transaction can free the dir and bmap blocks giving: | ||
199 | * the agf for the ag in which the blocks live: 2 * sector size | ||
200 | * the agfl for the ag in which the blocks live: 2 * sector size | ||
201 | * the superblock for the free block count: sector size | ||
202 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
203 | */ | ||
79 | STATIC uint | 204 | STATIC uint |
80 | xfs_calc_remove_reservation(xfs_mount_t *mp) | 205 | xfs_calc_remove_reservation( |
206 | struct xfs_mount *mp) | ||
81 | { | 207 | { |
82 | return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 208 | return XFS_DQUOT_LOGRES(mp) + |
209 | MAX((mp->m_sb.sb_inodesize + | ||
210 | mp->m_sb.sb_inodesize + | ||
211 | XFS_DIROP_LOG_RES(mp) + | ||
212 | 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), | ||
213 | (2 * mp->m_sb.sb_sectsize + | ||
214 | 2 * mp->m_sb.sb_sectsize + | ||
215 | mp->m_sb.sb_sectsize + | ||
216 | XFS_ALLOCFREE_LOG_RES(mp, 2) + | ||
217 | 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); | ||
83 | } | 218 | } |
84 | 219 | ||
220 | /* | ||
221 | * For symlink we can modify: | ||
222 | * the parent directory inode: inode size | ||
223 | * the new inode: inode size | ||
224 | * the inode btree entry: 1 block | ||
225 | * the directory btree: (max depth + v2) * dir block size | ||
226 | * the directory inode's bmap btree: (max depth + v2) * block size | ||
227 | * the blocks for the symlink: 1 kB | ||
228 | * Or in the first xact we allocate some inodes giving: | ||
229 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize | ||
230 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize | ||
231 | * the inode btree: max depth * blocksize | ||
232 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size | ||
233 | */ | ||
85 | STATIC uint | 234 | STATIC uint |
86 | xfs_calc_symlink_reservation(xfs_mount_t *mp) | 235 | xfs_calc_symlink_reservation( |
236 | struct xfs_mount *mp) | ||
87 | { | 237 | { |
88 | return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 238 | return XFS_DQUOT_LOGRES(mp) + |
239 | MAX((mp->m_sb.sb_inodesize + | ||
240 | mp->m_sb.sb_inodesize + | ||
241 | XFS_FSB_TO_B(mp, 1) + | ||
242 | XFS_DIROP_LOG_RES(mp) + | ||
243 | 1024 + | ||
244 | 128 * (4 + XFS_DIROP_LOG_COUNT(mp))), | ||
245 | (2 * mp->m_sb.sb_sectsize + | ||
246 | XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + | ||
247 | XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + | ||
248 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
249 | 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + | ||
250 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); | ||
89 | } | 251 | } |
90 | 252 | ||
253 | /* | ||
254 | * For create we can modify: | ||
255 | * the parent directory inode: inode size | ||
256 | * the new inode: inode size | ||
257 | * the inode btree entry: block size | ||
258 | * the superblock for the nlink flag: sector size | ||
259 | * the directory btree: (max depth + v2) * dir block size | ||
260 | * the directory inode's bmap btree: (max depth + v2) * block size | ||
261 | * Or in the first xact we allocate some inodes giving: | ||
262 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize | ||
263 | * the superblock for the nlink flag: sector size | ||
264 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize | ||
265 | * the inode btree: max depth * blocksize | ||
266 | * the allocation btrees: 2 trees * (max depth - 1) * block size | ||
267 | */ | ||
91 | STATIC uint | 268 | STATIC uint |
92 | xfs_calc_create_reservation(xfs_mount_t *mp) | 269 | xfs_calc_create_reservation( |
270 | struct xfs_mount *mp) | ||
93 | { | 271 | { |
94 | return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 272 | return XFS_DQUOT_LOGRES(mp) + |
273 | MAX((mp->m_sb.sb_inodesize + | ||
274 | mp->m_sb.sb_inodesize + | ||
275 | mp->m_sb.sb_sectsize + | ||
276 | XFS_FSB_TO_B(mp, 1) + | ||
277 | XFS_DIROP_LOG_RES(mp) + | ||
278 | 128 * (3 + XFS_DIROP_LOG_COUNT(mp))), | ||
279 | (3 * mp->m_sb.sb_sectsize + | ||
280 | XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + | ||
281 | XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + | ||
282 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
283 | 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + | ||
284 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); | ||
95 | } | 285 | } |
96 | 286 | ||
287 | /* | ||
288 | * Making a new directory is the same as creating a new file. | ||
289 | */ | ||
97 | STATIC uint | 290 | STATIC uint |
98 | xfs_calc_mkdir_reservation(xfs_mount_t *mp) | 291 | xfs_calc_mkdir_reservation( |
292 | struct xfs_mount *mp) | ||
99 | { | 293 | { |
100 | return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 294 | return xfs_calc_create_reservation(mp); |
101 | } | 295 | } |
102 | 296 | ||
297 | /* | ||
298 | * In freeing an inode we can modify: | ||
299 | * the inode being freed: inode size | ||
300 | * the super block free inode counter: sector size | ||
301 | * the agi hash list and counters: sector size | ||
302 | * the inode btree entry: block size | ||
303 | * the on disk inode before ours in the agi hash list: inode cluster size | ||
304 | * the inode btree: max depth * blocksize | ||
305 | * the allocation btrees: 2 trees * (max depth - 1) * block size | ||
306 | */ | ||
103 | STATIC uint | 307 | STATIC uint |
104 | xfs_calc_ifree_reservation(xfs_mount_t *mp) | 308 | xfs_calc_ifree_reservation( |
309 | struct xfs_mount *mp) | ||
105 | { | 310 | { |
106 | return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 311 | return XFS_DQUOT_LOGRES(mp) + |
312 | mp->m_sb.sb_inodesize + | ||
313 | mp->m_sb.sb_sectsize + | ||
314 | mp->m_sb.sb_sectsize + | ||
315 | XFS_FSB_TO_B(mp, 1) + | ||
316 | MAX((__uint16_t)XFS_FSB_TO_B(mp, 1), | ||
317 | XFS_INODE_CLUSTER_SIZE(mp)) + | ||
318 | 128 * 5 + | ||
319 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
320 | 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + | ||
321 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)); | ||
107 | } | 322 | } |
108 | 323 | ||
324 | /* | ||
325 | * When only changing the inode we log the inode and possibly the superblock | ||
326 | * We also add a bit of slop for the transaction stuff. | ||
327 | */ | ||
109 | STATIC uint | 328 | STATIC uint |
110 | xfs_calc_ichange_reservation(xfs_mount_t *mp) | 329 | xfs_calc_ichange_reservation( |
330 | struct xfs_mount *mp) | ||
111 | { | 331 | { |
112 | return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 332 | return XFS_DQUOT_LOGRES(mp) + |
333 | mp->m_sb.sb_inodesize + | ||
334 | mp->m_sb.sb_sectsize + | ||
335 | 512; | ||
336 | |||
113 | } | 337 | } |
114 | 338 | ||
339 | /* | ||
340 | * Growing the data section of the filesystem. | ||
341 | * superblock | ||
342 | * agi and agf | ||
343 | * allocation btrees | ||
344 | */ | ||
115 | STATIC uint | 345 | STATIC uint |
116 | xfs_calc_growdata_reservation(xfs_mount_t *mp) | 346 | xfs_calc_growdata_reservation( |
347 | struct xfs_mount *mp) | ||
117 | { | 348 | { |
118 | return XFS_CALC_GROWDATA_LOG_RES(mp); | 349 | return mp->m_sb.sb_sectsize * 3 + |
350 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
351 | 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); | ||
119 | } | 352 | } |
120 | 353 | ||
354 | /* | ||
355 | * Growing the rt section of the filesystem. | ||
356 | * In the first set of transactions (ALLOC) we allocate space to the | ||
357 | * bitmap or summary files. | ||
358 | * superblock: sector size | ||
359 | * agf of the ag from which the extent is allocated: sector size | ||
360 | * bmap btree for bitmap/summary inode: max depth * blocksize | ||
361 | * bitmap/summary inode: inode size | ||
362 | * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize | ||
363 | */ | ||
121 | STATIC uint | 364 | STATIC uint |
122 | xfs_calc_growrtalloc_reservation(xfs_mount_t *mp) | 365 | xfs_calc_growrtalloc_reservation( |
366 | struct xfs_mount *mp) | ||
123 | { | 367 | { |
124 | return XFS_CALC_GROWRTALLOC_LOG_RES(mp); | 368 | return 2 * mp->m_sb.sb_sectsize + |
369 | XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + | ||
370 | mp->m_sb.sb_inodesize + | ||
371 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
372 | 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + | ||
373 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)); | ||
125 | } | 374 | } |
126 | 375 | ||
376 | /* | ||
377 | * Growing the rt section of the filesystem. | ||
378 | * In the second set of transactions (ZERO) we zero the new metadata blocks. | ||
379 | * one bitmap/summary block: blocksize | ||
380 | */ | ||
127 | STATIC uint | 381 | STATIC uint |
128 | xfs_calc_growrtzero_reservation(xfs_mount_t *mp) | 382 | xfs_calc_growrtzero_reservation( |
383 | struct xfs_mount *mp) | ||
129 | { | 384 | { |
130 | return XFS_CALC_GROWRTZERO_LOG_RES(mp); | 385 | return mp->m_sb.sb_blocksize + 128; |
131 | } | 386 | } |
132 | 387 | ||
388 | /* | ||
389 | * Growing the rt section of the filesystem. | ||
390 | * In the third set of transactions (FREE) we update metadata without | ||
391 | * allocating any new blocks. | ||
392 | * superblock: sector size | ||
393 | * bitmap inode: inode size | ||
394 | * summary inode: inode size | ||
395 | * one bitmap block: blocksize | ||
396 | * summary blocks: new summary size | ||
397 | */ | ||
133 | STATIC uint | 398 | STATIC uint |
134 | xfs_calc_growrtfree_reservation(xfs_mount_t *mp) | 399 | xfs_calc_growrtfree_reservation( |
400 | struct xfs_mount *mp) | ||
135 | { | 401 | { |
136 | return XFS_CALC_GROWRTFREE_LOG_RES(mp); | 402 | return mp->m_sb.sb_sectsize + |
403 | 2 * mp->m_sb.sb_inodesize + | ||
404 | mp->m_sb.sb_blocksize + | ||
405 | mp->m_rsumsize + | ||
406 | 128 * 5; | ||
137 | } | 407 | } |
138 | 408 | ||
409 | /* | ||
410 | * Logging the inode modification timestamp on a synchronous write. | ||
411 | * inode | ||
412 | */ | ||
139 | STATIC uint | 413 | STATIC uint |
140 | xfs_calc_swrite_reservation(xfs_mount_t *mp) | 414 | xfs_calc_swrite_reservation( |
415 | struct xfs_mount *mp) | ||
141 | { | 416 | { |
142 | return XFS_CALC_SWRITE_LOG_RES(mp); | 417 | return mp->m_sb.sb_inodesize + 128; |
143 | } | 418 | } |
144 | 419 | ||
420 | /* | ||
421 | * Logging the inode mode bits when writing a setuid/setgid file | ||
422 | * inode | ||
423 | */ | ||
145 | STATIC uint | 424 | STATIC uint |
146 | xfs_calc_writeid_reservation(xfs_mount_t *mp) | 425 | xfs_calc_writeid_reservation(xfs_mount_t *mp) |
147 | { | 426 | { |
148 | return XFS_CALC_WRITEID_LOG_RES(mp); | 427 | return mp->m_sb.sb_inodesize + 128; |
149 | } | 428 | } |
150 | 429 | ||
430 | /* | ||
431 | * Converting the inode from non-attributed to attributed. | ||
432 | * the inode being converted: inode size | ||
433 | * agf block and superblock (for block allocation) | ||
434 | * the new block (directory sized) | ||
435 | * bmap blocks for the new directory block | ||
436 | * allocation btrees | ||
437 | */ | ||
151 | STATIC uint | 438 | STATIC uint |
152 | xfs_calc_addafork_reservation(xfs_mount_t *mp) | 439 | xfs_calc_addafork_reservation( |
440 | struct xfs_mount *mp) | ||
153 | { | 441 | { |
154 | return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 442 | return XFS_DQUOT_LOGRES(mp) + |
443 | mp->m_sb.sb_inodesize + | ||
444 | mp->m_sb.sb_sectsize * 2 + | ||
445 | mp->m_dirblksize + | ||
446 | XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + | ||
447 | XFS_ALLOCFREE_LOG_RES(mp, 1) + | ||
448 | 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 + | ||
449 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)); | ||
155 | } | 450 | } |
156 | 451 | ||
452 | /* | ||
453 | * Removing the attribute fork of a file | ||
454 | * the inode being truncated: inode size | ||
455 | * the inode's bmap btree: max depth * block size | ||
456 | * And the bmap_finish transaction can free the blocks and bmap blocks: | ||
457 | * the agf for each of the ags: 4 * sector size | ||
458 | * the agfl for each of the ags: 4 * sector size | ||
459 | * the super block to reflect the freed blocks: sector size | ||
460 | * worst case split in allocation btrees per extent assuming 4 extents: | ||
461 | * 4 exts * 2 trees * (2 * max depth - 1) * block size | ||
462 | */ | ||
157 | STATIC uint | 463 | STATIC uint |
158 | xfs_calc_attrinval_reservation(xfs_mount_t *mp) | 464 | xfs_calc_attrinval_reservation( |
465 | struct xfs_mount *mp) | ||
159 | { | 466 | { |
160 | return XFS_CALC_ATTRINVAL_LOG_RES(mp); | 467 | return MAX((mp->m_sb.sb_inodesize + |
468 | XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + | ||
469 | 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))), | ||
470 | (4 * mp->m_sb.sb_sectsize + | ||
471 | 4 * mp->m_sb.sb_sectsize + | ||
472 | mp->m_sb.sb_sectsize + | ||
473 | XFS_ALLOCFREE_LOG_RES(mp, 4) + | ||
474 | 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))); | ||
161 | } | 475 | } |
162 | 476 | ||
477 | /* | ||
478 | * Setting an attribute. | ||
479 | * the inode getting the attribute | ||
480 | * the superblock for allocations | ||
481 | * the agfs extents are allocated from | ||
482 | * the attribute btree * max depth | ||
483 | * the inode allocation btree | ||
484 | * Since attribute transaction space is dependent on the size of the attribute, | ||
485 | * the calculation is done partially at mount time and partially at runtime. | ||
486 | */ | ||
163 | STATIC uint | 487 | STATIC uint |
164 | xfs_calc_attrset_reservation(xfs_mount_t *mp) | 488 | xfs_calc_attrset_reservation( |
489 | struct xfs_mount *mp) | ||
165 | { | 490 | { |
166 | return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 491 | return XFS_DQUOT_LOGRES(mp) + |
492 | mp->m_sb.sb_inodesize + | ||
493 | mp->m_sb.sb_sectsize + | ||
494 | XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + | ||
495 | 128 * (2 + XFS_DA_NODE_MAXDEPTH); | ||
167 | } | 496 | } |
168 | 497 | ||
498 | /* | ||
499 | * Removing an attribute. | ||
500 | * the inode: inode size | ||
501 | * the attribute btree could join: max depth * block size | ||
502 | * the inode bmap btree could join or split: max depth * block size | ||
503 | * And the bmap_finish transaction can free the attr blocks freed giving: | ||
504 | * the agf for the ag in which the blocks live: 2 * sector size | ||
505 | * the agfl for the ag in which the blocks live: 2 * sector size | ||
506 | * the superblock for the free block count: sector size | ||
507 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
508 | */ | ||
169 | STATIC uint | 509 | STATIC uint |
170 | xfs_calc_attrrm_reservation(xfs_mount_t *mp) | 510 | xfs_calc_attrrm_reservation( |
511 | struct xfs_mount *mp) | ||
171 | { | 512 | { |
172 | return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); | 513 | return XFS_DQUOT_LOGRES(mp) + |
514 | MAX((mp->m_sb.sb_inodesize + | ||
515 | XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + | ||
516 | XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + | ||
517 | 128 * (1 + XFS_DA_NODE_MAXDEPTH + | ||
518 | XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), | ||
519 | (2 * mp->m_sb.sb_sectsize + | ||
520 | 2 * mp->m_sb.sb_sectsize + | ||
521 | mp->m_sb.sb_sectsize + | ||
522 | XFS_ALLOCFREE_LOG_RES(mp, 2) + | ||
523 | 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); | ||
173 | } | 524 | } |
174 | 525 | ||
526 | /* | ||
527 | * Clearing a bad agino number in an agi hash bucket. | ||
528 | */ | ||
175 | STATIC uint | 529 | STATIC uint |
176 | xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) | 530 | xfs_calc_clear_agi_bucket_reservation( |
531 | struct xfs_mount *mp) | ||
177 | { | 532 | { |
178 | return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp); | 533 | return mp->m_sb.sb_sectsize + 128; |
179 | } | 534 | } |
180 | 535 | ||
181 | /* | 536 | /* |
@@ -184,11 +539,10 @@ xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) | |||
184 | */ | 539 | */ |
185 | void | 540 | void |
186 | xfs_trans_init( | 541 | xfs_trans_init( |
187 | xfs_mount_t *mp) | 542 | struct xfs_mount *mp) |
188 | { | 543 | { |
189 | xfs_trans_reservations_t *resp; | 544 | struct xfs_trans_reservations *resp = &mp->m_reservations; |
190 | 545 | ||
191 | resp = &(mp->m_reservations); | ||
192 | resp->tr_write = xfs_calc_write_reservation(mp); | 546 | resp->tr_write = xfs_calc_write_reservation(mp); |
193 | resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); | 547 | resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); |
194 | resp->tr_rename = xfs_calc_rename_reservation(mp); | 548 | resp->tr_rename = xfs_calc_rename_reservation(mp); |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 8c69e7824f68..e639e8e9a2a9 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -300,24 +300,6 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | |||
300 | 300 | ||
301 | 301 | ||
302 | /* | 302 | /* |
303 | * Various log reservation values. | ||
304 | * These are based on the size of the file system block | ||
305 | * because that is what most transactions manipulate. | ||
306 | * Each adds in an additional 128 bytes per item logged to | ||
307 | * try to account for the overhead of the transaction mechanism. | ||
308 | * | ||
309 | * Note: | ||
310 | * Most of the reservations underestimate the number of allocation | ||
311 | * groups into which they could free extents in the xfs_bmap_finish() | ||
312 | * call. This is because the number in the worst case is quite high | ||
313 | * and quite unusual. In order to fix this we need to change | ||
314 | * xfs_bmap_finish() to free extents in only a single AG at a time. | ||
315 | * This will require changes to the EFI code as well, however, so that | ||
316 | * the EFI for the extents not freed is logged again in each transaction. | ||
317 | * See bug 261917. | ||
318 | */ | ||
319 | |||
320 | /* | ||
321 | * Per-extent log reservation for the allocation btree changes | 303 | * Per-extent log reservation for the allocation btree changes |
322 | * involved in freeing or allocating an extent. | 304 | * involved in freeing or allocating an extent. |
323 | * 2 trees * (2 blocks/level * max depth - 1) * block size | 305 | * 2 trees * (2 blocks/level * max depth - 1) * block size |
@@ -341,429 +323,36 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | |||
341 | (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ | 323 | (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ |
342 | XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) | 324 | XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) |
343 | 325 | ||
344 | /* | ||
345 | * In a write transaction we can allocate a maximum of 2 | ||
346 | * extents. This gives: | ||
347 | * the inode getting the new extents: inode size | ||
348 | * the inode's bmap btree: max depth * block size | ||
349 | * the agfs of the ags from which the extents are allocated: 2 * sector | ||
350 | * the superblock free block counter: sector size | ||
351 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
352 | * And the bmap_finish transaction can free bmap blocks in a join: | ||
353 | * the agfs of the ags containing the blocks: 2 * sector size | ||
354 | * the agfls of the ags containing the blocks: 2 * sector size | ||
355 | * the super block free block counter: sector size | ||
356 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
357 | */ | ||
358 | #define XFS_CALC_WRITE_LOG_RES(mp) \ | ||
359 | (MAX( \ | ||
360 | ((mp)->m_sb.sb_inodesize + \ | ||
361 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ | ||
362 | (2 * (mp)->m_sb.sb_sectsize) + \ | ||
363 | (mp)->m_sb.sb_sectsize + \ | ||
364 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | ||
365 | (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\ | ||
366 | ((2 * (mp)->m_sb.sb_sectsize) + \ | ||
367 | (2 * (mp)->m_sb.sb_sectsize) + \ | ||
368 | (mp)->m_sb.sb_sectsize + \ | ||
369 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | ||
370 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) | ||
371 | 326 | ||
372 | #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) | 327 | #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) |
373 | |||
374 | /* | ||
375 | * In truncating a file we free up to two extents at once. We can modify: | ||
376 | * the inode being truncated: inode size | ||
377 | * the inode's bmap btree: (max depth + 1) * block size | ||
378 | * And the bmap_finish transaction can free the blocks and bmap blocks: | ||
379 | * the agf for each of the ags: 4 * sector size | ||
380 | * the agfl for each of the ags: 4 * sector size | ||
381 | * the super block to reflect the freed blocks: sector size | ||
382 | * worst case split in allocation btrees per extent assuming 4 extents: | ||
383 | * 4 exts * 2 trees * (2 * max depth - 1) * block size | ||
384 | * the inode btree: max depth * blocksize | ||
385 | * the allocation btrees: 2 trees * (max depth - 1) * block size | ||
386 | */ | ||
387 | #define XFS_CALC_ITRUNCATE_LOG_RES(mp) \ | ||
388 | (MAX( \ | ||
389 | ((mp)->m_sb.sb_inodesize + \ | ||
390 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \ | ||
391 | (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ | ||
392 | ((4 * (mp)->m_sb.sb_sectsize) + \ | ||
393 | (4 * (mp)->m_sb.sb_sectsize) + \ | ||
394 | (mp)->m_sb.sb_sectsize + \ | ||
395 | XFS_ALLOCFREE_LOG_RES(mp, 4) + \ | ||
396 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \ | ||
397 | (128 * 5) + \ | ||
398 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
399 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ | ||
400 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | ||
401 | |||
402 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) | 328 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) |
403 | |||
404 | /* | ||
405 | * In renaming a files we can modify: | ||
406 | * the four inodes involved: 4 * inode size | ||
407 | * the two directory btrees: 2 * (max depth + v2) * dir block size | ||
408 | * the two directory bmap btrees: 2 * max depth * block size | ||
409 | * And the bmap_finish transaction can free dir and bmap blocks (two sets | ||
410 | * of bmap blocks) giving: | ||
411 | * the agf for the ags in which the blocks live: 3 * sector size | ||
412 | * the agfl for the ags in which the blocks live: 3 * sector size | ||
413 | * the superblock for the free block count: sector size | ||
414 | * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size | ||
415 | */ | ||
416 | #define XFS_CALC_RENAME_LOG_RES(mp) \ | ||
417 | (MAX( \ | ||
418 | ((4 * (mp)->m_sb.sb_inodesize) + \ | ||
419 | (2 * XFS_DIROP_LOG_RES(mp)) + \ | ||
420 | (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \ | ||
421 | ((3 * (mp)->m_sb.sb_sectsize) + \ | ||
422 | (3 * (mp)->m_sb.sb_sectsize) + \ | ||
423 | (mp)->m_sb.sb_sectsize + \ | ||
424 | XFS_ALLOCFREE_LOG_RES(mp, 3) + \ | ||
425 | (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))))) | ||
426 | |||
427 | #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) | 329 | #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) |
428 | |||
429 | /* | ||
430 | * For creating a link to an inode: | ||
431 | * the parent directory inode: inode size | ||
432 | * the linked inode: inode size | ||
433 | * the directory btree could split: (max depth + v2) * dir block size | ||
434 | * the directory bmap btree could join or split: (max depth + v2) * blocksize | ||
435 | * And the bmap_finish transaction can free some bmap blocks giving: | ||
436 | * the agf for the ag in which the blocks live: sector size | ||
437 | * the agfl for the ag in which the blocks live: sector size | ||
438 | * the superblock for the free block count: sector size | ||
439 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size | ||
440 | */ | ||
441 | #define XFS_CALC_LINK_LOG_RES(mp) \ | ||
442 | (MAX( \ | ||
443 | ((mp)->m_sb.sb_inodesize + \ | ||
444 | (mp)->m_sb.sb_inodesize + \ | ||
445 | XFS_DIROP_LOG_RES(mp) + \ | ||
446 | (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ | ||
447 | ((mp)->m_sb.sb_sectsize + \ | ||
448 | (mp)->m_sb.sb_sectsize + \ | ||
449 | (mp)->m_sb.sb_sectsize + \ | ||
450 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
451 | (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | ||
452 | |||
453 | #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) | 330 | #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) |
454 | |||
455 | /* | ||
456 | * For removing a directory entry we can modify: | ||
457 | * the parent directory inode: inode size | ||
458 | * the removed inode: inode size | ||
459 | * the directory btree could join: (max depth + v2) * dir block size | ||
460 | * the directory bmap btree could join or split: (max depth + v2) * blocksize | ||
461 | * And the bmap_finish transaction can free the dir and bmap blocks giving: | ||
462 | * the agf for the ag in which the blocks live: 2 * sector size | ||
463 | * the agfl for the ag in which the blocks live: 2 * sector size | ||
464 | * the superblock for the free block count: sector size | ||
465 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
466 | */ | ||
467 | #define XFS_CALC_REMOVE_LOG_RES(mp) \ | ||
468 | (MAX( \ | ||
469 | ((mp)->m_sb.sb_inodesize + \ | ||
470 | (mp)->m_sb.sb_inodesize + \ | ||
471 | XFS_DIROP_LOG_RES(mp) + \ | ||
472 | (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ | ||
473 | ((2 * (mp)->m_sb.sb_sectsize) + \ | ||
474 | (2 * (mp)->m_sb.sb_sectsize) + \ | ||
475 | (mp)->m_sb.sb_sectsize + \ | ||
476 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | ||
477 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) | ||
478 | |||
479 | #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) | 331 | #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) |
480 | |||
481 | /* | ||
482 | * For symlink we can modify: | ||
483 | * the parent directory inode: inode size | ||
484 | * the new inode: inode size | ||
485 | * the inode btree entry: 1 block | ||
486 | * the directory btree: (max depth + v2) * dir block size | ||
487 | * the directory inode's bmap btree: (max depth + v2) * block size | ||
488 | * the blocks for the symlink: 1 kB | ||
489 | * Or in the first xact we allocate some inodes giving: | ||
490 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize | ||
491 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize | ||
492 | * the inode btree: max depth * blocksize | ||
493 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size | ||
494 | */ | ||
495 | #define XFS_CALC_SYMLINK_LOG_RES(mp) \ | ||
496 | (MAX( \ | ||
497 | ((mp)->m_sb.sb_inodesize + \ | ||
498 | (mp)->m_sb.sb_inodesize + \ | ||
499 | XFS_FSB_TO_B(mp, 1) + \ | ||
500 | XFS_DIROP_LOG_RES(mp) + \ | ||
501 | 1024 + \ | ||
502 | (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \ | ||
503 | (2 * (mp)->m_sb.sb_sectsize + \ | ||
504 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ | ||
505 | XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \ | ||
506 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
507 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ | ||
508 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | ||
509 | |||
510 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) | 332 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) |
511 | |||
512 | /* | ||
513 | * For create we can modify: | ||
514 | * the parent directory inode: inode size | ||
515 | * the new inode: inode size | ||
516 | * the inode btree entry: block size | ||
517 | * the superblock for the nlink flag: sector size | ||
518 | * the directory btree: (max depth + v2) * dir block size | ||
519 | * the directory inode's bmap btree: (max depth + v2) * block size | ||
520 | * Or in the first xact we allocate some inodes giving: | ||
521 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize | ||
522 | * the superblock for the nlink flag: sector size | ||
523 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize | ||
524 | * the inode btree: max depth * blocksize | ||
525 | * the allocation btrees: 2 trees * (max depth - 1) * block size | ||
526 | */ | ||
527 | #define XFS_CALC_CREATE_LOG_RES(mp) \ | ||
528 | (MAX( \ | ||
529 | ((mp)->m_sb.sb_inodesize + \ | ||
530 | (mp)->m_sb.sb_inodesize + \ | ||
531 | (mp)->m_sb.sb_sectsize + \ | ||
532 | XFS_FSB_TO_B(mp, 1) + \ | ||
533 | XFS_DIROP_LOG_RES(mp) + \ | ||
534 | (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \ | ||
535 | (3 * (mp)->m_sb.sb_sectsize + \ | ||
536 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ | ||
537 | XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \ | ||
538 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
539 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ | ||
540 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | ||
541 | |||
542 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) | 333 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) |
543 | |||
544 | /* | ||
545 | * Making a new directory is the same as creating a new file. | ||
546 | */ | ||
547 | #define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp) | ||
548 | |||
549 | #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) | 334 | #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) |
550 | |||
551 | /* | ||
552 | * In freeing an inode we can modify: | ||
553 | * the inode being freed: inode size | ||
554 | * the super block free inode counter: sector size | ||
555 | * the agi hash list and counters: sector size | ||
556 | * the inode btree entry: block size | ||
557 | * the on disk inode before ours in the agi hash list: inode cluster size | ||
558 | * the inode btree: max depth * blocksize | ||
559 | * the allocation btrees: 2 trees * (max depth - 1) * block size | ||
560 | */ | ||
561 | #define XFS_CALC_IFREE_LOG_RES(mp) \ | ||
562 | ((mp)->m_sb.sb_inodesize + \ | ||
563 | (mp)->m_sb.sb_sectsize + \ | ||
564 | (mp)->m_sb.sb_sectsize + \ | ||
565 | XFS_FSB_TO_B((mp), 1) + \ | ||
566 | MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ | ||
567 | (128 * 5) + \ | ||
568 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
569 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ | ||
570 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | ||
571 | |||
572 | |||
573 | #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) | 335 | #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) |
574 | |||
575 | /* | ||
576 | * When only changing the inode we log the inode and possibly the superblock | ||
577 | * We also add a bit of slop for the transaction stuff. | ||
578 | */ | ||
579 | #define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \ | ||
580 | (mp)->m_sb.sb_sectsize + 512) | ||
581 | |||
582 | #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) | 336 | #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) |
583 | |||
584 | /* | ||
585 | * Growing the data section of the filesystem. | ||
586 | * superblock | ||
587 | * agi and agf | ||
588 | * allocation btrees | ||
589 | */ | ||
590 | #define XFS_CALC_GROWDATA_LOG_RES(mp) \ | ||
591 | ((mp)->m_sb.sb_sectsize * 3 + \ | ||
592 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
593 | (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | ||
594 | |||
595 | #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) | 337 | #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) |
596 | |||
597 | /* | ||
598 | * Growing the rt section of the filesystem. | ||
599 | * In the first set of transactions (ALLOC) we allocate space to the | ||
600 | * bitmap or summary files. | ||
601 | * superblock: sector size | ||
602 | * agf of the ag from which the extent is allocated: sector size | ||
603 | * bmap btree for bitmap/summary inode: max depth * blocksize | ||
604 | * bitmap/summary inode: inode size | ||
605 | * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize | ||
606 | */ | ||
607 | #define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \ | ||
608 | (2 * (mp)->m_sb.sb_sectsize + \ | ||
609 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ | ||
610 | (mp)->m_sb.sb_inodesize + \ | ||
611 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
612 | (128 * \ | ||
613 | (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \ | ||
614 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | ||
615 | |||
616 | #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) | 338 | #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) |
617 | |||
618 | /* | ||
619 | * Growing the rt section of the filesystem. | ||
620 | * In the second set of transactions (ZERO) we zero the new metadata blocks. | ||
621 | * one bitmap/summary block: blocksize | ||
622 | */ | ||
623 | #define XFS_CALC_GROWRTZERO_LOG_RES(mp) \ | ||
624 | ((mp)->m_sb.sb_blocksize + 128) | ||
625 | |||
626 | #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) | 339 | #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) |
627 | |||
628 | /* | ||
629 | * Growing the rt section of the filesystem. | ||
630 | * In the third set of transactions (FREE) we update metadata without | ||
631 | * allocating any new blocks. | ||
632 | * superblock: sector size | ||
633 | * bitmap inode: inode size | ||
634 | * summary inode: inode size | ||
635 | * one bitmap block: blocksize | ||
636 | * summary blocks: new summary size | ||
637 | */ | ||
638 | #define XFS_CALC_GROWRTFREE_LOG_RES(mp) \ | ||
639 | ((mp)->m_sb.sb_sectsize + \ | ||
640 | 2 * (mp)->m_sb.sb_inodesize + \ | ||
641 | (mp)->m_sb.sb_blocksize + \ | ||
642 | (mp)->m_rsumsize + \ | ||
643 | (128 * 5)) | ||
644 | |||
645 | #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) | 340 | #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) |
646 | |||
647 | /* | ||
648 | * Logging the inode modification timestamp on a synchronous write. | ||
649 | * inode | ||
650 | */ | ||
651 | #define XFS_CALC_SWRITE_LOG_RES(mp) \ | ||
652 | ((mp)->m_sb.sb_inodesize + 128) | ||
653 | |||
654 | #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 341 | #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
655 | |||
656 | /* | 342 | /* |
657 | * Logging the inode timestamps on an fsync -- same as SWRITE | 343 | * Logging the inode timestamps on an fsync -- same as SWRITE |
658 | * as long as SWRITE logs the entire inode core | 344 | * as long as SWRITE logs the entire inode core |
659 | */ | 345 | */ |
660 | #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 346 | #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
661 | |||
662 | /* | ||
663 | * Logging the inode mode bits when writing a setuid/setgid file | ||
664 | * inode | ||
665 | */ | ||
666 | #define XFS_CALC_WRITEID_LOG_RES(mp) \ | ||
667 | ((mp)->m_sb.sb_inodesize + 128) | ||
668 | |||
669 | #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 347 | #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
670 | |||
671 | /* | ||
672 | * Converting the inode from non-attributed to attributed. | ||
673 | * the inode being converted: inode size | ||
674 | * agf block and superblock (for block allocation) | ||
675 | * the new block (directory sized) | ||
676 | * bmap blocks for the new directory block | ||
677 | * allocation btrees | ||
678 | */ | ||
679 | #define XFS_CALC_ADDAFORK_LOG_RES(mp) \ | ||
680 | ((mp)->m_sb.sb_inodesize + \ | ||
681 | (mp)->m_sb.sb_sectsize * 2 + \ | ||
682 | (mp)->m_dirblksize + \ | ||
683 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ | ||
684 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | ||
685 | (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ | ||
686 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | ||
687 | |||
688 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) | 348 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) |
689 | |||
690 | /* | ||
691 | * Removing the attribute fork of a file | ||
692 | * the inode being truncated: inode size | ||
693 | * the inode's bmap btree: max depth * block size | ||
694 | * And the bmap_finish transaction can free the blocks and bmap blocks: | ||
695 | * the agf for each of the ags: 4 * sector size | ||
696 | * the agfl for each of the ags: 4 * sector size | ||
697 | * the super block to reflect the freed blocks: sector size | ||
698 | * worst case split in allocation btrees per extent assuming 4 extents: | ||
699 | * 4 exts * 2 trees * (2 * max depth - 1) * block size | ||
700 | */ | ||
701 | #define XFS_CALC_ATTRINVAL_LOG_RES(mp) \ | ||
702 | (MAX( \ | ||
703 | ((mp)->m_sb.sb_inodesize + \ | ||
704 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ | ||
705 | (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \ | ||
706 | ((4 * (mp)->m_sb.sb_sectsize) + \ | ||
707 | (4 * (mp)->m_sb.sb_sectsize) + \ | ||
708 | (mp)->m_sb.sb_sectsize + \ | ||
709 | XFS_ALLOCFREE_LOG_RES(mp, 4) + \ | ||
710 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))))) | ||
711 | |||
712 | #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) | 349 | #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) |
713 | |||
714 | /* | ||
715 | * Setting an attribute. | ||
716 | * the inode getting the attribute | ||
717 | * the superblock for allocations | ||
718 | * the agfs extents are allocated from | ||
719 | * the attribute btree * max depth | ||
720 | * the inode allocation btree | ||
721 | * Since attribute transaction space is dependent on the size of the attribute, | ||
722 | * the calculation is done partially at mount time and partially at runtime. | ||
723 | */ | ||
724 | #define XFS_CALC_ATTRSET_LOG_RES(mp) \ | ||
725 | ((mp)->m_sb.sb_inodesize + \ | ||
726 | (mp)->m_sb.sb_sectsize + \ | ||
727 | XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ | ||
728 | (128 * (2 + XFS_DA_NODE_MAXDEPTH))) | ||
729 | |||
730 | #define XFS_ATTRSET_LOG_RES(mp, ext) \ | 350 | #define XFS_ATTRSET_LOG_RES(mp, ext) \ |
731 | ((mp)->m_reservations.tr_attrset + \ | 351 | ((mp)->m_reservations.tr_attrset + \ |
732 | (ext * (mp)->m_sb.sb_sectsize) + \ | 352 | (ext * (mp)->m_sb.sb_sectsize) + \ |
733 | (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ | 353 | (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ |
734 | (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) | 354 | (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) |
735 | |||
736 | /* | ||
737 | * Removing an attribute. | ||
738 | * the inode: inode size | ||
739 | * the attribute btree could join: max depth * block size | ||
740 | * the inode bmap btree could join or split: max depth * block size | ||
741 | * And the bmap_finish transaction can free the attr blocks freed giving: | ||
742 | * the agf for the ag in which the blocks live: 2 * sector size | ||
743 | * the agfl for the ag in which the blocks live: 2 * sector size | ||
744 | * the superblock for the free block count: sector size | ||
745 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | ||
746 | */ | ||
747 | #define XFS_CALC_ATTRRM_LOG_RES(mp) \ | ||
748 | (MAX( \ | ||
749 | ((mp)->m_sb.sb_inodesize + \ | ||
750 | XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ | ||
751 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ | ||
752 | (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ | ||
753 | ((2 * (mp)->m_sb.sb_sectsize) + \ | ||
754 | (2 * (mp)->m_sb.sb_sectsize) + \ | ||
755 | (mp)->m_sb.sb_sectsize + \ | ||
756 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | ||
757 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) | ||
758 | |||
759 | #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) | 355 | #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) |
760 | |||
761 | /* | ||
762 | * Clearing a bad agino number in an agi hash bucket. | ||
763 | */ | ||
764 | #define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \ | ||
765 | ((mp)->m_sb.sb_sectsize + 128) | ||
766 | |||
767 | #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) | 356 | #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) |
768 | 357 | ||
769 | 358 | ||
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 9d376be0ea38..a06bd62504fc 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -267,7 +267,7 @@ xfs_setattr( | |||
267 | if (code) { | 267 | if (code) { |
268 | ASSERT(tp == NULL); | 268 | ASSERT(tp == NULL); |
269 | lock_flags &= ~XFS_ILOCK_EXCL; | 269 | lock_flags &= ~XFS_ILOCK_EXCL; |
270 | ASSERT(lock_flags == XFS_IOLOCK_EXCL); | 270 | ASSERT(lock_flags == XFS_IOLOCK_EXCL || !need_iolock); |
271 | goto error_return; | 271 | goto error_return; |
272 | } | 272 | } |
273 | tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); | 273 | tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); |