From e795cd4b3bdc0856222a2a3d8a6af0537ff45b18 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 May 2013 14:04:11 +0200 Subject: [PATCH] --- yaml --- r: 376491 b: refs/heads/master c: 5d477b6079619910dab882fa229cce1f14f86cf8 h: refs/heads/master i: 376489: 7a6650761a8a08496c9010a168ac85d5b0d8949b 376487: 7b727e288e84d265d930dd2d3ab08a74e2238d30 v: v3 --- [refs] | 2 +- trunk/arch/arm64/kernel/arm64ksyms.c | 1 - trunk/arch/arm64/kernel/entry.S | 10 - trunk/arch/arm64/kernel/traps.c | 17 +- trunk/arch/arm64/mm/fault.c | 3 +- trunk/drivers/acpi/apei/cper.c | 18 + trunk/drivers/acpi/apei/ghes.c | 4 +- trunk/drivers/pci/pcie/aer/aerdrv_core.c | 5 +- trunk/drivers/pci/pcie/aer/aerdrv_errprint.c | 4 +- trunk/fs/nfs/nfs4proc.c | 2 +- trunk/fs/nfs/super.c | 2 - trunk/fs/pnode.c | 3 +- trunk/fs/reiserfs/dir.c | 2 - trunk/fs/reiserfs/inode.c | 9 +- trunk/fs/reiserfs/xattr.c | 14 +- trunk/fs/reiserfs/xattr_acl.c | 3 - trunk/fs/xfs/xfs_attr_leaf.c | 71 ++-- trunk/fs/xfs/xfs_attr_remote.c | 408 ++++++++----------- trunk/fs/xfs/xfs_attr_remote.h | 10 - trunk/fs/xfs/xfs_buf.c | 1 - trunk/fs/xfs/xfs_buf_item.c | 7 +- trunk/fs/xfs/xfs_dfrag.c | 8 - trunk/fs/xfs/xfs_dir2_format.h | 1 - trunk/fs/xfs/xfs_dir2_node.c | 13 +- trunk/fs/xfs/xfs_fs.h | 1 - trunk/fs/xfs/xfs_fsops.c | 4 +- trunk/fs/xfs/xfs_iops.c | 47 +-- trunk/fs/xfs/xfs_log_recover.c | 11 - trunk/fs/xfs/xfs_qm_syscalls.c | 40 +- trunk/fs/xfs/xfs_symlink.c | 20 +- trunk/include/linux/aer.h | 5 +- 31 files changed, 280 insertions(+), 466 deletions(-) diff --git a/[refs] b/[refs] index 3e8656810a38..f302011b59bd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f8cb27916ae256ef3b4e2ecca7262109dcfdd083 +refs/heads/master: 5d477b6079619910dab882fa229cce1f14f86cf8 diff --git a/trunk/arch/arm64/kernel/arm64ksyms.c b/trunk/arch/arm64/kernel/arm64ksyms.c index 41b4f626d554..7df1aad29b67 100644 --- a/trunk/arch/arm64/kernel/arm64ksyms.c +++ b/trunk/arch/arm64/kernel/arm64ksyms.c @@ -34,7 +34,6 @@ EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(copy_page); -EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__copy_to_user); diff --git a/trunk/arch/arm64/kernel/entry.S b/trunk/arch/arm64/kernel/entry.S index 1d1314280a03..c7e047049f2c 100644 --- a/trunk/arch/arm64/kernel/entry.S +++ b/trunk/arch/arm64/kernel/entry.S @@ -390,16 +390,6 @@ el0_sync_compat: b.eq el0_fpsimd_exc cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0 b.eq el0_undef - cmp x24, #ESR_EL1_EC_CP15_32 // CP15 MRC/MCR trap - b.eq el0_undef - cmp x24, #ESR_EL1_EC_CP15_64 // CP15 MRRC/MCRR trap - b.eq el0_undef - cmp x24, #ESR_EL1_EC_CP14_MR // CP14 MRC/MCR trap - b.eq el0_undef - cmp x24, #ESR_EL1_EC_CP14_LS // CP14 LDC/STC trap - b.eq el0_undef - cmp x24, #ESR_EL1_EC_CP14_64 // CP14 MRRC/MCRR trap - b.eq el0_undef cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0 b.ge el0_dbg b el0_inv diff --git a/trunk/arch/arm64/kernel/traps.c b/trunk/arch/arm64/kernel/traps.c index f30852d28590..61d7dd29f756 100644 --- a/trunk/arch/arm64/kernel/traps.c +++ b/trunk/arch/arm64/kernel/traps.c @@ -267,8 +267,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) return; #endif - if (show_unhandled_signals && unhandled_signal(current, SIGILL) && - printk_ratelimit()) { + if (show_unhandled_signals) { pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); dump_instr(KERN_INFO, regs); @@ -295,7 +294,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) } #endif - if (show_unhandled_signals && printk_ratelimit()) { + if (show_unhandled_signals) { pr_info("%s[%d]: syscall %d\n", current->comm, task_pid_nr(current), (int)regs->syscallno); dump_instr("", regs); @@ -311,20 +310,14 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) { - siginfo_t info; - void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); - __show_regs(regs); - - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_code = ILL_ILLOPC; - info.si_addr = pc; - arm64_notify_die("Oops - bad mode", regs, &info, 0); + die("Oops - bad mode", regs, 0); + local_irq_disable(); + panic("bad mode"); } void __pte_error(const char *file, int line, unsigned long val) diff --git a/trunk/arch/arm64/mm/fault.c b/trunk/arch/arm64/mm/fault.c index 1426468b77f3..98af6e760cce 100644 --- a/trunk/arch/arm64/mm/fault.c +++ b/trunk/arch/arm64/mm/fault.c @@ -113,8 +113,7 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, { struct siginfo si; - if (show_unhandled_signals && unhandled_signal(tsk, sig) && - printk_ratelimit()) { + if (show_unhandled_signals) { pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", tsk->comm, task_pid_nr(tsk), fault_name(esr), sig, addr, esr); diff --git a/trunk/drivers/acpi/apei/cper.c b/trunk/drivers/acpi/apei/cper.c index 33dc6a004802..fefc2ca7cc3e 100644 --- a/trunk/drivers/acpi/apei/cper.c +++ b/trunk/drivers/acpi/apei/cper.c @@ -250,6 +250,10 @@ static const char *cper_pcie_port_type_strs[] = { static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, const struct acpi_hest_generic_data *gdata) { +#ifdef CONFIG_ACPI_APEI_PCIEAER + struct pci_dev *dev; +#endif + if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? @@ -281,6 +285,20 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, printk( "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", pfx, pcie->bridge.secondary_status, pcie->bridge.control); +#ifdef CONFIG_ACPI_APEI_PCIEAER + dev = pci_get_domain_bus_and_slot(pcie->device_id.segment, + pcie->device_id.bus, pcie->device_id.function); + if (!dev) { + pr_err("PCI AER Cannot get PCI device %04x:%02x:%02x.%d\n", + pcie->device_id.segment, pcie->device_id.bus, + pcie->device_id.slot, pcie->device_id.function); + return; + } + if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) + cper_print_aer(pfx, dev, gdata->error_severity, + (struct aer_capability_regs *) pcie->aer_info); + pci_dev_put(dev); +#endif } static const char *apei_estatus_section_flag_strs[] = { diff --git a/trunk/drivers/acpi/apei/ghes.c b/trunk/drivers/acpi/apei/ghes.c index 403baf4dffc1..d668a8ae602b 100644 --- a/trunk/drivers/acpi/apei/ghes.c +++ b/trunk/drivers/acpi/apei/ghes.c @@ -454,9 +454,7 @@ static void ghes_do_proc(struct ghes *ghes, aer_severity = cper_severity_to_aer(sev); aer_recover_queue(pcie_err->device_id.segment, pcie_err->device_id.bus, - devfn, aer_severity, - (struct aer_capability_regs *) - pcie_err->aer_info); + devfn, aer_severity); } } diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 0f4554e48cc5..8ec8b4f48560 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -580,7 +580,6 @@ struct aer_recover_entry u8 devfn; u16 domain; int severity; - struct aer_capability_regs *regs; }; static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry, @@ -594,7 +593,7 @@ static DEFINE_SPINLOCK(aer_recover_ring_lock); static DECLARE_WORK(aer_recover_work, aer_recover_work_func); void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity, struct aer_capability_regs *aer_regs) + int severity) { unsigned long flags; struct aer_recover_entry entry = { @@ -602,7 +601,6 @@ void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, .devfn = devfn, .domain = domain, .severity = severity, - .regs = aer_regs, }; spin_lock_irqsave(&aer_recover_ring_lock, flags); @@ -629,7 +627,6 @@ static void aer_recover_work_func(struct work_struct *work) PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn)); continue; } - cper_print_aer(pdev, entry.severity, entry.regs); do_recovery(pdev, entry.severity); pci_dev_put(pdev); } diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c b/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c index 2c7c9f5f592c..5ab14251839d 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c @@ -220,7 +220,7 @@ int cper_severity_to_aer(int cper_severity) } EXPORT_SYMBOL_GPL(cper_severity_to_aer); -void cper_print_aer(struct pci_dev *dev, int cper_severity, +void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, struct aer_capability_regs *aer) { int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; @@ -244,7 +244,7 @@ void cper_print_aer(struct pci_dev *dev, int cper_severity, agent = AER_GET_AGENT(aer_severity, status); dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask); - cper_print_bits("", status, status_strs, status_strs_size); + cper_print_bits(prefix, status, status_strs, status_strs_size); dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n", aer_error_layer[layer], aer_agent_string[agent]); if (aer_severity != AER_CORRECTABLE) diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index d7ba5616989c..4e2fe714d5c2 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -1078,7 +1078,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) struct nfs4_state *state = opendata->state; struct nfs_inode *nfsi = NFS_I(state->inode); struct nfs_delegation *delegation; - int open_mode = opendata->o_arg.open_flags; + int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC); fmode_t fmode = opendata->o_arg.fmode; nfs4_stateid stateid; int ret = -EAGAIN; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 2d7525fbcf25..a366107a7331 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -1942,7 +1942,6 @@ static int nfs23_validate_mount_data(void *options, args->namlen = data->namlen; args->bsize = data->bsize; - args->auth_flavors[0] = RPC_AUTH_UNIX; if (data->flags & NFS_MOUNT_SECFLAVOUR) args->auth_flavors[0] = data->pseudoflavor; if (!args->nfs_server.hostname) @@ -2638,7 +2637,6 @@ static int nfs4_validate_mount_data(void *options, goto out_no_address; args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); - args->auth_flavors[0] = RPC_AUTH_UNIX; if (data->auth_flavourlen) { if (data->auth_flavourlen > 1) goto out_inval_auth; diff --git a/trunk/fs/pnode.c b/trunk/fs/pnode.c index 3d2a7141b87a..9af0df15256e 100644 --- a/trunk/fs/pnode.c +++ b/trunk/fs/pnode.c @@ -83,7 +83,8 @@ static int do_make_slave(struct mount *mnt) if (peer_mnt == mnt) peer_mnt = NULL; } - if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share)) + if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) && + list_empty(&mnt->mnt_share)) mnt_release_group_id(mnt); list_del_init(&mnt->mnt_share); diff --git a/trunk/fs/reiserfs/dir.c b/trunk/fs/reiserfs/dir.c index 6c2d136561cb..66c53b642a88 100644 --- a/trunk/fs/reiserfs/dir.c +++ b/trunk/fs/reiserfs/dir.c @@ -204,8 +204,6 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, next_pos = deh_offset(deh) + 1; if (item_moved(&tmp_ih, &path_to_entry)) { - set_cpu_key_k_offset(&pos_key, - next_pos); goto research; } } /* for */ diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index f844533792ee..77d6d47abc83 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -1811,16 +1811,11 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); - - reiserfs_write_unlock(inode->i_sb); - err = insert_inode_locked4(inode, args.objectid, - reiserfs_find_actor, &args); - reiserfs_write_lock(inode->i_sb); - if (err) { + if (insert_inode_locked4(inode, args.objectid, + reiserfs_find_actor, &args) < 0) { err = -EINVAL; goto out_bad_inode; } - if (old_format_only(sb)) /* not a perfect generation count, as object ids can be reused, but ** this is as good as reiserfs can do right now. diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index 821bcf70e467..4cce1d9552fb 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -318,19 +318,7 @@ static int delete_one_xattr(struct dentry *dentry, void *data) static int chown_one_xattr(struct dentry *dentry, void *data) { struct iattr *attrs = data; - int ia_valid = attrs->ia_valid; - int err; - - /* - * We only want the ownership bits. Otherwise, we'll do - * things like change a directory to a regular file if - * ATTR_MODE is set. - */ - attrs->ia_valid &= (ATTR_UID|ATTR_GID); - err = reiserfs_setattr(dentry, attrs); - attrs->ia_valid = ia_valid; - - return err; + return reiserfs_setattr(dentry, attrs); } /* No i_mutex, but the inode is unconnected. */ diff --git a/trunk/fs/reiserfs/xattr_acl.c b/trunk/fs/reiserfs/xattr_acl.c index 6c8767fdfc6a..d7c01ef64eda 100644 --- a/trunk/fs/reiserfs/xattr_acl.c +++ b/trunk/fs/reiserfs/xattr_acl.c @@ -443,9 +443,6 @@ int reiserfs_acl_chmod(struct inode *inode) int depth; int error; - if (IS_PRIVATE(inode)) - return 0; - if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; diff --git a/trunk/fs/xfs/xfs_attr_leaf.c b/trunk/fs/xfs/xfs_attr_leaf.c index d788302e506a..0bce1b348580 100644 --- a/trunk/fs/xfs/xfs_attr_leaf.c +++ b/trunk/fs/xfs/xfs_attr_leaf.c @@ -1412,7 +1412,7 @@ xfs_attr3_leaf_add_work( name_rmt->valuelen = 0; name_rmt->valueblk = 0; args->rmtblkno = 1; - args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); + args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); } xfs_trans_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), @@ -1445,12 +1445,11 @@ xfs_attr3_leaf_add_work( STATIC void xfs_attr3_leaf_compact( struct xfs_da_args *args, - struct xfs_attr3_icleaf_hdr *ichdr_dst, + struct xfs_attr3_icleaf_hdr *ichdr_d, struct xfs_buf *bp) { - struct xfs_attr_leafblock *leaf_src; - struct xfs_attr_leafblock *leaf_dst; - struct xfs_attr3_icleaf_hdr ichdr_src; + xfs_attr_leafblock_t *leaf_s, *leaf_d; + struct xfs_attr3_icleaf_hdr ichdr_s; struct xfs_trans *trans = args->trans; struct xfs_mount *mp = trans->t_mountp; char *tmpbuffer; @@ -1458,38 +1457,29 @@ xfs_attr3_leaf_compact( trace_xfs_attr_leaf_compact(args); tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); + ASSERT(tmpbuffer != NULL); memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); memset(bp->b_addr, 0, XFS_LBSIZE(mp)); - leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; - leaf_dst = bp->b_addr; /* - * Copy the on-disk header back into the destination buffer to ensure - * all the information in the header that is not part of the incore - * header structure is preserved. + * Copy basic information */ - memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src)); - - /* Initialise the incore headers */ - ichdr_src = *ichdr_dst; /* struct copy */ - ichdr_dst->firstused = XFS_LBSIZE(mp); - ichdr_dst->usedbytes = 0; - ichdr_dst->count = 0; - ichdr_dst->holes = 0; - ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src); - ichdr_dst->freemap[0].size = ichdr_dst->firstused - - ichdr_dst->freemap[0].base; - - - /* write the header back to initialise the underlying buffer */ - xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst); + leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; + leaf_d = bp->b_addr; + ichdr_s = *ichdr_d; /* struct copy */ + ichdr_d->firstused = XFS_LBSIZE(mp); + ichdr_d->usedbytes = 0; + ichdr_d->count = 0; + ichdr_d->holes = 0; + ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_s); + ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base; /* * Copy all entry's in the same (sorted) order, * but allocate name/value pairs packed and in sequence. */ - xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, - ichdr_src.count, mp); + xfs_attr3_leaf_moveents(leaf_s, &ichdr_s, 0, leaf_d, ichdr_d, 0, + ichdr_s.count, mp); /* * this logs the entire buffer, but the caller must write the header * back to the buffer when it is finished modifying it. @@ -2191,24 +2181,14 @@ xfs_attr3_leaf_unbalance( struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr3_icleaf_hdr tmphdr; - tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP); - - /* - * Copy the header into the temp leaf so that all the stuff - * not in the incore header is present and gets copied back in - * once we've moved all the entries. - */ - memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf)); - + tmp_leaf = kmem_alloc(state->blocksize, KM_SLEEP); + memset(tmp_leaf, 0, state->blocksize); memset(&tmphdr, 0, sizeof(tmphdr)); + tmphdr.magic = savehdr.magic; tmphdr.forw = savehdr.forw; tmphdr.back = savehdr.back; tmphdr.firstused = state->blocksize; - - /* write the header to the temp buffer to initialise it */ - xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); - if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, drop_blk->bp, &drophdr)) { xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, @@ -2354,9 +2334,8 @@ xfs_attr3_leaf_lookup_int( args->index = probe; args->valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); - args->rmtblkcnt = xfs_attr3_rmt_blocks( - args->dp->i_mount, - args->valuelen); + args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, + args->valuelen); return XFS_ERROR(EEXIST); } } @@ -2407,8 +2386,7 @@ xfs_attr3_leaf_getvalue( ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); valuelen = be32_to_cpu(name_rmt->valuelen); args->rmtblkno = be32_to_cpu(name_rmt->valueblk); - args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, - valuelen); + args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); if (args->flags & ATTR_KERNOVAL) { args->valuelen = valuelen; return 0; @@ -2734,8 +2712,7 @@ xfs_attr3_leaf_list_int( args.valuelen = valuelen; args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); args.rmtblkno = be32_to_cpu(name_rmt->valueblk); - args.rmtblkcnt = xfs_attr3_rmt_blocks( - args.dp->i_mount, valuelen); + args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); retval = xfs_attr_rmtval_get(&args); if (retval) return retval; diff --git a/trunk/fs/xfs/xfs_attr_remote.c b/trunk/fs/xfs/xfs_attr_remote.c index ef6b0c124528..dee84466dcc9 100644 --- a/trunk/fs/xfs/xfs_attr_remote.c +++ b/trunk/fs/xfs/xfs_attr_remote.c @@ -47,55 +47,22 @@ * Each contiguous block has a header, so it is not just a simple attribute * length to FSB conversion. */ -int +static int xfs_attr3_rmt_blocks( struct xfs_mount *mp, int attrlen) { - if (xfs_sb_version_hascrc(&mp->m_sb)) { - int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, mp->m_sb.sb_blocksize); - return (attrlen + buflen - 1) / buflen; - } - return XFS_B_TO_FSB(mp, attrlen); -} - -/* - * Checking of the remote attribute header is split into two parts. The verifier - * does CRC, location and bounds checking, the unpacking function checks the - * attribute parameters and owner. - */ -static bool -xfs_attr3_rmt_hdr_ok( - struct xfs_mount *mp, - void *ptr, - xfs_ino_t ino, - uint32_t offset, - uint32_t size, - xfs_daddr_t bno) -{ - struct xfs_attr3_rmt_hdr *rmt = ptr; - - if (bno != be64_to_cpu(rmt->rm_blkno)) - return false; - if (offset != be32_to_cpu(rmt->rm_offset)) - return false; - if (size != be32_to_cpu(rmt->rm_bytes)) - return false; - if (ino != be64_to_cpu(rmt->rm_owner)) - return false; - - /* ok */ - return true; + int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, + mp->m_sb.sb_blocksize); + return (attrlen + buflen - 1) / buflen; } static bool xfs_attr3_rmt_verify( - struct xfs_mount *mp, - void *ptr, - int fsbsize, - xfs_daddr_t bno) + struct xfs_buf *bp) { - struct xfs_attr3_rmt_hdr *rmt = ptr; + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; if (!xfs_sb_version_hascrc(&mp->m_sb)) return false; @@ -103,9 +70,7 @@ xfs_attr3_rmt_verify( return false; if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_uuid)) return false; - if (be64_to_cpu(rmt->rm_blkno) != bno) - return false; - if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt)) + if (bp->b_bn != be64_to_cpu(rmt->rm_blkno)) return false; if (be32_to_cpu(rmt->rm_offset) + be32_to_cpu(rmt->rm_bytes) >= XATTR_SIZE_MAX) @@ -121,40 +86,17 @@ xfs_attr3_rmt_read_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - char *ptr; - int len; - bool corrupt = false; - xfs_daddr_t bno; /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) return; - ptr = bp->b_addr; - bno = bp->b_bn; - len = BBTOB(bp->b_length); - ASSERT(len >= XFS_LBSIZE(mp)); - - while (len > 0) { - if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), - XFS_ATTR3_RMT_CRC_OFF)) { - corrupt = true; - break; - } - if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { - corrupt = true; - break; - } - len -= XFS_LBSIZE(mp); - ptr += XFS_LBSIZE(mp); - bno += mp->m_bsize; - } - - if (corrupt) { + if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), + XFS_ATTR3_RMT_CRC_OFF) || + !xfs_attr3_rmt_verify(bp)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); xfs_buf_ioerror(bp, EFSCORRUPTED); - } else - ASSERT(len == 0); + } } static void @@ -163,39 +105,23 @@ xfs_attr3_rmt_write_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_buf_log_item *bip = bp->b_fspriv; - char *ptr; - int len; - xfs_daddr_t bno; /* no verification of non-crc buffers */ if (!xfs_sb_version_hascrc(&mp->m_sb)) return; - ptr = bp->b_addr; - bno = bp->b_bn; - len = BBTOB(bp->b_length); - ASSERT(len >= XFS_LBSIZE(mp)); - - while (len > 0) { - if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { - XFS_CORRUPTION_ERROR(__func__, - XFS_ERRLEVEL_LOW, mp, bp->b_addr); - xfs_buf_ioerror(bp, EFSCORRUPTED); - return; - } - if (bip) { - struct xfs_attr3_rmt_hdr *rmt; - - rmt = (struct xfs_attr3_rmt_hdr *)ptr; - rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); - } - xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF); + if (!xfs_attr3_rmt_verify(bp)) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); + xfs_buf_ioerror(bp, EFSCORRUPTED); + return; + } - len -= XFS_LBSIZE(mp); - ptr += XFS_LBSIZE(mp); - bno += mp->m_bsize; + if (bip) { + struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; + rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); } - ASSERT(len == 0); + xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), + XFS_ATTR3_RMT_CRC_OFF); } const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { @@ -203,16 +129,15 @@ const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { .verify_write = xfs_attr3_rmt_write_verify, }; -STATIC int +static int xfs_attr3_rmt_hdr_set( struct xfs_mount *mp, - void *ptr, xfs_ino_t ino, uint32_t offset, uint32_t size, - xfs_daddr_t bno) + struct xfs_buf *bp) { - struct xfs_attr3_rmt_hdr *rmt = ptr; + struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; if (!xfs_sb_version_hascrc(&mp->m_sb)) return 0; @@ -222,107 +147,36 @@ xfs_attr3_rmt_hdr_set( rmt->rm_bytes = cpu_to_be32(size); uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_uuid); rmt->rm_owner = cpu_to_be64(ino); - rmt->rm_blkno = cpu_to_be64(bno); + rmt->rm_blkno = cpu_to_be64(bp->b_bn); + bp->b_ops = &xfs_attr3_rmt_buf_ops; return sizeof(struct xfs_attr3_rmt_hdr); } /* - * Helper functions to copy attribute data in and out of the one disk extents + * Checking of the remote attribute header is split into two parts. the verifier + * does CRC, location and bounds checking, the unpacking function checks the + * attribute parameters and owner. */ -STATIC int -xfs_attr_rmtval_copyout( - struct xfs_mount *mp, - struct xfs_buf *bp, - xfs_ino_t ino, - int *offset, - int *valuelen, - char **dst) -{ - char *src = bp->b_addr; - xfs_daddr_t bno = bp->b_bn; - int len = BBTOB(bp->b_length); - - ASSERT(len >= XFS_LBSIZE(mp)); - - while (len > 0 && *valuelen > 0) { - int hdr_size = 0; - int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); - - byte_cnt = min_t(int, *valuelen, byte_cnt); - - if (xfs_sb_version_hascrc(&mp->m_sb)) { - if (!xfs_attr3_rmt_hdr_ok(mp, src, ino, *offset, - byte_cnt, bno)) { - xfs_alert(mp, -"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)", - bno, *offset, byte_cnt, ino); - return EFSCORRUPTED; - } - hdr_size = sizeof(struct xfs_attr3_rmt_hdr); - } - - memcpy(*dst, src + hdr_size, byte_cnt); - - /* roll buffer forwards */ - len -= XFS_LBSIZE(mp); - src += XFS_LBSIZE(mp); - bno += mp->m_bsize; - - /* roll attribute data forwards */ - *valuelen -= byte_cnt; - *dst += byte_cnt; - *offset += byte_cnt; - } - return 0; -} - -STATIC void -xfs_attr_rmtval_copyin( - struct xfs_mount *mp, - struct xfs_buf *bp, - xfs_ino_t ino, - int *offset, - int *valuelen, - char **src) +static bool +xfs_attr3_rmt_hdr_ok( + struct xfs_mount *mp, + xfs_ino_t ino, + uint32_t offset, + uint32_t size, + struct xfs_buf *bp) { - char *dst = bp->b_addr; - xfs_daddr_t bno = bp->b_bn; - int len = BBTOB(bp->b_length); - - ASSERT(len >= XFS_LBSIZE(mp)); - - while (len > 0 && *valuelen > 0) { - int hdr_size; - int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); - - byte_cnt = min(*valuelen, byte_cnt); - hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, - byte_cnt, bno); + struct xfs_attr3_rmt_hdr *rmt = bp->b_addr; - memcpy(dst + hdr_size, *src, byte_cnt); - - /* - * If this is the last block, zero the remainder of it. - * Check that we are actually the last block, too. - */ - if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) { - ASSERT(*valuelen - byte_cnt == 0); - ASSERT(len == XFS_LBSIZE(mp)); - memset(dst + hdr_size + byte_cnt, 0, - XFS_LBSIZE(mp) - hdr_size - byte_cnt); - } - - /* roll buffer forwards */ - len -= XFS_LBSIZE(mp); - dst += XFS_LBSIZE(mp); - bno += mp->m_bsize; + if (offset != be32_to_cpu(rmt->rm_offset)) + return false; + if (size != be32_to_cpu(rmt->rm_bytes)) + return false; + if (ino != be64_to_cpu(rmt->rm_owner)) + return false; - /* roll attribute data forwards */ - *valuelen -= byte_cnt; - *src += byte_cnt; - *offset += byte_cnt; - } + /* ok */ + return true; } /* @@ -336,12 +190,13 @@ xfs_attr_rmtval_get( struct xfs_bmbt_irec map[ATTR_RMTVALUE_MAPSIZE]; struct xfs_mount *mp = args->dp->i_mount; struct xfs_buf *bp; + xfs_daddr_t dblkno; xfs_dablk_t lblkno = args->rmtblkno; - char *dst = args->value; + void *dst = args->value; int valuelen = args->valuelen; int nmap; int error; - int blkcnt = args->rmtblkcnt; + int blkcnt; int i; int offset = 0; @@ -352,36 +207,52 @@ xfs_attr_rmtval_get( while (valuelen > 0) { nmap = ATTR_RMTVALUE_MAPSIZE; error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, - blkcnt, map, &nmap, + args->rmtblkcnt, map, &nmap, XFS_BMAPI_ATTRFORK); if (error) return error; ASSERT(nmap >= 1); for (i = 0; (i < nmap) && (valuelen > 0); i++) { - xfs_daddr_t dblkno; - int dblkcnt; + int byte_cnt; + char *src; ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) && (map[i].br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); - dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); + blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, - dblkno, dblkcnt, 0, &bp, + dblkno, blkcnt, 0, &bp, &xfs_attr3_rmt_buf_ops); if (error) return error; - error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino, - &offset, &valuelen, - &dst); + byte_cnt = min_t(int, valuelen, BBTOB(bp->b_length)); + byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt); + + src = bp->b_addr; + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (!xfs_attr3_rmt_hdr_ok(mp, args->dp->i_ino, + offset, byte_cnt, bp)) { + xfs_alert(mp, +"remote attribute header does not match required off/len/owner (0x%x/Ox%x,0x%llx)", + offset, byte_cnt, args->dp->i_ino); + xfs_buf_relse(bp); + return EFSCORRUPTED; + + } + + src += sizeof(struct xfs_attr3_rmt_hdr); + } + + memcpy(dst, src, byte_cnt); xfs_buf_relse(bp); - if (error) - return error; - /* roll attribute extent map forwards */ + offset += byte_cnt; + dst += byte_cnt; + valuelen -= byte_cnt; + lblkno += map[i].br_blockcount; - blkcnt -= map[i].br_blockcount; } } ASSERT(valuelen == 0); @@ -399,13 +270,17 @@ xfs_attr_rmtval_set( struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; struct xfs_bmbt_irec map; + struct xfs_buf *bp; + xfs_daddr_t dblkno; xfs_dablk_t lblkno; xfs_fileoff_t lfileoff = 0; - char *src = args->value; + void *src = args->value; int blkcnt; int valuelen; int nmap; int error; + int hdrcnt = 0; + bool crcs = xfs_sb_version_hascrc(&mp->m_sb); int offset = 0; trace_xfs_attr_rmtval_set(args); @@ -414,14 +289,24 @@ xfs_attr_rmtval_set( * Find a "hole" in the attribute address space large enough for * us to drop the new attribute's value into. Because CRC enable * attributes have headers, we can't just do a straight byte to FSB - * conversion and have to take the header space into account. + * conversion. We calculate the worst case block count in this case + * and we may not need that many, so we have to handle this when + * allocating the blocks below. */ - blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); + if (!crcs) + blkcnt = XFS_B_TO_FSB(mp, args->valuelen); + else + blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); + error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, XFS_ATTR_FORK); if (error) return error; + /* Start with the attribute data. We'll allocate the rest afterwards. */ + if (crcs) + blkcnt = XFS_B_TO_FSB(mp, args->valuelen); + args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; args->rmtblkcnt = blkcnt; @@ -464,6 +349,26 @@ xfs_attr_rmtval_set( (map.br_startblock != HOLESTARTBLOCK)); lblkno += map.br_blockcount; blkcnt -= map.br_blockcount; + hdrcnt++; + + /* + * If we have enough blocks for the attribute data, calculate + * how many extra blocks we need for headers. We might run + * through this multiple times in the case that the additional + * headers in the blocks needed for the data fragments spills + * into requiring more blocks. e.g. for 512 byte blocks, we'll + * spill for another block every 9 headers we require in this + * loop. + */ + if (crcs && blkcnt == 0) { + int total_len; + + total_len = args->valuelen + + hdrcnt * sizeof(struct xfs_attr3_rmt_hdr); + blkcnt = XFS_B_TO_FSB(mp, total_len); + blkcnt -= args->rmtblkcnt; + args->rmtblkcnt += blkcnt; + } /* * Start the next trans in the chain. @@ -480,19 +385,18 @@ xfs_attr_rmtval_set( * the INCOMPLETE flag. */ lblkno = args->rmtblkno; - blkcnt = args->rmtblkcnt; valuelen = args->valuelen; while (valuelen > 0) { - struct xfs_buf *bp; - xfs_daddr_t dblkno; - int dblkcnt; - - ASSERT(blkcnt > 0); + int byte_cnt; + char *buf; + /* + * Try to remember where we decided to put the value. + */ xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, - blkcnt, &map, &nmap, + args->rmtblkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK); if (error) return(error); @@ -501,27 +405,41 @@ xfs_attr_rmtval_set( (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); - bp = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt, 0); + bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 0); if (!bp) return ENOMEM; bp->b_ops = &xfs_attr3_rmt_buf_ops; - xfs_attr_rmtval_copyin(mp, bp, args->dp->i_ino, &offset, - &valuelen, &src); + byte_cnt = BBTOB(bp->b_length); + byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt); + if (valuelen < byte_cnt) + byte_cnt = valuelen; + + buf = bp->b_addr; + buf += xfs_attr3_rmt_hdr_set(mp, dp->i_ino, offset, + byte_cnt, bp); + memcpy(buf, src, byte_cnt); + + if (byte_cnt < BBTOB(bp->b_length)) + xfs_buf_zero(bp, byte_cnt, + BBTOB(bp->b_length) - byte_cnt); error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */ xfs_buf_relse(bp); if (error) return error; + src += byte_cnt; + valuelen -= byte_cnt; + offset += byte_cnt; + hdrcnt--; - /* roll attribute extent map forwards */ lblkno += map.br_blockcount; - blkcnt -= map.br_blockcount; } ASSERT(valuelen == 0); + ASSERT(hdrcnt == 0); return 0; } @@ -530,40 +448,33 @@ xfs_attr_rmtval_set( * out-of-line buffer that it is stored on. */ int -xfs_attr_rmtval_remove( - struct xfs_da_args *args) +xfs_attr_rmtval_remove(xfs_da_args_t *args) { - struct xfs_mount *mp = args->dp->i_mount; - xfs_dablk_t lblkno; - int blkcnt; - int error; - int done; + xfs_mount_t *mp; + xfs_bmbt_irec_t map; + xfs_buf_t *bp; + xfs_daddr_t dblkno; + xfs_dablk_t lblkno; + int valuelen, blkcnt, nmap, error, done, committed; trace_xfs_attr_rmtval_remove(args); + mp = args->dp->i_mount; + /* - * Roll through the "value", invalidating the attribute value's blocks. - * Note that args->rmtblkcnt is the minimum number of data blocks we'll - * see for a CRC enabled remote attribute. Each extent will have a - * header, and so we may have more blocks than we realise here. If we - * fail to map the blocks correctly, we'll have problems with the buffer - * lookups. + * Roll through the "value", invalidating the attribute value's + * blocks. */ lblkno = args->rmtblkno; - blkcnt = args->rmtblkcnt; - while (blkcnt > 0) { - struct xfs_bmbt_irec map; - struct xfs_buf *bp; - xfs_daddr_t dblkno; - int dblkcnt; - int nmap; - + valuelen = args->rmtblkcnt; + while (valuelen > 0) { /* * Try to remember where we decided to put the value. */ nmap = 1; error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, - blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK); + args->rmtblkcnt, &map, &nmap, + XFS_BMAPI_ATTRFORK); if (error) return(error); ASSERT(nmap == 1); @@ -571,20 +482,21 @@ xfs_attr_rmtval_remove( (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); /* * If the "remote" value is in the cache, remove it. */ - bp = xfs_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK); + bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK); if (bp) { xfs_buf_stale(bp); xfs_buf_relse(bp); bp = NULL; } + valuelen -= map.br_blockcount; + lblkno += map.br_blockcount; - blkcnt -= map.br_blockcount; } /* @@ -594,8 +506,6 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - int committed; - xfs_bmap_init(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, diff --git a/trunk/fs/xfs/xfs_attr_remote.h b/trunk/fs/xfs/xfs_attr_remote.h index 92a8fd7977cc..c7cca60a062a 100644 --- a/trunk/fs/xfs/xfs_attr_remote.h +++ b/trunk/fs/xfs/xfs_attr_remote.h @@ -20,14 +20,6 @@ #define XFS_ATTR3_RMT_MAGIC 0x5841524d /* XARM */ -/* - * There is one of these headers per filesystem block in a remote attribute. - * This is done to ensure there is a 1:1 mapping between the attribute value - * length and the number of blocks needed to store the attribute. This makes the - * verification of a buffer a little more complex, but greatly simplifies the - * allocation, reading and writing of these attributes as we don't have to guess - * the number of blocks needed to store the attribute data. - */ struct xfs_attr3_rmt_hdr { __be32 rm_magic; __be32 rm_offset; @@ -47,8 +39,6 @@ struct xfs_attr3_rmt_hdr { extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; -int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen); - int xfs_attr_rmtval_get(struct xfs_da_args *args); int xfs_attr_rmtval_set(struct xfs_da_args *args); int xfs_attr_rmtval_remove(struct xfs_da_args *args); diff --git a/trunk/fs/xfs/xfs_buf.c b/trunk/fs/xfs/xfs_buf.c index 1b2472a46e46..0d2554299688 100644 --- a/trunk/fs/xfs/xfs_buf.c +++ b/trunk/fs/xfs/xfs_buf.c @@ -513,7 +513,6 @@ _xfs_buf_find( xfs_alert(btp->bt_mount, "%s: Block out of range: block 0x%llx, EOFS 0x%llx ", __func__, blkno, eofs); - WARN_ON(1); return NULL; } diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index 4ec431777048..cf263476d6b4 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -262,7 +262,12 @@ xfs_buf_item_format_segment( vecp->i_addr = xfs_buf_offset(bp, buffer_offset); vecp->i_len = nbits * XFS_BLF_CHUNK; vecp->i_type = XLOG_REG_TYPE_BCHUNK; - nvecs++; +/* + * You would think we need to bump the nvecs here too, but we do not + * this number is used by recovery, and it gets confused by the boundary + * split here + * nvecs++; + */ vecp++; first_bit = next_bit; last_bit = next_bit; diff --git a/trunk/fs/xfs/xfs_dfrag.c b/trunk/fs/xfs/xfs_dfrag.c index c407e1ccff43..f852b082a084 100644 --- a/trunk/fs/xfs/xfs_dfrag.c +++ b/trunk/fs/xfs/xfs_dfrag.c @@ -219,14 +219,6 @@ xfs_swap_extents( int taforkblks = 0; __uint64_t tmp; - /* - * We have no way of updating owner information in the BMBT blocks for - * each inode on CRC enabled filesystems, so to avoid corrupting the - * this metadata we simply don't allow extent swaps to occur. - */ - if (xfs_sb_version_hascrc(&mp->m_sb)) - return XFS_ERROR(EINVAL); - tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); if (!tempifp) { error = XFS_ERROR(ENOMEM); diff --git a/trunk/fs/xfs/xfs_dir2_format.h b/trunk/fs/xfs/xfs_dir2_format.h index 995f1f505a52..a3b1bd841a80 100644 --- a/trunk/fs/xfs/xfs_dir2_format.h +++ b/trunk/fs/xfs/xfs_dir2_format.h @@ -715,7 +715,6 @@ struct xfs_dir3_free_hdr { __be32 firstdb; /* db of first entry */ __be32 nvalid; /* count of valid entries */ __be32 nused; /* count of used entries */ - __be32 pad; /* 64 bit alignment. */ }; struct xfs_dir3_free { diff --git a/trunk/fs/xfs/xfs_dir2_node.c b/trunk/fs/xfs/xfs_dir2_node.c index 2226a00acd15..5246de4912d4 100644 --- a/trunk/fs/xfs/xfs_dir2_node.c +++ b/trunk/fs/xfs/xfs_dir2_node.c @@ -263,19 +263,18 @@ xfs_dir3_free_get_buf( * Initialize the new block to be empty, and remember * its first slot as our empty slot. */ - memset(bp->b_addr, 0, sizeof(struct xfs_dir3_free_hdr)); - memset(&hdr, 0, sizeof(hdr)); - + hdr.magic = XFS_DIR2_FREE_MAGIC; + hdr.firstdb = 0; + hdr.nused = 0; + hdr.nvalid = 0; if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; hdr.magic = XFS_DIR3_FREE_MAGIC; - hdr3->hdr.blkno = cpu_to_be64(bp->b_bn); hdr3->hdr.owner = cpu_to_be64(dp->i_ino); uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); - } else - hdr.magic = XFS_DIR2_FREE_MAGIC; + } xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr); *bpp = bp; return 0; @@ -1922,6 +1921,8 @@ xfs_dir2_node_addname_int( */ freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * xfs_dir3_free_max_bests(mp); + free->hdr.nvalid = 0; + free->hdr.nused = 0; } else { free = fbp->b_addr; bests = xfs_dir3_free_bests_p(mp, free); diff --git a/trunk/fs/xfs/xfs_fs.h b/trunk/fs/xfs/xfs_fs.h index d04695545397..6dda3f949b04 100644 --- a/trunk/fs/xfs/xfs_fs.h +++ b/trunk/fs/xfs/xfs_fs.h @@ -236,7 +236,6 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_PROJID32 0x0800 /* 32-bit project IDs */ #define XFS_FSOP_GEOM_FLAGS_DIRV2CI 0x1000 /* ASCII only CI names */ #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ -#define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ /* diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index 3c3644ea825b..87595b211da1 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -99,9 +99,7 @@ xfs_fs_geometry( (xfs_sb_version_hasattr2(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_ATTR2 : 0) | (xfs_sb_version_hasprojid32bit(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_PROJID32 : 0) | - (xfs_sb_version_hascrc(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_V5SB : 0); + XFS_FSOP_GEOM_FLAGS_PROJID32 : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; diff --git a/trunk/fs/xfs/xfs_iops.c b/trunk/fs/xfs/xfs_iops.c index ca9ecaa81112..d82efaa2ac73 100644 --- a/trunk/fs/xfs/xfs_iops.c +++ b/trunk/fs/xfs/xfs_iops.c @@ -455,28 +455,6 @@ xfs_vn_getattr( return 0; } -static void -xfs_setattr_mode( - struct xfs_trans *tp, - struct xfs_inode *ip, - struct iattr *iattr) -{ - struct inode *inode = VFS_I(ip); - umode_t mode = iattr->ia_mode; - - ASSERT(tp); - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - mode &= ~S_ISGID; - - ip->i_d.di_mode &= S_IFMT; - ip->i_d.di_mode |= mode & ~S_IFMT; - - inode->i_mode &= S_IFMT; - inode->i_mode |= mode & ~S_IFMT; -} - int xfs_setattr_nonsize( struct xfs_inode *ip, @@ -628,8 +606,18 @@ xfs_setattr_nonsize( /* * Change file access modes. */ - if (mask & ATTR_MODE) - xfs_setattr_mode(tp, ip, iattr); + if (mask & ATTR_MODE) { + umode_t mode = iattr->ia_mode; + + if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) + mode &= ~S_ISGID; + + ip->i_d.di_mode &= S_IFMT; + ip->i_d.di_mode |= mode & ~S_IFMT; + + inode->i_mode &= S_IFMT; + inode->i_mode |= mode & ~S_IFMT; + } /* * Change file access or modified times. @@ -726,8 +714,9 @@ xfs_setattr_size( return XFS_ERROR(error); ASSERT(S_ISREG(ip->i_d.di_mode)); - ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| - ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); + ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| + ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| + ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); if (!(flags & XFS_ATTR_NOLOCK)) { lock_flags |= XFS_IOLOCK_EXCL; @@ -871,12 +860,6 @@ xfs_setattr_size( xfs_inode_clear_eofblocks_tag(ip); } - /* - * Change file access modes. - */ - if (mask & ATTR_MODE) - xfs_setattr_mode(tp, ip, iattr); - if (mask & ATTR_CTIME) { inode->i_ctime = iattr->ia_ctime; ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index d9e4d3c3991a..93f03ec17eec 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -2096,17 +2096,6 @@ xlog_recover_do_reg_buffer( ASSERT(BBTOB(bp->b_io_length) >= ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT)); - /* - * The dirty regions logged in the buffer, even though - * contiguous, may span multiple chunks. This is because the - * dirty region may span a physical page boundary in a buffer - * and hence be split into two separate vectors for writing into - * the log. Hence we need to trim nbits back to the length of - * the current region being copied out of the log. - */ - if (item->ri_buf[i].i_len < (nbits << XFS_BLF_SHIFT)) - nbits = item->ri_buf[i].i_len >> XFS_BLF_SHIFT; - /* * Do a sanity check if this is a dquot buffer. Just checking * the first dquot in the buffer should do. XXXThis is diff --git a/trunk/fs/xfs/xfs_qm_syscalls.c b/trunk/fs/xfs/xfs_qm_syscalls.c index 6cdf6ffc36a1..c41190cad6e9 100644 --- a/trunk/fs/xfs/xfs_qm_syscalls.c +++ b/trunk/fs/xfs/xfs_qm_syscalls.c @@ -489,36 +489,31 @@ xfs_qm_scall_setqlim( if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0) return 0; + tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); + error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp), + 0, 0, XFS_DEFAULT_LOG_COUNT); + if (error) { + xfs_trans_cancel(tp, 0); + return (error); + } + /* * We don't want to race with a quotaoff so take the quotaoff lock. - * We don't hold an inode lock, so there's nothing else to stop - * a quotaoff from happening. + * (We don't hold an inode lock, so there's nothing else to stop + * a quotaoff from happening). (XXXThis doesn't currently happen + * because we take the vfslock before calling xfs_qm_sysent). */ mutex_lock(&q->qi_quotaofflock); /* - * Get the dquot (locked) before we start, as we need to do a - * transaction to allocate it if it doesn't exist. Once we have the - * dquot, unlock it so we can start the next transaction safely. We hold - * a reference to the dquot, so it's safe to do this unlock/lock without - * it being reclaimed in the mean time. + * Get the dquot (locked), and join it to the transaction. + * Allocate the dquot if this doesn't exist. */ - error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp); - if (error) { + if ((error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp))) { + xfs_trans_cancel(tp, XFS_TRANS_ABORT); ASSERT(error != ENOENT); goto out_unlock; } - xfs_dqunlock(dqp); - - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); - error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp), - 0, 0, XFS_DEFAULT_LOG_COUNT); - if (error) { - xfs_trans_cancel(tp, 0); - goto out_rele; - } - - xfs_dqlock(dqp); xfs_trans_dqjoin(tp, dqp); ddq = &dqp->q_core; @@ -626,10 +621,9 @@ xfs_qm_scall_setqlim( xfs_trans_log_dquot(tp, dqp); error = xfs_trans_commit(tp, 0); - -out_rele: xfs_qm_dqrele(dqp); -out_unlock: + + out_unlock: mutex_unlock(&q->qi_quotaofflock); return error; } diff --git a/trunk/fs/xfs/xfs_symlink.c b/trunk/fs/xfs/xfs_symlink.c index 195a403e1522..5f234389327c 100644 --- a/trunk/fs/xfs/xfs_symlink.c +++ b/trunk/fs/xfs/xfs_symlink.c @@ -56,9 +56,16 @@ xfs_symlink_blocks( struct xfs_mount *mp, int pathlen) { - int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize); + int fsblocks = 0; + int len = pathlen; - return (pathlen + buflen - 1) / buflen; + do { + fsblocks++; + len -= XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize); + } while (len > 0); + + ASSERT(fsblocks <= XFS_SYMLINK_MAPS); + return fsblocks; } static int @@ -398,7 +405,7 @@ xfs_symlink( if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version)) fs_blocks = 0; else - fs_blocks = xfs_symlink_blocks(mp, pathlen); + fs_blocks = XFS_B_TO_FSB(mp, pathlen); resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks); error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT); @@ -505,7 +512,7 @@ xfs_symlink( cur_chunk = target_path; offset = 0; for (n = 0; n < nmaps; n++) { - char *buf; + char *buf; d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); @@ -518,7 +525,9 @@ xfs_symlink( bp->b_ops = &xfs_symlink_buf_ops; byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt); - byte_cnt = min(byte_cnt, pathlen); + if (pathlen < byte_cnt) { + byte_cnt = pathlen; + } buf = bp->b_addr; buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset, @@ -533,7 +542,6 @@ xfs_symlink( xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) - (char *)bp->b_addr); } - ASSERT(pathlen == 0); } /* diff --git a/trunk/include/linux/aer.h b/trunk/include/linux/aer.h index 737f90ab4b62..ec10e1b24c1c 100644 --- a/trunk/include/linux/aer.h +++ b/trunk/include/linux/aer.h @@ -49,11 +49,10 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) } #endif -extern void cper_print_aer(struct pci_dev *dev, +extern void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity, struct aer_capability_regs *aer); extern int cper_severity_to_aer(int cper_severity); extern void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity, - struct aer_capability_regs *aer_regs); + int severity); #endif //_AER_H_